From 4f57350ae9a994ec340a34b4e715ceb34f3300c8 Mon Sep 17 00:00:00 2001 From: Aldwin Hermanudin Date: Mon, 11 Dec 2023 17:37:38 -0800 Subject: [PATCH] update test flash and deep-sleep --- src/mbedos/test-deep-sleep/main.cpp | 22 ++++++- src/mbedos/test-flash/mbed_app.json | 9 ++- src/mbedos/test-flash/readme.md | 39 +++++++----- src/mbedos/test-flash/source/main.cpp | 90 ++++++++++++++++++++++++--- 4 files changed, 132 insertions(+), 28 deletions(-) diff --git a/src/mbedos/test-deep-sleep/main.cpp b/src/mbedos/test-deep-sleep/main.cpp index 4bf8fa2..12bd892 100644 --- a/src/mbedos/test-deep-sleep/main.cpp +++ b/src/mbedos/test-deep-sleep/main.cpp @@ -1,3 +1,12 @@ +/* + * + * Deep-sleep test + * Compiled in `Develop` or Release` build. The following is the expected behavior: + * a. RED LED ( PA1 ) is on for 5 seconds. Consumed around 1.5ma + * b. RED LED ( PA1 ) is off for 10 seconds. Consumed around 10ua + * c. Repeat to inifinity + * + */ #include #include "external/bme680/BME680.h" @@ -5,6 +14,8 @@ mbed::DigitalOut led0(PA_15); mbed::DigitalOut led1(PA_1); +uint32_t sram_data = 0; + int main() { // disable on-board LED @@ -45,7 +56,16 @@ int main() bool read_dummy = sda; read_dummy = scl; + sram_data = 0xfeedbeef; + while (1) { + // data should still be retained even after deep-sleep + if ( sram_data == 0xfeedbeef){ + led0 = 1; + // go to deep-sleep STOP2 + ThisThread::sleep_for(5000ms); + led0 = 0; + } ThisThread::sleep_for(10000ms); } -} \ No newline at end of file +} diff --git a/src/mbedos/test-flash/mbed_app.json b/src/mbedos/test-flash/mbed_app.json index 60c2dd4..20e0456 100644 --- a/src/mbedos/test-flash/mbed_app.json +++ b/src/mbedos/test-flash/mbed_app.json @@ -1,13 +1,18 @@ { "config": { - "main_stack_size": { "value": 4096 } + "main_stack_size": { + "value": 4096 + } }, "target_overrides": { "*": { + "target.features_add": ["STORAGE"], + "target.components_add": ["FLASH", "FLASHIAP"], + "target.restrict_size": "0x3C000", "target.c_lib": "std", "target.printf_lib": "std", "platform.cpu-stats-enabled": 0, - "target.macros_add": ["MBED_TICKLESS", "DEVICE_I2C_FREE_DESTRUCTOR"], + "target.macros_add": ["MBED_TICKLESS", "DEVICE_I2C_FREE_DESTRUCTOR", "MBED_SLEEP_TRACING_ENABLED"], "platform.stdio-buffered-serial": 1, "platform.stdio-convert-newlines": true, "platform.stdio-baud-rate": 115200, diff --git a/src/mbedos/test-flash/readme.md b/src/mbedos/test-flash/readme.md index e2ea339..36a0232 100644 --- a/src/mbedos/test-flash/readme.md +++ b/src/mbedos/test-flash/readme.md @@ -1,22 +1,29 @@ +# RAK3172 Flash IAP Example -# BSEC BME688 Test Example +Uses the internal flash as user data. This example uses first `245760` bytes as application and remaining `16384` bytes as user data that user can access. Some details about the size as follow: +- Sector size: `2048` bytes +- Application size: `sector size * 120` = `2048 * 120` = `245760` bytes +- User data size: remaining flash space = `2048 * 8` = `16384` bytes -Tested on: +Below configuration needs to be enabled to limit the application size to specific size. Under `mbed_app.json` set the following: - - Compiler ARMC6 - - With/without sleep trace enabled - - [BSEC2 Library](https://www.bosch-sensortec.com/software-tools/software/bme688-software/) + "target_overrides": { + "*": { + "target.features_add": ["STORAGE"], + "target.components_add": ["FLASH", "FLASHIAP"], + "target.restrict_size": "0x3C000" + ... + ... + } + } -## Acknowledgement -Source code is based on https://github.com/Mircerson/AERQ +`"target.features_add": ["STORAGE"]` and `"target.components_add": ["FLASH", "FLASHIAP"]` might be optional. +`"target.restrict_size": "0x3C000"` limit the application size to `245760` bytes -## TODO +## Reference -- [ ] Update BSEC library to use the latest version -- [ ] Provide BSEC static library - - `libalgobsec.a` for GCC_ARM - - `libalgobsec.ar` for ARMC6 ( currently rename the .lib file to .ar from the BSEC library) - - STM32WL55CC is Cortex-M4 -- [ ] Implement simple AQI reader without proper sleep -- [ ] Rewrite BME688 high-level library -- [ ] Create a different repo for proper AQI reader with sleep +The following are some good reference: +- https://tronche.com/blog/2020/03/mbed-flashiap-tdbstore-and-stm32f4-internal-flash/ +- https://os.mbed.com/docs/mbed-os/v6.16/program-setup/creating-and-using-a-bootloader.html +- https://forums.mbed.com/t/how-can-i-provision-a-persistent-array-of-int-in-flash-memory-and-access-it-as-an-array-of-int-from-mbed-c/6927/8 +- https://forums.mbed.com/t/saving-config-data-with-flashiap-on-stm32l476rg-isnt-persisting-the-data/14721 \ No newline at end of file diff --git a/src/mbedos/test-flash/source/main.cpp b/src/mbedos/test-flash/source/main.cpp index 4a2e742..6e0750f 100644 --- a/src/mbedos/test-flash/source/main.cpp +++ b/src/mbedos/test-flash/source/main.cpp @@ -1,29 +1,101 @@ -/* - * Copyright (c) 2020 Arm Limited and affiliates. - * SPDX-License-Identifier: Apache-2.0 - */ #include "mbed.h" +// this example define the remaining flash area as user data +#define FLASH_USER_DATA_ADDR POST_APPLICATION_ADDR +#define FLASH_USER_DATA_SIZE POST_APPLICATION_SIZE + Thread thread; FlashIAP flash; mbed::DigitalOut led0(PA_1); -DigitalOut led1(PA_15); +mbed::DigitalOut led1(PA_15); -// Spawns a thread to run blink for 5 seconds int main() { led0 = 0; led1 = 0; + flash.init(); + + // print flash information uint32_t flash_start = flash.get_flash_start(); uint32_t flash_size = flash.get_flash_size(); uint32_t page_size = flash.get_page_size(); + printf("Flash start: 0x%x \r\n", flash_start); + printf("Flash size: %d bytes\r\n", flash_size); + printf("Page size: %d bytes\r\n", page_size); + printf("Sector size: %d bytes\r\n", flash.get_sector_size(flash_start)); + printf("App start address: 0x%x\r\n", APPLICATION_ADDR); + printf("App size: %d bytes\r\n", APPLICATION_SIZE); + printf("Post App start address: 0x%x\r\n", POST_APPLICATION_ADDR); + printf("Post App size: %d bytes\r\n", POST_APPLICATION_SIZE); + // see: https://os.mbed.com/docs/mbed-os/v6.16/program-setup/bootloader-configuration.html + // for information on application address and size + + int result; + const char header_magic[] = "USRDAT1"; + uint8_t buf_read[1024]; + + // read user-data area + result = flash.read( buf_read, FLASH_USER_DATA_ADDR, sizeof(header_magic) ); + if ( result != 0) + { + printf("failed to read user-data memory\r\n"); + } + else + { + printf("successfully read user-data memory\r\n"); + } + + // check if magic header exist in the flash + result = -1; + for( int i =0; i<(sizeof(header_magic)) ; i++) + { + if( buf_read[i] != header_magic[i] ) + { + result = -1; + break; + } + } + if ( result != 0) + { + printf("magic header not found\r\n"); + } + else + { + printf("magic header found\r\n"); + printf("got %s\r\n", buf_read); + } + + // if magic header not found, then write it + if ( result != 0 ) + { + // erase all user-data + result = flash.erase(FLASH_USER_DATA_ADDR, FLASH_USER_DATA_SIZE); + if ( result != 0) + { + printf("failed to erase user-data memory\r\n"); + } + else + { + printf("successfully erase user-data memory\r\n"); + } + + // write data to user-data area + result = flash.program( header_magic, FLASH_USER_DATA_ADDR, sizeof(header_magic) ); + if ( result != 0) + { + printf("failed to program user-data memory\r\n"); + } + else + { + printf("successfully program user-data memory\r\n"); + } + } - printf("Flash start: %ld bytes\r\n", flash_start); - printf("Flash size: %ld bytes\r\n", flash_size); - printf("Page size: %ld bytes\r\n", page_size); + flash.deinit(); + // sleep to inifinity while ( 1 ) { ThisThread::sleep_for(5000ms);