Device
The nv table property provides data storage that, unlike the imp’s main memory, is protected during deep sleep (see server.sleepfor() and server.sleepuntil()). Its contents are cached in low-power memory before entering deep sleep and are recovered upon restart. It is available on some imps, but not all.
The nv table can’t survive a cold boot, however. To retain data across power cycles, you can make use of the following options:
Use the agent.send()/device.on() mechanism to transfer the data to the agent, which can then use server.save() to cache the data in permanent storage. The agent can later call server.load() to retrieve the data and pass it back to the device.
Use the imp.setuserconfiguration()/imp.getuserconfiguration() mechanism to persist the data in the imp’s Flash storage. The data will persist across both warm and cold starts (unlike the nv table), is not dependent on an Internet connection (unlike server.save()), and will be retained until it is actively overwritten. However, data must be stored as a blob or a string, and every write erodes the Flash’s finite write capacity.
The nv table is not instantiated automatically: if you need to store data across deep sleeps, you need to establish a table called nv as a global variable. Just before it goes into deep sleep, impOS will check for a global table variable called nv and preserve it for you. It will automatically re-establish the variable when the device next wakes.
There are some instances when a restart will not preserve your nv table. It is possible to determine whether the nv table should have been preserved by consulting hardware.wakereason():
Constant | Value | Description | nv Preserved? |
---|---|---|---|
WAKEREASON_POWER_ON | 0 | Powered on (cold boot) | No |
WAKEREASON_TIMER | 1 | Woken after sleep time expired | Yes |
WAKEREASON_SW_RESET | 2 | Restarted due to a software reset | No |
WAKEREASON_PIN | 3 | Woken by wakeup pin going high | Yes |
WAKEREASON_NEW_SQUIRREL | 4 | Restarted due to new Squirrel code being loaded | No |
WAKEREASON_SQUIRREL_ERROR | 5 | Restarted due to a Squirrel run-time error | No |
WAKEREASON_NEW_FIRMWARE | 6 | Restarted due to a firmware upgrade | No |
WAKEREASON_SNOOZE | 7 | Woken from a snooze-and-retry event | Yes |
WAKEREASON_HW_RESET | 8 | Restarted by RESET_L pin (imp003 only) | No |
The values assigned to the constants may change in a future impOS release.
Most, but not all, Squirrel data-types can be stored in the nv table, ie. those that can be serialized. See the Developer Guide Squirrel Data Serialization for details. However, there is a definite maximum size of the serialized data: just under 4KB. Tables which become larger than this can’t be persisted in nv table. Be warned: no error is generated in this case because the imp is already shutting down when the write is attempted.
Because the nv table size is limited, it is important to confirm that there is sufficient room to store the data you need to be preserved during deep sleep. The nv data is stored in BSON (Binary jSON) format. However, formatting your data in JSON form does not provide a guide to the size of its BSON equivalent. The recommended approach, therefore, is to derive by experimentation how much of your data the nv can contain, ie. find out how much of your sample data you recover after saving it to nv (see the note on errors in the paragraph above), and then embed that figure (minus a safety factor) in your code as a constant.
The nv table is not currently available for use within factory firmware.
For more information on saving data, see the Developer Guide Data Persistence In imp Applications.
For sample code that can be used to manage data persistence on the device and the agent, see the imp API Cookbook recipes Device Data Persistence and Agent Data Persistence.
The nv table is not implemented on these imps. Attempting to establish and access the nv table will throw the following exception: "nv table not available on this imp"
.
Users who need to store data across deep sleeps on imp004m and the imp006 can use hardware.spiflash. With the imp004m, they can potentially even avoid deep sleep altogether. This is possible because shallow sleep on the imp004m consumes less power than other imps do in shallow sleep.
The imp005 does not support deep sleep.
This example shows how the imp API's nv table is used to preserve a single value across periodic deep sleeps.