Using storage on Azure Sphere

This topic describes how to use storage on an Azure Sphere device. Azure Sphere provides two types of storage, read-only flash storage and mutable storage.

Read-only storage is used to store application image packages on a device so the contents can't be modified without updating the application. This can include any data such as user interface assets, static configuration data, binary resources including firmware images used to update external MCUs, or initialization data for mutable storage. Memory available for applications provides additional details about the amount of storage available.

Mutable storage stores data that persists when a device reboots. For example, if you want to manage system time using the local time zone, you can store the time zone settings in mutable storage. Some other examples are settings a user can modify, or downloaded configuration data. The mutable storage sample shows how to use mutable storage in an application.

Using read-only storage

You can use these Applibs functions to manage read-only storage. For an example that uses these functions see Connect to web services using curl.

Read-only storage requirements

Applications that use read-only storage must include the appropriate header files.

Include the storage and unistd headers in your project:

#include <unistd.h>
#include <applibs/storage.h>

Add a file to an image package

To add a file to read-only storage on the Azure Sphere device, you can add it to your project as a resource and include it in the application's image package. Use these functions in CMakeLists.txt to add the file as a resource:

  • Use azsphere_configure_tools to configure the Azure Sphere SDK Tools version. For example:

    azsphere_configure_tools(TOOLS_REVISION "20.04")

  • Use azsphere_target_add_image_package to specify the image package file and any resources files to include when building. For example:

    azsphere_target_add_image_package(${PROJECT_NAME} RESOURCE_FILES "file1.dat" "file2.dat")

The files "file1.dat" and "file2.dat" should now appear in the image package. See Use CMake functions for more information about these functions.

Note

Absolute paths are not supported for RESOURCE_FILES.

Using mutable storage

When you configure mutable storage for your application, it is assigned to the component ID of the application and can't be accessed by an application that has a different component ID. If the component ID of the application changes, the new application will not have access to the mutable storage of the previous application.

If you delete an application from a device, the mutable storage assigned to the application is also deleted. If the same application is then loaded back onto the device, the mutable storage will be empty. However, if you update the application without deleting it, the mutable storage contents are maintained.

The azsphere device app show-quota command displays the amount of mutable storage currently in use.

The Azure Sphere OS has power-loss protection mechanisms in place to avoid corruption of critical configuration state and file system metadata. The mutable storage API benefits from these features. However, the actual contents of mutable storage depends on whether, and in what order, buffers are flushed, so there is no guarantee that all pending changes at the time of power loss will be reflected in the file itself after recovery.

You can use these Applibs functions to manage mutable storage data:

Mutable storage requirements

Applications that use mutable storage must include the appropriate header files and add mutable storage settings to the application manifest.

Header files for mutable storage

Include the storage and unistd headers in your project:

#include <unistd.h>
#include <applibs/storage.h>

Application manifest

To use the APIs in this topic, you must add the MutableStorage capability to the application manifest and then set the SizeKB field. The SizeKB field is an integer that specifies the size of your mutable storage in kibibytes. The maximum value is 64 and the storage is allocated according to the erase block size of the device. The allocation is done by rounding up the SizeKB value to the next block size if the value isn't a whole multiple of the block size of the device.

Note

The MT3620 has an erase block size of 8 KB, so any values that are not multiples of 8 will be rounded up. For example, if you specify 12 KB in the 'MutableStorage' capability, you will receive 16 KB on an MT3620.

In the example below, the MutableStorage storage capability is added to the application manifest with a size of 8 KB.

{
  "SchemaVersion": 1,
  "Name" : "Mt3620App_Mutable_Storage",
  "ComponentId" : "9f4fee77-0c2c-4433-827b-e778024a04c3",
  "EntryPoint": "/bin/app",
  "CmdArgs": [],
   "Capabilities": {
    "AllowedConnections": [],
    "AllowedTcpServerPorts": [],
    "AllowedUdpServerPorts": [],
    "MutableStorage": { "SizeKB": 8 },
    "Gpio": [],
    "Uart": [],
    "WifiConfig": false,
    "NetworkConfig": false,
    "SystemTime": false
  }
}

Write persistent data

To write data to persistent storage, start by calling the Applibs function Storage_OpenMutableFile to retrieve a file descriptor for a persistent data file. Next call the write function to write the data to the persistent data file. If the amount of data you attempt to write exceeds your mutable storage allocation, the write function might succeed; however, the only data written will be the portion that doesn't exceed the storage allocation. To ensure all the data is written you must check the return value of the write function call.

Read persistent data

To read data from persistent storage call Storage_OpenMutableFile to retrieve a file descriptor for the persistent data file, and then call the read function to read the data.

Delete persistent data

To delete data from persistent storage call Storage_DeleteMutableFile.