Beispiel #1
0
def safe_mode_act(boot_pin):

    if boot_pin.safe_mode:

        led_pin = boot_pin.led_pin
        led_on = boot_pin.led_on
        btn_pin = boot_pin.btn_pin
        reset_val = boot_pin.reset_val

        print("Pin Control: LED {}, BTN: {}".format(led_pin, btn_pin))

        safe_pin = Pin(btn_pin, Pin.IN, Pin.PULL_DOWN)
        led_pin = Pin(led_pin, Pin.OUT)
        led_pin.value(led_on)
        print("Wait 5sec - Safe Mode")
        sleep(5)
        print("Safe Mode Activate: {}".format(safe_pin.value() == reset_val))

        if safe_pin.value() == reset_val:
            led_pin.value(1 - led_on)
            Partition.set_boot(Partition('factory'))
            reset()

        sleep(1)
        led_pin.value(1 - led_on)

    else:
        print("Safe Mode: not present")
Beispiel #2
0
 def __init__(self):
     self.part = Partition(Partition.RUNNING).get_next_update()
     self.sha = hashlib.sha256()
     self.seq = 0
     self.block = 0
     self.buf = bytearray(BLOCKLEN)
     self.buflen = 0
Beispiel #3
0
    def get_current_partition_name(self):
        """
            returns current partition name.

            Args:
                void.
            Returns:
                string with current partition name (ota_0 or ota_1).
        """
        cur = Partition(Partition.RUNNING)
        return cur.info()[4]
Beispiel #4
0
    def __init__(self, verbose=False):
        self.verbose = verbose
        # the partition we are writing to
        self.part = Partition(Partition.RUNNING).get_next_update()

        # sha of the new app, computed in _app_data
        self.sha = hashlib.sha256()

        # keeping track (_app_data)
        self.block = 0
        self.buf = bytearray(BLOCKLEN)
        self.buflen = 0  # length of current content of self.buf
Beispiel #5
0
    def __init__(self, _debug=True):
        self.debug = _debug
        self.update_file_pages_counter = 0
        self.update_file_page_data = bytearray()

        current_partition = Partition(Partition.RUNNING)
        current_partition_name = current_partition.info()[4]

        self.plot_debug("current partition:" + str(current_partition.info()))

        if not current_partition_name.startswith(
                "ota_"):  # firmware is adapted to OTA ?
            print(
                "memory_esp32: skipping... Partition table not adapted to OTA")
            raise SystemExit

        self.partition = current_partition.get_next_update()
        self.plot_debug("next partition:" + str(self.partition.info()))
Beispiel #6
0
def feed():
    global first
    wdt.feed()
    if safemode and not revert:
        return
    elif first is None:
        return  # done with safe mode stuff
    elif first == 0:
        first = time.ticks_ms()  # record time of first feeding
    elif time.ticks_diff(time.ticks_ms(), first) > allok:
        if sys.platform == 'esp32':
            # mark the current partition as OK, this prevents rollback after OTA
            from esp32 import Partition
            part = Partition(Partition.RUNNING)
            part.mark_app_valid_cancel_rollback()
        if safemode:
            log.critical("Switching to NORMAL MODE via reset")
            reset(True)
        else:
            log.warning("Next reset: normal boot")
            normalboot(True)
            first = None
Beispiel #7
0
from esp32 import Partition

