pycom / pycom-micropython-sigfox

A fork of MicroPython with the ESP32 port customized to run on Pycom's IoT multi-network modules.
MIT License
196 stars 167 forks source link

Error updating NVRAM Flash with nvs_set() #101

Open rolandvs opened 6 years ago

rolandvs commented 6 years ago

Posted it also on the forum, but it seems that when all entries of the nvs area are set the bug appears when you try to update an existing entry.

The size of the nvs is 614 entries maximum. You can only find out by filling it (see code fragment). As a suggestion: return the size as return parameter from nvs_set().

When there are 614 entries filled and you want to update an existing one you get an error: pycom.nvs_set('<entry>',<value>) will throw an exception. If you take out one entry with pycom.nvs_erase('<entry>') the exception will not be thrown anymore.

It looks to me like an internal range error check.

# fill the nvs section until error
import pycom
keep = pycom.heartbeat() # kill the flashing LED
pycom.heartbeat(False)

print("Test Maximum NVM parameters")
pycom.nvs_erase_all()
ii = 0
while True:
    try:
        print (ii)
        pycom.nvs_set('loc'+str(ii), ii)
        ii+=1
    except OSError as err:
        print(err, ii-1)
        break

The code will run and exit with no space available 613, so locations 0-613 can be used. Every location is filled with its "index" number.

pycom.nvs_get('loc614') will return None, pycom.nvs_get('loc613') will return 613, pycom.nvs_get('loc612') will return 612, etc.

UPDATING any location: pycom.nvs_set('loc612', 0x55aa) gives an error: OSError no space available.

Removing a single entry: pycom.nvs_erase('loc613'). If it does not exist the error KeyError: key not found is returned. Then when you store the value again: pycom.nvs_set('loc613', 0x55aa) it is ok, however when doing it again you end up with the OSError: no space available.

So there are 614 locations available where you can store a 32bit value.

nevercast commented 5 years ago

Just an aside, listing the names is probably going to never be possible, since the namespace and key name are hashed, and their integer value is used as an index to store in NVRAM. There also does not seem to be the ability to check how many pages/entries are allocated or free. Espressif API: https://esp-idf.readthedocs.io/en/v1.0/api/nvs_flash.html

Unfortunately it seems your request might be unachievable without modifications to the Espressif SDK (assuming there isn't further hardware limits).

While I can't offer any information regarding the SDK side and its mutability, I do have the query, why do you need 613 entries? (2.4KB) Can you not use the flash file system provided?