micropython: add micropython component

This commit is contained in:
KY-zhang-X
2022-09-29 12:10:37 +08:00
parent 1514f1cb9b
commit dd76146324
2679 changed files with 354110 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
try:
from esp32 import Partition as p
import micropython
except ImportError:
print("SKIP")
raise SystemExit
# try some vanilla OSError to get std error code
try:
open("this filedoesnotexist", "r")
print("FAILED TO RAISE")
except OSError as e:
print(e)
# try to make nvs partition bootable, which ain't gonna work
part = p.find(type=p.TYPE_DATA)[0]
fun = p.set_boot
try:
fun(part)
print("FAILED TO RAISE")
except OSError as e:
print(e)
# same but with out of memory condition by locking the heap
exc = "FAILED TO RAISE"
micropython.heap_lock()
try:
fun(part)
except OSError as e:
exc = e
micropython.heap_unlock()
print("exc:", exc) # exc empty due to no memory
# same again but having an emergency buffer
micropython.alloc_emergency_exception_buf(256)
exc = "FAILED TO RAISE"
micropython.heap_lock()
try:
fun(part)
except Exception as e:
exc = e
micropython.heap_unlock()
print(exc)

View File

@@ -0,0 +1,4 @@
[Errno 2] ENOENT
(-5379, 'ESP_ERR_OTA_VALIDATE_FAILED')
exc:
-5379

View File

@@ -0,0 +1,33 @@
# Test the esp32's esp32.idf_heap_info to return sane data
try:
import esp32
except ImportError:
print("SKIP")
raise SystemExit
# region tuple is: (size, free, largest free, min free)
# we check that each region's size is > 0 and that the free amounts are smaller than the size
def chk_heap(kind, regions):
chk = [True, True, True, True]
for r in regions:
chk = [
chk[0] and r[0] > 0,
chk[1] and r[1] <= r[0],
chk[2] and r[2] <= r[0],
chk[3] and r[3] <= r[0],
]
print(kind, chk)
# try getting heap regions
regions = esp32.idf_heap_info(esp32.HEAP_DATA)
print("HEAP_DATA >2:", len(regions) > 2)
chk_heap("HEAP_DATA", regions)
# try getting code regions
regions = esp32.idf_heap_info(esp32.HEAP_EXEC)
print("HEAP_EXEC >2:", len(regions) > 2)
chk_heap("HEAP_EXEC", regions)
# try invalid param
print(esp32.idf_heap_info(-1))

View File

@@ -0,0 +1,5 @@
HEAP_DATA >2: True
HEAP_DATA [True, True, True, True]
HEAP_EXEC >2: True
HEAP_EXEC [True, True, True, True]
[]

View File

@@ -0,0 +1,67 @@
# Test the esp32 NVS class - access to esp-idf's Non-Volatile-Storage
from esp32 import NVS
nvs = NVS("mp-test")
# test setting and gettin an integer kv
nvs.set_i32("key1", 1234)
print(nvs.get_i32("key1"))
nvs.set_i32("key2", -503)
print(nvs.get_i32("key2"))
print(nvs.get_i32("key1"))
# test setting and getting a blob kv using a bytearray
blob1 = "testing a string as a blob"
nvs.set_blob("blob1", blob1)
buf1 = bytearray(len(blob1))
len1 = nvs.get_blob("blob1", buf1)
print(buf1)
print(len(blob1), len1)
# test setting and getting a blob kv using a string
blob2 = b"testing a bytearray"
nvs.set_blob("blob2", blob2)
buf2 = bytearray(len(blob2))
len2 = nvs.get_blob("blob2", buf2)
print(buf2)
print(len(blob2), len2)
# test raising of error exceptions
nvs.erase_key("key1")
try:
nvs.erase_key("key1") # not found
except OSError as e:
print(e)
try:
nvs.get_i32("key1") # not found
except OSError as e:
print(e)
try:
nvs.get_i32("blob1") # not found (blob1 exists but diff type)
except OSError as e:
print(e)
try:
buf3 = bytearray(10)
nvs.get_blob("blob1", buf3) # invalid length (too short)
except OSError as e:
print(e)
nvs.commit() # we're not verifying that this does anything, just doesn't error
# test using a second namespace and that it doesn't interfere with first
nvs2 = NVS("mp-test2")
try:
print(nvs2.get_i32("key2"))
except OSError as e:
print(e)
nvs2.set_i32("key2", 7654)
print(nvs.get_i32("key2"))
print(nvs2.get_i32("key2"))
# clean-up (the namespaces will remain)
nvs.erase_key("key2")
nvs.erase_key("blob1")
nvs.erase_key("blob2")
nvs2.erase_key("key2")
nvs.commit()

View File

@@ -0,0 +1,14 @@
1234
-503
1234
bytearray(b'testing a string as a blob')
26 26
bytearray(b'testing a bytearray')
19 19
(-4354, 'ESP_ERR_NVS_NOT_FOUND')
(-4354, 'ESP_ERR_NVS_NOT_FOUND')
(-4354, 'ESP_ERR_NVS_NOT_FOUND')
(-4364, 'ESP_ERR_NVS_INVALID_LENGTH')
(-4354, 'ESP_ERR_NVS_NOT_FOUND')
-503
7654

View File

