File System
Most connected applications require the ability to store configuration information or cache local data. Gecko OS provides a reliable read/write filesystem and access to extended and bulk flash storage to satisfy application storage requirements.
Silicon Labs IoT modules contain a microprocessor with internal flash and an extended (on module) serial flash. An additional (optional) bulk serial flash is also supported. See Flash Storage . For third-party devices running Gecko OS, an extended serial flash must be provided to store temporary files and to enable wireless OTA updates.
Commands are available to create, delete and open files , and file contents can be easily accessed using one or more stream commands .
Here's a quick example showing how to create, manipulate then delete a file:
Gecko OS Commands | Description |
---|---|
|
|
When a file is open, Gecko OS creates a file stream and returns a file stream handle to be used as an argument of the
stream_read
command. See
Network Connections and Streams
. The stream type is
FILE
.
File System Limits
Prohibited Files and Directories
Files cannot be created under the
sys
virtual directory. That is, a file cannot be created where the file name begins with
sys/
. This prevents deleting and replacing 'system' files.
Minimum File Size
Files are created 4KByte aligned; that is, no file can occupy less flash space than 4K.
Maximum File Size
There is no limit to the size of an individual file other than the size of the extended or bulk serial flash connected to the Gecko OS hardware. However the method of creating the file may impose a limit.
When creating files via the
file_create
command without the
-o
option, or via the Web App, which uses
file_create
in the background, file size is limited by available RAM at file creation.
Maximum File Count
The minimum flash space occupied by files is
<number of files> * 4K
. For example, in
20K
of flash you can create no more than
5
files .
Listing Files
To list files, use the ls command .
To obtain a verbose listing of all files on the MCU-internal flash, bulk and extended serial flash, use the
ls command
with the
-v
(verbose) or
-l
(long) option. The
-v
and
-l
options result in the same listing. Users are permitted to write files only to serial flash.
ls -l
! # L Hnd Type Flag O Perm Size Created Version Filename
# 0 e 61 45 0401 d FFFF 743 1528250046 1.0.0 favicon.ico.gz
# 1 e 44 41 0401 d FFFF 1236 1528250046 1.0.0 geotrust_ca.pem
# 2 i 0 1 0607 d 0000 327424 1528250046 0.0.0 sys/kernel.bin
# 3 i 50 7 0607 d 0000 254768 1528250046 1.0.0 sys/plugins.bin
# 4 e 0 2 0605 d 0000 276552 1528250046 1.2.6 sys/wfm_wf200.sec
# 5 e C4 4 0201 u FFFF 2048 28 1.0.0 sys/wl_table.bin
# 6 e 45 45 0401 d FFFF 2357 1528250046 1.0.0 webapp/index.html
# 7 e 5E 45 0401 d FFFF 9745 1528250046 1.0.0 webapp/unauthorized.html
# 8 e 46 45 0401 d FFFF 22720 1528250046 1.0.0 webapp/gecko_os.css.gz
# 9 e 4C 45 0401 d FFFF 72947 1528250046 1.0.0 webapp/gecko_os.js.gz
The meaning of the columns is summarised here and covered in detail in the sections below:
-
L
- File memory location: i = internal, e = extended, b = bulk. See File Location . -
Hnd
- File handle as hex string. See File Handle . -
Type
- File types as hex string. See File Types . -
Flag
- File flags bitmask as hex string. See File Flags . -
O
- File owner:p
= product,d
= device,u
= user. See File Owner . -
Perm
- File permissions bitmask as hex string. See File Permissions . -
Size
- File size in bytes, in decimal format. -
Created
- UTC timestamp indicating when file was created on device: seconds since epoch in decimal format. -
Version
- File version as string. See File Version . -
Filename
- File's name. See File Names .
File Location
The
ls -l
file listing
L
column indicates the location of the file in internal, bulk or extended flash:
- i - MCU internal flash
- e - extended serial flash
- b - bulk serial flash
See Flash Storage below.
File Handle
The
ls -l
file listing
Hnd
column indicates the file handle. This is a file identifier that corresponds to the file's base sector in flash. The handle can be used with the
ls
command
-b
option for paging the file listing, and with the
file_open
,
file_delete
and
file_stat
<memory>-<handle>
parameters as a file identifier to distinguish files with the same file name.
File Types
The
ls
file listing
Type
column indicates the file type in hex. Gecko OS uses file type internally for file management.
File types are enumerated in the following table.
-
File types
0x00
to0x3F
are for Kernel use only. -
File types
0x40
to0x45
are fully accessible to the user: users can read, write and erase these files. -
File types
0x80
to0xFE
are custom types that can be set by the user. Use types in this range for file management specific to your application.
File type | ID (hex) | ID (dec) | Access |
---|---|---|---|
UNKNOWN | 0x00 | 0 | Kernel |
KERNEL | 0x01 | 1 | Kernel |
WIFI_FW | 0x02 | 2 | Kernel |
NVM_DEFAULTS | 0x03 | 3 | Kernel |
WEAR_LEVELING_TABLE | 0x04 | 4 | Kernel |
STARTUP_HANDLER | 0x05 | 5 | Kernel |
SAFEMODE_APP | 0x06 | 6 | Kernel |
PLUGINS_APP | 0x07 | 7 | Kernel |
USER_APP | 0x08 | 8 | Kernel |
TEMPORARY | 0x09 | 9 | Kernel |
NVM_USER_DEFAULTS | 0x0A | 10 | Kernel |
... Reserved ... | 0x0B-03F | 11 - 63 | Kernel |
USER_TYPES_START | 0x40 | 64 | User |
LOG | 0x40 | 64 | User |
TLS_CERTIFICATE | 0x41 | 65 | User |
GPIO_CONFIG | 0x42 | 66 | User |
SETTINGS_CSV | 0x43 | 67 | User |
GENERAL | 0x44 | 68 | User |
WEB_APP | 0x45 | 69 | User |
... Reserved ... | 0x46-0x7F | 70-127 | Kernel |
CUSTOM_START | 0x80 | 128 | User |
... Custom ... | 0x80-0xFE | 128-254 | User |
CUSTOM_END | 0xFE | 254 | User |
INVALID | 0xFF | 255 |
Custom User Types
The type range from
0x80
(decimal 128) to
0xFE
(decimal 254) is set aside for custom types. Use types in this range for file management specific to your application.
File Flags
The
ls
file listing
Flag
column indicates the file flags, in hex format, without a
0x
prefix.
Flag bits
0 - 7
are for Kernel use only and cannot be set by the application.
Flags correspond to bits as follows:
Flag | Bit | Notes | Access |
---|---|---|---|
Valid | 0 | File is valid on the File System. This flag can be set or cleared only by the kernel. | Kernel |
Executable | 1 | File is an executable (i.e. is an application). | Kernel |
Kernel-only | 2 | File is accessible only by the kernel. It is not readable by a customer application. | Kernel |
Reserved | 3 - 7 | Kernel | |
Encrypted | 8 |
0
: Not encrypted;
1
: Encrypted
See The Encrypted Flag . |
User |
Essential | 9 |
This flag can be set explicitly with the
-e
flag with the
file_create
and
http_download
commands. See
The Essential Flag
.
|
User |
Checksum Valid | 10 |
The file's checksum (CRC) field is valid. If this flag is set when creating a file, the checksum is validated against the supplied checksum before setting the file
Valid
flag.
|
User |
Pre-encrypted | 11 | The file's data is pre-encrypted. Gecko OS is not to encrypt the file as it is written. | User |
Examples:
Flags column | Flags Set |
---|---|
0101
|
Valid Encrypted |
0201
|
Valid Essential |
0301
|
Valid Encrypted Essential |
The Encrypted Flag
A file marked with the Encrypted flag is encrypted, either with the system.security_key or with the internal device key (AES key).
A file is encrypted on creation with the
file_create
and
http_download
commands, when you use the
-u
,
-d
or
-p
options.
-
-d
: encrypt automatically with the device key. -
-u
: encrypt automatically with the system.security_key ( u ser key). -
-p
: file contents are p re-encrypted with the system.security_key (user key).
See also Encrypting Gecko OS Files .
The Essential Flag
The Essential flag indicates that a file must not be deleted during an OTA. An OTA may delete files not marked Essential in order to make space for new or changed files.
You set the Essential flag on creating a file, using the
-e
option with the
file_create
and
http_download
commands.
File Owner
The
ls
file listing
O
column indicates the file owner. In the Gecko OS context, the file owner is the product, device, or user. The owner determines the encryption key to be used if file encryption is required.
ls code | Owner | Encryption Key |
---|---|---|
p
|
Product | DMS product's encryption key |
d
|
Device | Device's internal encryption key |
u
|
User | system.security_key |
File Permissions
The
ls
file listing
Perm
column indicates the file permissions. File permissions are displayed as a bit mask, specified as a hex string. The permissions attribute indicates which interfaces may read or delete the file. Note that if the 'Kernel-Only' file flag is set then this attribute is ignored.
The default permissions bitmask is
0xFFFF
: ALL
Interface | Bit | Notes |
---|---|---|
Serial Bus | 0 | Any UART, SPI, USB that has a command parser enabled |
Remote Terminal | 1 | Remote telnet terminal |
HTTP API | 2 | HTTP Server REST API or websocket |
Bluetooth | 3 | Bluetooth interface |
Zigbee | 4 | Zigbee interface |
File Version
For files that form part of the Gecko OS system, such as
services.bin
and
kernel.bin
, the file version follows the scheme:
<major>.<minor>.<patch>
When creating a user file, the user can choose the versioning scheme. The
file_create
and
http_download
commands provide a
version
option to set the version.
File Checksum
The checksum or CRC used on individual files is calculated using a CRC32 algorithm.
The file_create and http_download commands provide an option to set the CRC.
You can view a file CRC with the file_stat command. The CRC is the second item in the comma-separated list.
The following python fragment shows how the
binascii.crc32
function can be used to calculate the CRC.
import binascii
def crc32(data):
return binascii.crc32(data) & 0xffffffff
See also the File System application note.
File Names
File names are case sensitive, and can contain a maximum of 95 characters from the set:
A-Za-z0-9~!@#$%^&*()_+#.{}[]`=:;|\/'-.
That is, a file name can contain any character except for the double quote character. A double quote results in a parse error when creating a file with the file_create command.
It may be possible to create a file with a double quote character using other means, then download the file to the device flash.
The Gecko OS file system does not treat the
.
character or the
/
character differently to any other. These can be used to create pseudo extensions and pseudo folders. The web app recognizes the
/
character for folder emulation, which makes some file manipulations more convenient. See
Gecko OS Web App, Folder Emulation
.
Web app folder emulation creates some restrictions on where you can place a
/
character in a file name. These apply only to files manipulated in the Web App Files tab.
Special Files
Some files with special functions are listed in the following table:
File Name | Description | Notes |
---|---|---|
default_config.csv
|
Variable configuration, loaded after a successful OTA | See Configuration and Setup, Variable Configuration Script . |
factory_config.csv
|
Factory variable configuration, loaded if found after a hard or soft factory reset. | See Configuration and Setup, Variable Configuration Script . |
Writing Files
There are two Gecko OS commands that can write to the file system:
There are several ways to invoke these commands:
- Via the Gecko OS Web App . This is the simplest way to manage files manually.
- Manually, via a Gecko OS terminal or a remote terminal
- Under programmed MCU host control
- Via the HTTP Server RESTful API
Writing with the Web App File Browser
When you open the Gecko OS Web App in a web browser and select the Files tab , you can load files to the device file system using click and browse, or drag and drop.
In the background, the Gecko OS Web App uses the file_create command to write files to the device file system, using the HTTP Server RESTful API .
There are several ways to activate the Gecko OS Web App. See Gecko OS Web App .
Writing with the Terminal
In the Gecko OS terminal or remote terminal, use the file_create command to create the file. Immediately after issuing the command, type the file contents, or alternatively copy and paste the file contents into the terminal after issuing the fcr command. The length of the file must be supplied. The character count includes any line termination characters.
In the example below we create a script that can be run using the command setup cmd -v test.script . In this case the character count is 35.
> fcr test.script 35
help,setup,\r\n#This is a comment
File created
Success
Writing File Contents in Chunks
You can write the file in chunks by leaving the file open after issuing the
file_create
with the
-o
option. Write the file chunks to the stream returned by the
file_create
command. You must know the total size of the file to be created in advance.
When you open the file, Gecko OS returns a stream handle, to be used as an argument of the stream_write command. See Network Connections and Streams .
In the example below a small file is created in two chunks:
Commands and Responses | Description |
---|---|
|
|
HTTP Download
You can also provide the file for download from a web server accessible to the device, and use the http_download command. For example:
> http_download http://www.google.com.au/images/srpr/logo11w.png test1.png
Downloading: test1.png to flash file system
Request GET /images/srpr/logo11w.png
Connecting (http): www.google.com.au:80
HTTP response: 200
Success
> ls
! # Size Version Filename
…
# 4 14022 1.0.0 test1.png
…
OTA
OTA wireless updates allow you to update the Gecko OS system files automatically using the Zentri Device Management Service. Please contact Silicon Labs if you need custom hosting services for your application firmware or files.
Reading Files
The following Gecko OS commands can read from the file system:
There are several ways to invoke these commands:
- Via the Gecko OS Web App . This is the simplest way to manage files manually.
- Manually, via a Gecko OS terminal or a remote terminal
- Under programmed MCU host control
- Via the HTTP Server RESTful API
Reading with the Web App File Browser
When you open the Gecko OS Web App in a web browser and select the Files tab , you can download a file from the device file system by clicking the file name.
In the background, the Gecko OS Web App uses the file_open command to read the files from the device file system, using the HTTP Server RESTful API .
There are several ways to activate the Gecko OS Web App. See Gecko OS Web App .
Reading from a Terminal
You can read text files directly from the Gecko OS Terminal or remote terminal. Read the file, using a file_open followed by a stream_read command, specifying the stream index returned from the file open, e.g.:
> fop default_setup.script
[Opened: 0]
0
> read 0 1000
network_up,-s ,Configuration network credentials
set wlan.auto_join.enabled,true,Enable network auto-join
save,-,Saving settings
[Closed: 0]
HTTP Upload
You can upload the file to an available web server with file upload capability with the http_upload command.
Flash Storage
A Gecko OS device uses executable flash memory for storage of programs and critical system information, as well as extended flash and (optional) bulk flash memory for storage of user files and some system files.
Extended flash memory may be physically located inside the microprocessor on the Gecko OS device, or it may be located on a serial flash device. A bulk serial flash may be added if additional storage is required.
Flash Wear Leveling
The flash wear leveling feature ensures that all sectors on the extended/bulk flash are evenly used. This allows for maximum file writes to the extended/bulk flash. This system works seamlessly in the background, and requires no user activity.
The file
sys/wl_table.bin
is used by the flash wear leveling feature.
Bulk Flash
In addition, an external serial flash can be connected to the device using the existing sflash GPIOs. This is referred to as bulk flash .
To enable access to bulk flash, configure the chip select GPIO with the system.bflash.cs_gpio variable. Configure the bulk flash SPI port with the system.bflash.port variable.
By default Gecko OS can support up to 128MB bulk flash.
All OTA files and config files (created by the save command) are always stored on extended flash regardless of whether the bulk flash is enabled.
The following commands operate on bulk flash if available, otherwise on extended flash:
- http_download - saves file to bulk flash if available, otherwise to extended flash
-
file_create
- with no options, saves file to bulk flash if available, otherwise to extended flash. Use the
--extended
and--bulk
options to specify creating the file on bulk or extended flash - file_open - opens file if found on bulk flash, otherwise on extended flash
- file_delete - deletes file if found on bulk flash, otherwise on extended flash
Extended and bulk flash can be formatted with the format_flash command.
Supported Bulk Flash Chips
Serial flash chips currently supported by Gecko OS are as follows:
Model ID |
Storage Capacity
(Megabytes) |
---|---|
SFLASH_ID_EN25QH16 | 2MB |
SFLASH_ID_EN25Q80B | 1MB |
SFLASH_ID_IS25LP032 | 4MB |
SFLASH_ID_IS25LP064 | 8MB |
SFLASH_ID_IS25LP128 | 16MB |
SFLASH_ID_MX25L1606E | 2MB |
SFLASH_ID_MX25L3233F | 4MB |
SFLASH_ID_MX25L6406E | 8MB |
SFLASH_ID_MX25L8035E | 1MB |
SFLASH_ID_MX25R8035F | 1MB |
SFLASH_ID_MX25R1635F | 2MB |
SFLASH_ID_MX25V8035F | 2MB |
SFLASH_ID_SST25VF080B | 1MB |
SFLASH_ID_SST26VF016B | 2MB |
If you require support for a serial flash chip not listed in the table above, please contact Silicon Labs .
Connecting Bulk Serial Flash to the Device
The Gecko OS device is the SPI master. The bulk sflash is the SPI slave.
Connecting bulk sflash to the device requires 4 signals. The GPIO numbers vary depending on the device.
Use the format_flash bulk command to erase the contents of the sflash.
The bulk sflash uses the same SPI bus as the extended serial flash on-board the module. Thus the SPI parameters (clock speed, polarity, etc) are not configurable.
Encrypting Gecko OS Files
Gecko OS maintains three different AES encryption keys. The keys are as follows:
Name | Programmed/Updated | Location | Persistence | Uniqueness | Description |
---|---|---|---|---|---|
Product | Manufacturing or DFU | Kernel binary | Lifetime of product on DMS | Common for all devices of a given product type |
The 'product' encryption key is used to encrypt DFU images. The Kernel uses this key to decrypt DFU image data as it's read. The 'product' encryption key resides in the Kernel binary.
When an encrypted file 'owned' by the product is written to extended/bulk flash it is encrypted with this key. |
Device | First time its needed | NVM | Lifetime of internal flash | Unique per device |
The device internally generates this. It is never externally accessible.
When an encrypted file 'owned' by the device is written to extended/bulk flash it is encrypted with this key. |
User | Manufacturing, DFU, 'set' command | NVM | User specified | User specified |
The user generates this. It is set during DFU or the command 'set system.user_key'.
When an encrypted file 'owned' by the user is written to extended/bulk flash it is encrypted with this key. |
DFU File Encryption Sequence
The DFU (Device Firmware Update) process uses the product and device keys.
When performing a DFU, the DFU images are encrypted by the DMS with the device's product key. As the device reads the DFU image data, it decrypts the data using the product key embedded in the Kernel and writes the bundle files to their corresponding memory location.
IF a bundle file has its Encrypted flag set AND the file's 'owner' field is set to 'device', THEN the file is encrypted with the device's AES as it is written to device memory.
IF a bundle file has its Encrypted flag set AND the file's 'owner' field is set to 'product' or 'user', THEN the file is written AS-IS to device memory (the file is assumed to be encrypted with the corresponding key before sending to the device).
Encrypted File Format
A Gecko OS encrypted file has the following format:
-
32 byte 'header':
- 16 byte Initialization Vector (IV), used to do the AES CBC encryption
- 16 byte Hash Message Authentication Code (HMAC), used to verify the decrypted data
- Encrypted file data
So an encrypted file is always 32 bytes longer than a file with same contents unencrypted.
Encryption Sequence
The sequence for encrypting a file is as follows:
- Generate Initialization Vector (IV)
- Initialize AES-128 context with the user AES key
- Calculate the Cipher Block Chaining (CBC) of the entire file, IV=0, and pad with 0s to 16 bytes if necessary, the last 16 bytes of the encrypted output is used as the HMAC
- Write the initial IV (the IV from step 1) to the output file/buffer
- Using the IV from step 1 and AES-128 context from step 2, using CTR mode encrypt HMAC and write to output file/buffer
- Using IV from step 5 and AES-128 context from step 2, using CTR mode encrypt file contents and write to output file/buffer
Decryption Sequence
The sequence for decrypting a file is as follows:
- Initialize AES-128 context with the user AES key
- Read the 16 byte IV from the beginning of the encrypted file
- Read the 16 bytes encrypted HMAC from the file
- Using the AES context from Step 1 and the IV from Step 2, decrypt the HMAC using AES CTR mode
- Using the AES context and IV from step 4, decrypt the rest of the file using AES CTR mode
- Calculate the Cipher Block Chaining (CBC) of the decrypted file data from step 5, IV=0, and pad with 0s to 16 bytes if necessary
- The final block from step 6 should match the HMAC from step 4. If the two 16 byte values don't match then either the given user key is invalid or the encrypted file is corrupted.
Preventing File Corruption
The Gecko OS file system is designed to be resistant to file corruption. A file does not appear in the file system until it is marked as valid. See File Flags . A file is marked as valid only after all file data is written and validated. When a file is not valid, it cannot be listed with the ls command or opened with the file_open command. A valid file may not be modified. That is, file size and contents cannot be modified after the file is created.
This ensures the file system does not become populated with corrupt files due to sudden power loss, reset, or interruption of the file stream during writing.
Although normal files cannot be modified, you can add contents to a log file after it is created.
The steps in file creation are as follows:
- A file is created with the specified size.
- The file data is then written.
-
Once all the data is written, the file contents are validated and the file's
valid
flag is set to true.
If the module is reset or power cycled, or the file stream is manually closed before the
valid
flag is set, the created file and any written contents are lost.
Once the
valid
flag is set, the file may not be modified.
Log Files
There is no command API interface to this feature. Log files are available only through the Native API File System API :
Log files are used when the file contents are not known in advance, and when small amounts of data are to be written to the file in future.
For example, an application that wakes, writes sensor readings, then goes to sleep or shuts down, can use a log file to accumulate sensor data over a period of time.
If all the data is immediately available, normal files are more appropriate than log files.
A log file is created with a specified total size. The contents of the file are left blank. Logs may then be written to the file at any point thereafter.
Each log has its own header which indicates the log's size and has a
valid
flag. When a log is appended, a header is created and the log data is written. Once all the log data is written, the log's
valid
flag is set.
Log File Format
When a log file is generated, its entire contents is erased (i.e. the contents is set to
0xFF
).
When you call
gos_log_file_append()
, Gecko OS appends an individual log entry to the first blank (i.e. first
0xFFFF
) in the file.
The log entry starts with a 16bit header. The first 15bits contain the log's length in bytes (little-endian). The MSb is the log entry
valid
flag. When the MSb of the log's header is cleared (i.e. 0) the log entry is valid. After the 16bit header is the log's contents with length specified in the header.
After the log entry data is written, the MSb of the header is cleared to indicate that the log is valid.
The general format of a log file is:
<header><log data><header><log data>....<header><log data>0xFFFF...
where
<header>
is:
<1bit valid flag><15bit log data length, little-endian>