From 65f9d447e4fc8ecb60d4e0e5a42c76343d032586 Mon Sep 17 00:00:00 2001 From: Timo Kokkonen Date: Sun, 3 Mar 2024 20:45:38 -0800 Subject: [PATCH] Fix hang during boot if flash filesystem needed to be initialized. (#81) * Fix hang when no flash filesystem was found during boot. * Remove full path from compiler macros (like __FILE__) to slightly reduce firmware size. * Add new command: SYS:LFS:FORMAT --- CMakeLists.txt | 4 +++- commands.md | 35 +++++++++++++++++++++++------------ libs/pico-lfs | 2 +- src/command.c | 22 +++++++++++++++++++--- src/fanpico.c | 2 +- src/fanpico.h | 3 ++- src/flash.c | 27 +++++++++++++++++++++------ 7 files changed, 70 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 990283d..000febc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake) project(fanpico - VERSION 1.6.1 + VERSION 1.6.2 LANGUAGES C CXX ASM ) set(CMAKE_C_STANDARD 11) @@ -184,6 +184,8 @@ if (PICO_CYW43_SUPPORTED) # set by PICO_BOARD=pico_w endif() target_compile_options(fanpico PRIVATE -Wall) +target_compile_options(fanpico PRIVATE -fmacro-prefix-map=${CMAKE_SOURCE_DIR}/=) + target_compile_definitions(fanpico PRIVATE USBD_MANUFACTURER="TJKO Industries") target_compile_definitions(fanpico PRIVATE USBD_PRODUCT="FanPico-${FANPICO_BOARD} Fan Controller") target_compile_definitions(fanpico PRIVATE USBD_DESC_STR_MAX=32) diff --git a/commands.md b/commands.md index a1e1406..bc03822 100644 --- a/commands.md +++ b/commands.md @@ -108,6 +108,7 @@ Fanpico supports following commands: * [SYStem:LED](#systemled) * [SYStem:LED?](#systemled-1) * [SYStem:LFS?](#systemlfs) +* [SYStem:LFS:FORMAT](#systemlfsformat) * [SYStem:MBFANS?](#systemmbfans) * [SYStem:MEM](#systemmem) * [SYStem:MEM?](#systemmem-1) @@ -1512,7 +1513,7 @@ SYS:DISP? #### SYStem:DISPlay:LAYOUTR Configure (OLED) Display layout for the right side of the screen. -Layout is specified as a comma delimited string descibing what to +Layout is specified as a comma delimited string describing what to display on each row (8 rows available if using 128x64 OLEd module, 10 rows available with 128x128 pixel modules). Syntax: ,,... @@ -1525,7 +1526,7 @@ Mn|MBFan input n|n=1..4 Sn|Sensor input n|n=1..3 Vn|Virtual Sensor input n|n=1..8 -|Horizontal Line| -Ltext|Line with "text"|Max lenght 9 characters. +Ltext|Line with "text"|Max length 9 characters. Default: @@ -1695,6 +1696,16 @@ Number of subdirectories: 0 ``` +#### SYStem:LFS:FORMAT +Format flash filesystem. This will erase current configuration (including any TLS certificates saved in flash). + +Example (format filesystem and save current configuration): +``` +SYS:LFS:FORMAT +CONF:SAVE +``` + + #### SYStem:MBFANS? Display number of MBFAN input ports available. @@ -1706,10 +1717,10 @@ SYS:MBFANS? ### SYStem:MEM -Test how much availble (heap) memory system currently has. +Test how much available (heap) memory system currently has. This does simple test to try to determine what is the largest block of heap memory that is currently available as well as -try allocating as many as possible small block of memory to determin +try allocating as many as possible small block of memory to determine roughly the total available heap memory. This command takes optional 'blocksize' parameter to specify the memory @@ -1727,7 +1738,7 @@ Total available memory: 111104 bytes (217 x 512bytes) Returns information about heap and stack size. As well as information about current (heap) memory usage as returned by _mallinfo()_ system call. -Note, _mallinfo()_ doesnt "see" all of the available heap memory, unless ```SYS:MEM``` command +Note, _mallinfo()_ does not always "see" all of the available heap memory, unless ```SYS:MEM``` command has been run first. Example: @@ -1751,7 +1762,7 @@ Topmost releasable block (keepcost): 114808 ### SYStem:MQTT Commands -FanPico has MQTT Client that can be confiugred to publish (send) periodic status +FanPico has MQTT Client that can be configured to publish (send) periodic status updates to a topic. Additionally MQTT Client support subscribing to a "command" topic to listen for commands. This allows remotely controlling BrickPico. @@ -2177,7 +2188,7 @@ SYS:MQTT:TOPIC:RESP musername/feeds/response #### SYStem:MQTT:TOPIC:RESPonse? -Query currently set topic for publishing reponses to commands. +Query currently set topic for publishing responses to commands. Example: ``` @@ -2573,7 +2584,7 @@ Upload or delete TLS certificate for the HTTP server. Note, both certificate and private key must be installed before HTTPS server will activate (when system is restarted next time). -When run withouth arguments this will prompt to paste TLS (X.509) certificate +When run without arguments this will prompt to paste TLS (X.509) certificate in PEM format. When run with "DELETE" argument currently installed certificate will be deleted. @@ -2603,7 +2614,7 @@ Upload or delete (TLS Certificate) Private key for the HTTP server. Note, both certificate and private key must be installed before HTTPS server will activate (when system is restarted next time). -When run withouth arguments this will prompt to paste private key +When run without arguments this will prompt to paste private key in PEM format. When run with "DELETE" argument currently installed private key will be deleted. @@ -2614,7 +2625,7 @@ Paste private key in PEM format: ``` -Examnple (upload/paste EC private key and EC parameters): +Example (upload/paste EC private key and EC parameters): ``` SYS:TLS:PKEY 2 Paste private key in PEM format: @@ -2773,7 +2784,7 @@ SYS:WIFI:IP? Set WiFi connection mode. Normally this setting is not needed with modern APs. However, if FanPico is failing to connect to WiFi network, this couldbe -due to old firmware on the AP (upgrading to latest firmare typically helps). +due to old firmware on the AP (upgrading to latest firmware typically helps). If firmware update did not help or there is no updated firmware available, setting connection mode to synchronous can help (however this could cause FanPico to "hang" for up to 60 seconds during boot up). @@ -2794,7 +2805,7 @@ SYS:WIFI:MODE 1 ``` #### SYStem:WIFI:MODE? -Display currently configured WiFi connection mdoe? +Display currently configured WiFi connection mode? Example: diff --git a/libs/pico-lfs b/libs/pico-lfs index 9e4990a..fa25285 160000 --- a/libs/pico-lfs +++ b/libs/pico-lfs @@ -1 +1 @@ -Subproject commit 9e4990ad457cb14a13c05ed08e6cf0a608773643 +Subproject commit fa252859f016f48bd642387fc1734020b84e57ff diff --git a/src/command.c b/src/command.c index 61cc741..e5e6690 100644 --- a/src/command.c +++ b/src/command.c @@ -34,7 +34,6 @@ #include "hardware/watchdog.h" #include "hardware/rtc.h" #include "cJSON.h" -#include "lfs.h" #include "fanpico.h" #ifdef WIFI_SUPPORT #include "lwip/ip_addr.h" @@ -2274,7 +2273,7 @@ int cmd_name(const char *cmd, const char *args, int query, char *prev_cmd) } -int cmd_littlefs(const char *cmd, const char *args, int query, char *prev_cmd) +int cmd_lfs(const char *cmd, const char *args, int query, char *prev_cmd) { size_t size, free, used, files, dirs; @@ -2293,6 +2292,18 @@ int cmd_littlefs(const char *cmd, const char *args, int query, char *prev_cmd) return 0; } +int cmd_lfs_format(const char *cmd, const char *args, int query, char *prev_cmd) +{ + if (query) + return 1; + + printf("Formatting flash filesystem...\n"); + if (flash_format(true)) + return 2; + printf("Filesystem successfully formatted.\n"); + + return 0; +} int cmd_flash(const char *cmd, const char *args, int query, char *prev_cmd) { @@ -2383,6 +2394,11 @@ const struct cmd_t display_commands[] = { { 0, 0, 0, 0 } }; +const struct cmd_t lfs_commands[] = { + { "FORMAT", 6, NULL, cmd_lfs_format }, + { 0, 0, 0, 0 } +}; + const struct cmd_t wifi_commands[] = { #ifdef WIFI_SUPPORT { "COUntry", 3, NULL, cmd_wifi_country }, @@ -2478,7 +2494,7 @@ const struct cmd_t system_commands[] = { { "FANS", 4, NULL, cmd_fans }, { "FLASH", 5, NULL, cmd_flash }, { "LED", 3, NULL, cmd_led }, - { "LFS", 3, NULL, cmd_littlefs }, + { "LFS", 3, lfs_commands, cmd_lfs }, { "LOG", 3, NULL, cmd_log_level }, { "MBFANS", 6, NULL, cmd_mbfans }, { "MEMory", 3, NULL, cmd_memory }, diff --git a/src/fanpico.c b/src/fanpico.c index e08037d..5d620c7 100644 --- a/src/fanpico.c +++ b/src/fanpico.c @@ -133,7 +133,7 @@ void setup() sleep_ms(50); } - lfs_setup(); + lfs_setup(false); read_config(); #if TTL_SERIAL diff --git a/src/fanpico.h b/src/fanpico.h index fd1320e..0cca448 100644 --- a/src/fanpico.h +++ b/src/fanpico.h @@ -324,7 +324,8 @@ void oled_display_status(const struct fanpico_state *state, const struct fanpico void oled_display_message(int rows, const char **text_lines); /* flash.h */ -void lfs_setup(); +void lfs_setup(bool multicore); +int flash_format(bool multicore); int flash_read_file(char **bufptr, uint32_t *sizeptr, const char *filename); int flash_write_file(const char *buf, uint32_t size, const char *filename); int flash_delete_file(const char *filename); diff --git a/src/flash.c b/src/flash.c index 0d4a995..c4aed05 100644 --- a/src/flash.c +++ b/src/flash.c @@ -37,7 +37,7 @@ static struct lfs_config *lfs_cfg; static lfs_t lfs; static lfs_file_t lfs_file; -void lfs_setup() +void lfs_setup(bool multicore) { int err; @@ -49,17 +49,32 @@ void lfs_setup() /* Check if we need to initialize/format filesystem... */ err = lfs_mount(&lfs, lfs_cfg); if (err != LFS_ERR_OK) { - log_msg(LOG_NOTICE, "Trying to initialize a new filesystem..."); - if ((err = lfs_format(&lfs, lfs_cfg)) != LFS_ERR_OK) { - log_msg(LOG_ERR, "Unable to initialize flash filesystem: %d", err); + log_msg(LOG_ERR, "Trying to initialize a new filesystem..."); + if (flash_format(false)) return; - } - log_msg(LOG_NOTICE, "Filesystem successfully initialized: %d", err); + log_msg(LOG_ERR, "Filesystem successfully initialized."); } else { lfs_unmount(&lfs); } } +int flash_format(bool multicore) +{ + struct pico_lfs_context *ctx = (struct pico_lfs_context*)lfs_cfg; + int err; + bool saved; + + saved = ctx->multicore_lockout_enabled; + ctx->multicore_lockout_enabled = (multicore ? true : false); + + if ((err = lfs_format(&lfs, lfs_cfg)) != LFS_ERR_OK) { + log_msg(LOG_ERR, "Unable to format flash filesystem: %d", err); + } + + ctx->multicore_lockout_enabled = saved; + + return (err == LFS_ERR_OK ? 0 : 1); +} int flash_read_file(char **bufptr, uint32_t *sizeptr, const char *filename) {