From f73a4660b2f6a9562d1daae51372537e75cc82bb Mon Sep 17 00:00:00 2001 From: Timo Kokkonen Date: Wed, 13 Mar 2024 22:13:04 -0700 Subject: [PATCH] Fix possible hang when initializing LFS. (#15) * Add new command SYS:LFS:FORMAT * Fix possible hang if LFS needed to be initialized during boot. --- CMakeLists.txt | 5 ++++- commands.md | 32 ++++++++++++++++++++++---------- libs/pico-lfs | 2 +- src/brickpico.c | 2 +- src/brickpico.h | 3 ++- src/command.c | 23 ++++++++++++++++++++--- src/flash.c | 31 ++++++++++++++++++++++++------- 7 files changed, 74 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 269cdf3..b59083a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake) project(brickpico - VERSION 1.2.0 + VERSION 1.2.1 LANGUAGES C CXX ASM ) set(CMAKE_C_STANDARD 11) @@ -153,7 +153,10 @@ if (PICO_CYW43_SUPPORTED) # set by PICO_BOARD=pico_w endif() endif() + target_compile_options(brickpico PRIVATE -Wall) +target_compile_options(brickpico PRIVATE -fmacro-prefix-map=${CMAKE_SOURCE_DIR}/=) + target_compile_definitions(brickpico PRIVATE USBD_MANUFACTURER="TJKO Industries") target_compile_definitions(brickpico PRIVATE USBD_PRODUCT="BrickPico-${BRICKPICO_BOARD} LED Controller") target_compile_definitions(brickpico PRIVATE USBD_DESC_STR_MAX=32) diff --git a/commands.md b/commands.md index 034bda2..7fd5a39 100644 --- a/commands.md +++ b/commands.md @@ -54,6 +54,7 @@ BrickPico supports following commands: * [SYStem:LED](#systemled) * [SYStem:LED?](#systemled-1) * [SYStem:LFS?](#systemlfs) +* [SYStem:LFS:FORMAT](#systemlfsformat) * [SYStem:MEM](#systemmem) * [SYStem:MEM?](#systemmem-1) * [SYStem:MQTT:SERVer](#systemmqttserver) @@ -808,11 +809,22 @@ 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: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 @@ -829,7 +841,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()_ doesn't "see" all of the available heap memory, unless ```SYS:MEM``` command has been run first. Example: @@ -853,7 +865,7 @@ Topmost releasable block (keepcost): 114808 ### SYStem:MQTT Commands -BrickPico has MQTT Client that can be confiugred to publish (send) periodic status +BrickPico 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. @@ -1128,7 +1140,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: ``` @@ -1202,7 +1214,7 @@ myusername/feeds/brickpico_temp #### SYStem:MQTT:TOPIC:PWM Configure topic to publish output port PWM status to. -This is a template string where ```%d``` shoule be used to mark the output port number. +This is a template string where ```%d``` should be used to mark the output port number. Default: @@ -1498,7 +1510,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. @@ -1528,7 +1540,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. @@ -1681,7 +1693,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 firwmare 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). @@ -1702,7 +1714,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/brickpico.c b/src/brickpico.c index 15971dd..e1fb7fe 100644 --- a/src/brickpico.c +++ b/src/brickpico.c @@ -135,7 +135,7 @@ void setup() sleep_ms(50); } - lfs_setup(); + lfs_setup(false); read_config(); #if TTL_SERIAL > 0 diff --git a/src/brickpico.h b/src/brickpico.h index ca9cc6d..2251d8a 100644 --- a/src/brickpico.h +++ b/src/brickpico.h @@ -206,7 +206,8 @@ void oled_display_status(const struct brickpico_state *state, const struct brick 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/command.c b/src/command.c index db5f69e..bc03860 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 "brickpico.h" #ifdef WIFI_SUPPORT @@ -1220,7 +1219,7 @@ int cmd_name(const char *cmd, const char *args, int query, char *prev_cmd) conf->name, sizeof(conf->name), "System Name", NULL); } -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; @@ -1239,6 +1238,19 @@ 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) { if (!query) @@ -1414,6 +1426,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 }, @@ -1505,7 +1522,7 @@ const struct cmd_t system_commands[] = { { "FLASH", 5, NULL, cmd_flash }, { "OUTputs", 3, NULL, cmd_outputs }, { "LED", 3, NULL, cmd_led }, - { "LFS", 3, NULL, cmd_littlefs }, + { "LFS", 3, lfs_commands, cmd_lfs }, { "LOG", 3, NULL, cmd_log_level }, { "MEMLOG", 6, NULL, cmd_mem_log }, { "MEMory", 3, NULL, cmd_memory }, diff --git a/src/flash.c b/src/flash.c index c0f8810..7a0f522 100644 --- a/src/flash.c +++ b/src/flash.c @@ -1,5 +1,5 @@ /* flash.c - Copyright (C) 2023 Timo Kokkonen + Copyright (C) 2023-2024 Timo Kokkonen SPDX-License-Identifier: GPL-3.0-or-later @@ -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; @@ -48,18 +48,35 @@ 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(multicore)) return; - } - log_msg(LOG_NOTICE, "Filesystem successfully initialized: %d", err); + log_msg(LOG_ERR, "Filesystem successfully initialized: %d", err); } 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) { int res;