diff --git a/examples/suit_update/Makefile b/examples/suit_update/Makefile index a370233c43..8f85fcd493 100644 --- a/examples/suit_update/Makefile +++ b/examples/suit_update/Makefile @@ -101,6 +101,9 @@ TESTRUNNER_RESET_AFTER_TERM ?= 1 # with ed25519 support. TEST_ON_CI_BLACKLIST = all +# Add custom SUIT targets +include $(CURDIR)/Makefile.suit.custom + include $(RIOTBASE)/Makefile.include # allow to use large blocks to utilize large MTUs (802.15.4g, Ethernet, WiFi) diff --git a/examples/suit_update/Makefile.board.dep b/examples/suit_update/Makefile.board.dep index 032ebfd415..f682da2777 100644 --- a/examples/suit_update/Makefile.board.dep +++ b/examples/suit_update/Makefile.board.dep @@ -1,6 +1,14 @@ ifeq ($(BOARD),native) USEMODULE += suit_storage_ram USEMODULE += netdev_default + # Use VFS storage for native + USEMODULE += suit_storage_vfs + ## Use VFS + USEMODULE += vfs + ## Use default storage + USEMODULE += vfs_default + ## Auto-format on mount + USEMODULE += vfs_auto_format else USEMODULE += suit_storage_flashwrite endif diff --git a/examples/suit_update/Makefile.suit.custom b/examples/suit_update/Makefile.suit.custom new file mode 100644 index 0000000000..0e2c8bd1e3 --- /dev/null +++ b/examples/suit_update/Makefile.suit.custom @@ -0,0 +1,30 @@ +# Required variables defined in riotboot.inc.mk or Makefile.include +BINDIR_APP = $(CURDIR)/bin/$(BOARD)/$(APPLICATION) +$(BINDIR_APP): $(CLEAN) + $(Q)mkdir -p $(BINDIR_APP) + +# Include to be able to use memoized +include $(RIOTBASE)/makefiles/utils/variables.mk +EPOCH = $(call memoized,EPOCH,$(shell date +%s)) +APP_VER ?= $(EPOCH) + +# Default addressing if following README.native.md +ifeq ($(BOARD),native) + SUIT_CLIENT ?= [2001:db8::2] + SUIT_COAP_SERVER ?= [2001:db8::1] +endif + +ifeq ($(BOARD),native) + # Set settings for publishing fake fw payloads to native + SUIT_NATIVE_PAYLOAD ?= "AABBCCDD" + SUIT_NATIVE_PAYLOAD_BIN ?= $(BINDIR_APP)/fw.$(APP_VER).bin + # Make sure it is built + BUILD_FILES += $(SUIT_NATIVE_PAYLOAD_BIN) + + $(SUIT_NATIVE_PAYLOAD_BIN): $(BINDIR_APP) + $(Q)echo $(SUIT_NATIVE_PAYLOAD) > $@ + + SUIT_FW_STORAGE ?= /nvm0/SLOT0.TXT + SUIT_MANIFEST_PAYLOADS ?= $(SUIT_NATIVE_PAYLOAD_BIN) + SUIT_MANIFEST_SLOTFILES ?= $(SUIT_NATIVE_PAYLOAD_BIN):0:$(SUIT_FW_STORAGE) +endif diff --git a/examples/suit_update/README.native.md b/examples/suit_update/README.native.md index 96887a515f..053b597f05 100644 --- a/examples/suit_update/README.native.md +++ b/examples/suit_update/README.native.md @@ -48,7 +48,7 @@ $ dist/tools/suit/suit-manifest-generator/bin/suit-tool sign -k keys/default.pem 5. Pull the manifest from the native instance: ``` -> suit coap://[2001:db8::1]/suit_manifest.signed +> suit fetch coap://[2001:db8::1]/suit_manifest.signed ``` 6. Verify the content of the storage location @@ -172,14 +172,18 @@ the payloads. lsstorage RAM slot 0: ".ram.0" RAM slot 1: ".ram.1" +VFS 0: "/nvm0/SLOT0.txt" +VFS 1: "/nvm0/SLOT1.txt" ``` -As shown above, two storage locations are available, `.ram.0` and `.ram.1`. -While two slots are available, in this example only the content of the `.ram.0` -slot will be updated. +As shown above, four storage locations are available, RAM based storage: `.ram.0` and `.ram.1` +as well as VFS based storage: `/nvm0/SLOT0.TXT` and `/nvm0/SLOT1.TXT`. +While multiple slots are available, in this example only the content of the `.ram.0` +slot will be updated, but the procedure is the same for any other slot, just replace +`.ram.0 - The `storage_content` command can be used to display a hex dump command of one - of the storage locations. It requires a location string, an offset and a + of the RAM storage locations. It requires a location string, an offset and a number of bytes to print: ```console @@ -188,6 +192,13 @@ slot will be updated. ``` As the storage location is empty on boot, nothing is printed. +For VFS based storage the `vfs` command can be used instead: +```console +> vfs r /nvm0/SLOT0.txt +Error opening file "/nvm0/SLOT0.txt": -ENOENT +``` +But as the file does not initially exist, nothing is printed. + ### Generating the payload and manifest [generating-the-payload-and-manifest]: #generating-the-payload-and-manifest @@ -208,6 +219,12 @@ acts as a template for the real SUIT manifest. Within RIOT, the script $ dist/tools/suit/gen_manifest.py --urlroot coap://[2001:db8::1]/ --seqnr 1 -o suit.tmp coaproot/payload.bin:0:ram:0 ``` +or for vfs storage: + +```console +$ dist/tools/suit/gen_manifest.py --urlroot coap://[2001:db8::1]/ --seqnr 1 -o suit.tmp coaproot/payload.bin:0:/nvm0/SLOT0.txt +``` + This generates a suit manifest template with the sequence number set to `1`, a payload that should be stored at slot offset zero in slot `.ram.0`. The url for the payload starts with `coap://[fe80::4049:bfff:fe60:db09]/`. Make sure to @@ -294,7 +311,7 @@ command sequences in the manifest and download the payload when instructed to. The URL for the manifest can be supplied to the instance via the command line. ```console -> suit coap://[2001:db8::1]/suit_manifest.signed +> suit fetch coap://[2001:db8::1]/suit_manifest.signed ``` The payload is the full URL to the signed manifest. The native instance should @@ -338,6 +355,14 @@ same payload as suggested above was used, it should look like this: 41414242434344440A ``` -The process can be done multiple times with both slot `.ram.0` and `.ram.1` and +Or for vfs storage: + +``` +> vfs r /nvm0/SLOT0.txt +vfs r /nvm0/SLOT0.txt +00000000: 4141 4242 4343 4444 0a AABBCCDD. +-- EOF -- +``` +The process can be done multiple times for any of the slots and different payloads. Keep in mind that the sequence number is a strict monotonically number and must be increased after every update. diff --git a/examples/suit_update/main.c b/examples/suit_update/main.c index 58dbd650be..21f2569c63 100644 --- a/examples/suit_update/main.c +++ b/examples/suit_update/main.c @@ -33,6 +33,11 @@ #include "suit/storage.h" #include "suit/storage/ram.h" +#ifdef BOARD_NATIVE +#include "suit/storage/vfs.h" +#include "xfa.h" +#include "vfs_default.h" +#endif #ifdef MODULE_PERIPH_GPIO #include "periph/gpio.h" @@ -48,6 +53,15 @@ static msg_t _nanocoap_server_msg_queue[NANOCOAP_SERVER_QUEUE_SIZE]; #define MAIN_QUEUE_SIZE (8) static msg_t _main_msg_queue[MAIN_QUEUE_SIZE]; +/* add handled storages */ +#if IS_USED(MODULE_SUIT_STORAGE_VFS) +XFA_USE(char*, suit_storage_files_reg); +#ifdef BOARD_NATIVE +XFA(suit_storage_files_reg, 0) char* _slot0 = VFS_DEFAULT_DATA "/SLOT0.txt"; +XFA(suit_storage_files_reg, 1) char* _slot1 = VFS_DEFAULT_DATA "/SLOT1.txt"; +#endif +#endif + static void *_nanocoap_server_thread(void *arg) { (void)arg; @@ -162,6 +176,12 @@ static int cmd_lsstorage(int argc, char **argv) if (IS_ACTIVE(MODULE_SUIT_STORAGE_FLASHWRITE)) { puts("Flashwrite slot 0: \"\"\n"); } +#if IS_USED(MODULE_SUIT_STORAGE_VFS) + for (unsigned i = 0; i < XFA_LEN(char **, suit_storage_files_reg); i++) { + const char *filepath = (const char *)suit_storage_files_reg[i]; + printf("VFS %u: \"%s\"\n", i, filepath); + } +#endif return 0; } @@ -189,7 +209,8 @@ int main(void) cmd_print_current_slot(0, NULL); cmd_print_riotboot_hdr(0, NULL); #endif - + /* initialize suit storage */ + suit_storage_init_all(); /* start suit coap updater thread */ suit_coap_run();