@@ -0,0 +1,117 @@
# Test ESP32 OTA updates, including automatic roll-back.
# Running this test requires firmware with an OTA Partition, such as the GENERIC_OTA "board".
# This test also requires patience as it copies the boot partition into the other OTA slot.
import machine
from esp32 import Partition
# start by checking that the running partition table has OTA partitions, 'cause if
# it doesn't there's nothing we can test
cur = Partition(Partition.RUNNING)
cur_name = cur.info()[4]
if not cur_name.startswith("ota_"):
print("SKIP")
raise SystemExit
DEBUG = True
def log(*args):
if DEBUG:
print(*args)
# replace boot.py with the test code that will run on each reboot
import uos
try:
uos.rename("boot.py", "boot-orig.py")
except:
pass
with open("boot.py", "w") as f:
f.write("DEBUG=" + str(DEBUG))
f.write(
"""
import machine
from esp32 import Partition
cur = Partition(Partition.RUNNING)
cur_name = cur.info()[4]
def log(*args):
if DEBUG: print(*args)
from step import STEP, EXPECT
log("Running partition: " + cur_name + " STEP=" + str(STEP) + " EXPECT=" + EXPECT)
if cur_name != EXPECT:
print("\\x04FAILED: step " + str(STEP) + " expected " + EXPECT + " got " + cur_name + "\\x04")
if STEP == 0:
log("Not confirming boot ok and resetting back into first")
nxt = cur.get_next_update()
with open("step.py", "w") as f:
f.write("STEP=1\\nEXPECT=\\"" + nxt.info()[4] + "\\"\\n")
machine.reset()
elif STEP == 1:
log("Booting into second partition again")
nxt = cur.get_next_update()
nxt.set_boot()
with open("step.py", "w") as f:
f.write("STEP=2\\nEXPECT=\\"" + nxt.info()[4] + "\\"\\n")
machine.reset()
elif STEP == 2:
log("Confirming boot ok and rebooting into same partition")
Partition.mark_app_valid_cancel_rollback()
with open("step.py", "w") as f:
f.write("STEP=3\\nEXPECT=\\"" + cur_name + "\\"\\n")
machine.reset()
elif STEP == 3:
log("Booting into original partition")
nxt = cur.get_next_update()
nxt.set_boot()
with open("step.py", "w") as f:
f.write("STEP=4\\nEXPECT=\\"" + nxt.info()[4] + "\\"\\n")
machine.reset()
elif STEP == 4:
log("Confirming boot ok and DONE!")
Partition.mark_app_valid_cancel_rollback()
import uos
uos.remove("step.py")
uos.remove("boot.py")
uos.rename("boot-orig.py", "boot.py")
print("\\nSUCCESS!\\n\\x04\\x04")
"""
)
def copy_partition(src, dest):
log("Partition copy: {} --> {}".format(src.info(), dest.info()))
sz = src.info()[3]
if dest.info()[3] != sz:
raise ValueError("Sizes don't match: {} vs {}".format(sz, dest.info()[3]))
addr = 0
blk = bytearray(4096)
while addr < sz:
if sz - addr < 4096:
blk = blk[: sz - addr]
if addr & 0xFFFF == 0:
# need to show progress to run-tests.py else it times out
print(" ... 0x{:06x}".format(addr))
src.readblocks(addr >> 12, blk)
dest.writeblocks(addr >> 12, blk)
addr += len(blk)
# get things started by copying the current partition into the next slot and rebooting
print("Copying current to next partition")
nxt = cur.get_next_update()
copy_partition(cur, nxt)
print("Partition copied, booting into it")
nxt.set_boot()
# the step.py file is used to keep track of state across reboots
# EXPECT is the name of the partition we expect to reboot into
with open("step.py", "w") as f:
f.write('STEP=0\nEXPECT="' + nxt.info()[4] + '"\n')
machine.reset()

View File

@@ -0,0 +1,15 @@
Copying current to next partition
########
Partition copied, booting into it
########
Not confirming boot ok and resetting back into first
########
Booting into second partition again
########
Confirming boot ok and rebooting into same partition
########
Booting into original partition
########
Confirming boot ok and DONE!
SUCCESS!

View File

@@ -0,0 +1,59 @@
# Test that the esp32's socket module performs DNS resolutions on bind and connect
import sys
if sys.implementation.name == "micropython" and sys.platform != "esp32":
print("SKIP")
raise SystemExit
try:
import usocket as socket, sys
except:
import socket, sys
def test_bind_resolves_0_0_0_0():
s = socket.socket()
try:
s.bind(("0.0.0.0", 31245))
print("bind actually bound")
s.close()
except Exception as e:
print("bind raised", e)
def test_bind_resolves_localhost():
s = socket.socket()
try:
s.bind(("localhost", 31245))
print("bind actually bound")
s.close()
except Exception as e:
print("bind raised", e)
def test_connect_resolves():
s = socket.socket()
try:
s.connect(("micropython.org", 80))
print("connect actually connected")
s.close()
except Exception as e:
print("connect raised", e)
def test_connect_non_existent():
s = socket.socket()
try:
s.connect(("nonexistent.example.com", 80))
print("connect actually connected")
s.close()
except OSError as e:
print("connect raised OSError")
except Exception as e:
print("connect raised", e)
test_funs = [n for n in dir() if n.startswith("test_")]
for f in sorted(test_funs):
print("--", f, end=": ")
eval(f + "()")