bdev = Partition.find(Partition.TYPE_DATA, label="vfs")
bdev = bdev[0] if bdev else None
'''

import random
from esp32 import Partition
import esp
import uos

filename = "csv_data_file.txt"

# Get some statistics:
print(
    "Available flash space: ",
    esp.flash_size())  # This will give you the total amount of Flash available

partition = Partition(Partition.RUNNING)
print(
    partition.info()
)  # Print out information about the running flash partition on which you can store your files.

file_stats = uos.stat(filename)
print(
    "File size before write: ", file_stats[6]
)  # the item at index 6 of the tupple contains the total bytes in the file.

# This loop will add 10 lines that contain dummy comma-delimited data.
for x in range(10):
    random_temp = random.randint(0, 50)
    random_humi = random.randint(20, 90)
    random_pres = random.randint(900, 1100)  # in hPa
Beispiel #9
0
def reboot(part="ota_0"):

    ota_0 = Partition(part)
    Partition.set_boot(ota_0)

    reset()
Beispiel #10
0
files = os.listdir()

if '_manifest.json' in files:  # have an new manifest ? make upgrade

    _manifest_file = open('_manifest.json', 'r')
    _manifest_str = _manifest_file.read()
    _manifest_file.close()

    try:
        _manifest_object = json.loads(_manifest_str)

        if _manifest_object['type'] == 'bin':

            print('monolithic upgrade identified.')

            _current_partition = Partition(Partition.RUNNING)
            if _manifest_object['ota'] == _current_partition.info(
            )[4]:  # changed ota partition ?

                os.rename("_manifest.json", "manifest.json")
                print('update with success.')
                _updated = True
            else:
                print('failed to update.')
                os.remove('_manifest.json')
        else:

            print('diferential upgrade identified.')

            for file in files:
                if file[0] == '_':  # is an update file (_xxx)
Beispiel #11
0
try:
    import boot_pin
    safe_mode_act(boot_pin)
    del (boot_pin)
except Exception as e:
    print(e)
    pass

# PARTITIONS // Path

import sys
import uos
import gc

bootpart = Partition(Partition.BOOT)
runningpart = Partition(Partition.RUNNING)

print("INFO - Partitions")
print("Boot: {}".format(bootpart))
print("Run: {}".format(runningpart))

part_info = runningpart.info()
part_name = part_info[4]

try:
    uos.mkdir(part_name)
except OSError as e:
    print("Path already exist")
    pass
Beispiel #12
0
# import esp
from utime import sleep
from machine import Pin, reset

from esp32 import Partition

import sys
import uos
import gc

bootpart = Partition(Partition.BOOT)
runningpart = Partition(Partition.RUNNING)

print("INFO - Partitions")
print("Boot: {}".format(bootpart))
print("Run: {}".format(runningpart))

# SAFE MODE
safe_mode = False

try:
    import boot_pin
    safe_mode = boot_pin.safe_mode
    print(safe_mode)
except Exception:
    pass

if safe_mode:

    print("Pin Control: LED {}, BTN: {}".format(boot_pin.led_pin,
                                                boot_pin.btn_pin))
Beispiel #13
0
        if wlan.isconnected(): break
        time.sleep_ms(100)
    if not wlan.isconnected():
        print("Unable to connect to WiFi!")
        wlan.disconnect()
        return
    print("IP", wlan.ifconfig()[0])
    print("mDNS", mdns_name + ".local")
    # set clock to local time
    tm = time.localtime(ntptime.time() + getattr(secrets, 'tz_offset', 0))
    print("time", tm)
    machine.RTC().datetime(
        (tm[0], tm[1], tm[2], tm[6] + 1, tm[3], tm[4], tm[5], 0))


# OTA ... accept uploaded image (if we uploaded a new one)
from esp32 import Partition

Partition.mark_app_valid_cancel_rollback()

# connect to WiFi
connect()

if True:
    # webrepl
    import webrepl
    webrepl.start()
    network.WLAN(network.STA_IF).mdns_add_service('_ws', '_tcp', 8266)

gc.collect()
# 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:
 def part(self):
     runningpart = Partition(Partition.RUNNING)
     part_info = runningpart.info()
     part_name = part_info[4]
     return part_name
 def reboot(part=None):
     if part:
         _part = Partition(part)
         Partition.set_boot(_part)
     machine.reset()
Beispiel #17
0
from esp32 import Partition

# MicroPython's partition table uses "vfs", TinyUF2 uses "ffat".
bdev = Partition.find(Partition.TYPE_DATA, label="vfs")
if not bdev:
    bdev = Partition.find(Partition.TYPE_DATA, label="ffat", block_size=512)
bdev = bdev[0] if bdev else None
Beispiel #18
0
    class OTA:
        def __init__(self):
            self.part = Partition(Partition.RUNNING).get_next_update()
            self.sha = hashlib.sha256()
            self.seq = 0
            self.block = 0
            self.buf = bytearray(BLOCKLEN)
            self.buflen = 0

        # handle processes one message with a chunk of data in msg. The sequence number seq needs
        # to increment sequentially and the last call needs to have last==True as well as the
        # sha set to the hashlib.sha256(entire_data).hexdigest().
        def handle(self, sha, msg, seq, last):
            if self.seq is None:
                raise ValueError("missing first message")
            elif self.seq < seq:
                # "duplicate message"
                log.warning("Duplicate OTA message seq=%d", seq)
                return None
            elif self.seq > seq:
                raise ValueError("message missing")
            else:
                self.seq += 1
            self.sha.update(msg)
            # avoid allocating memory: use buf as-is
            msglen = len(msg)
            if self.buflen + msglen >= BLOCKLEN:
                # got a full block, assemble it and write to flash
                cpylen = BLOCKLEN - self.buflen
                self.buf[self.buflen:BLOCKLEN] = msg[:cpylen]
                self.part.writeblocks(self.block, self.buf)
                self.block += 1
                msglen -= cpylen
                if msglen > 0:
                    self.buf[:msglen] = msg[cpylen:]
                self.buflen = msglen
            else:
                self.buf[self.buflen:self.buflen + msglen] = msg
                self.buflen += msglen
                if last and self.buflen > 0:
                    for i in range(BLOCKLEN - self.buflen):
                        self.buf[self.buflen + i] = 0xFF  # erased flash is ff
                    self.part.writeblocks(self.block, self.buf)
                    self.block += 1
            assert len(self.buf) == BLOCKLEN
            if last:
                return self.finish(sha)
            elif (seq & 7) == 0:
                # log.info("Sending ACK {}".format(seq))
                return "SEQ {}".format(seq).encode()

        def finish(self, check_sha):
            del self.buf
            self.seq = None
            calc_sha = binascii.hexlify(self.sha.digest())
            check_sha = check_sha.encode()
            if calc_sha != check_sha:
                raise ValueError("SHA mismatch calc:{} check={}".format(
                    calc_sha, check_sha))
            self.part.set_boot()
            return "OK"
Beispiel #19
0
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()
Beispiel #20
0
from esp32 import Partition

bdev = Partition.find(Partition.TYPE_DATA, label='vfs')
bdev = bdev[0] if bdev else None
Beispiel #21
0
class OTA:

    # constructor, follow by calling ota(...)
    def __init__(self, verbose=False):
        self.verbose = verbose
        # the partition we are writing to
        self.part = Partition(Partition.RUNNING).get_next_update()

        # sha of the new app, computed in _app_data
        self.sha = hashlib.sha256()

        # keeping track (_app_data)
        self.block = 0
        self.buf = bytearray(BLOCKLEN)
        self.buflen = 0  # length of current content of self.buf

    # load app into the next partition and set it as the next one to boot upon restart
    #     :param:  url of app
    #     :sha256: sha256 of app
    def ota(self, url, sha256):
        if sys.platform != 'esp32':
            raise ValueError("N/A")
        if self.verbose: print('OTA ', end='')
        buffer = bytearray(BLOCKLEN)
        mv = memoryview(buffer)
        sock = open_url(url)
        while True:
            sz = sock.readinto(buffer)
            if not sz: break
            self._app_data(mv[0:sz])
        self._finish(sha256)
        buffer = None
        gc.collect()

    # accept chunks of the app and write to self.part
    def _app_data(self, data, last=False):
        global BLOCKLEN, buf, buflen, block
        data_len = len(data)
        self.sha.update(data)
        if self.buflen + data_len >= BLOCKLEN:
            # got a full block, assemble it and write to flash
            cpylen = BLOCKLEN - self.buflen
            self.buf[self.buflen:BLOCKLEN] = data[:cpylen]
            assert len(self.buf) == BLOCKLEN
            if self.verbose: print('.', end='')
            self.part.writeblocks(self.block, self.buf)
            self.block += 1
            data_len -= cpylen
            if data_len > 0:
                self.buf[:data_len] = data[cpylen:]
            self.buflen = data_len
        else:
            self.buf[self.buflen:self.buflen + data_len] = data
            self.buflen += data_len
            if last and self.buflen > 0:
                for i in range(BLOCKLEN - self.buflen):
                    self.buf[self.buflen +
                             i] = 0xFF  # ord('-') # erased flash is ff
                if self.verbose: print('.', end='')
                self.part.writeblocks(self.block, self.buf)
                assert len(self.buf) == BLOCKLEN

    # finish writing the app to the partition and check the sha
    def _finish(self, check_sha):
        # flush the app buffer and complete the write
        self._app_data(b'', last=False)
        self._app_data(b'', last=True)
        del self.buf
        # check the sha
        calc_sha = binascii.hexlify(self.sha.digest())
        check_sha = check_sha.encode()
        if calc_sha != check_sha:
            raise ValueError(
                "SHA mismatch\n    calc:  {}\n    check: {}".format(
                    calc_sha, check_sha))
        self.part.set_boot()
        if self.verbose: print(' Done.')