From 685e0950bf0c6c187d6562195a8d4f03c28094ef Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Fri, 19 May 2023 16:05:27 +0100 Subject: [PATCH] Create system_utils component Somewhat of a 'misc' component; handles early initialization, checking for first boot and rebooting. --- components/console_wrapper/CMakeLists.txt | 2 +- components/console_wrapper/console.c | 5 +- components/settings/settings.c | 14 ---- components/system_utils/CMakeLists.txt | 5 ++ components/system_utils/system_utils.c | 79 +++++++++++++++++++++++ components/system_utils/system_utils.h | 27 ++++++++ main/CMakeLists.txt | 3 +- main/main.c | 3 + 8 files changed, 120 insertions(+), 18 deletions(-) create mode 100644 components/system_utils/CMakeLists.txt create mode 100644 components/system_utils/system_utils.c create mode 100644 components/system_utils/system_utils.h diff --git a/components/console_wrapper/CMakeLists.txt b/components/console_wrapper/CMakeLists.txt index 7ed1f25..e1d908b 100644 --- a/components/console_wrapper/CMakeLists.txt +++ b/components/console_wrapper/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register( SRCS "console.c" INCLUDE_DIRS "." - REQUIRES console esp_system + REQUIRES console system_utils ) diff --git a/components/console_wrapper/console.c b/components/console_wrapper/console.c index b78c09e..6dd1c68 100644 --- a/components/console_wrapper/console.c +++ b/components/console_wrapper/console.c @@ -5,9 +5,10 @@ #include "console.h" +#include "system_utils.h" + #include "esp_console.h" #include "esp_log.h" -#include "esp_system.h" #define TAG "Console" @@ -17,7 +18,7 @@ static int reboot_command_func(int argc, char **argv) { (void)argc; (void)argv; - (void)esp_restart(); + reboot(); return 0; } diff --git a/components/settings/settings.c b/components/settings/settings.c index 6cb8e2d..3df9087 100644 --- a/components/settings/settings.c +++ b/components/settings/settings.c @@ -201,20 +201,6 @@ static int command_func(int argc, char **argv) void settings_init() { - esp_err_t error; - - error = nvs_flash_init(); - if (error == ESP_ERR_NVS_NO_FREE_PAGES - || error == ESP_ERR_NVS_NEW_VERSION_FOUND) { - ESP_LOGI(TAG, "NVS partition full or outdated; erasing"); - (void)nvs_flash_erase(); - error = nvs_flash_init(); - } - if (error != ESP_OK) { - ESP_LOGE(TAG, "Error initializing NVS store: %04x", error); - FATAL(); - } - for (ItemIndex item = (ItemIndex)0; item < ITEM_COUNT; ++item) { if (!load(item)) { set(item, state[item].default_value); diff --git a/components/system_utils/CMakeLists.txt b/components/system_utils/CMakeLists.txt new file mode 100644 index 0000000..8b16b21 --- /dev/null +++ b/components/system_utils/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRCS "system_utils.c" + INCLUDE_DIRS "." + REQUIRES esp_system fatal nvs_flash time +) diff --git a/components/system_utils/system_utils.c b/components/system_utils/system_utils.c new file mode 100644 index 0000000..3f6612c --- /dev/null +++ b/components/system_utils/system_utils.c @@ -0,0 +1,79 @@ + +/* + * SPDX-License-Identifier: AGPL-3.0-only + * Copyright (c) Camden Dixie O'Brien + */ + +#include "system_utils.h" + +#include "fatal.h" +#include "time_storage.h" + +#include "esp_log.h" +#include "esp_system.h" +#include "nvs_flash.h" + +#define TAG "System utils" + +#define NVS_NAMESPACE "system-utils" +#define BOOTED_FLAG_KEY "booted" + +static bool first_boot; + +static void test_first_boot(void) +{ + esp_err_t error; + nvs_handle_t handle; + error = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &handle); + if (error != ESP_OK) { + ESP_LOGE(TAG, "Error opening NVS store namespace: %02x", error); + first_boot = false; + return; + } + + uint8_t tmp; + error = nvs_get_u8(handle, BOOTED_FLAG_KEY, &tmp); + if (error == ESP_OK) { + first_boot = false; + } else if (error == ESP_ERR_NVS_NOT_FOUND) { + ESP_LOGI(TAG, "First boot of system"); + first_boot = true; + error = nvs_set_u8(handle, BOOTED_FLAG_KEY, 1); + if (error != ESP_OK) + ESP_LOGE(TAG, "Error setting booted flag: %02x", error); + } else { + ESP_LOGE(TAG, "Error getting booted flag: %02x", error); + first_boot = false; + } + + nvs_close(handle); +} + +void early_init() +{ + esp_err_t error = nvs_flash_init(); + if (error == ESP_ERR_NVS_NO_FREE_PAGES + || error == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_LOGI(TAG, "NVS partition full or outdated; erasing"); + (void)nvs_flash_erase(); + error = nvs_flash_init(); + } + if (error != ESP_OK) { + ESP_LOGE(TAG, "Error initializing NVS store: %04x", error); + FATAL(); + } + + test_first_boot(); +} + +bool is_first_boot() +{ + return first_boot; +} + +void reboot() +{ + ESP_LOGI(TAG, "Rebooting system"); + time_storage_save(); + esp_restart(); +} diff --git a/components/system_utils/system_utils.h b/components/system_utils/system_utils.h new file mode 100644 index 0000000..16cbbf4 --- /dev/null +++ b/components/system_utils/system_utils.h @@ -0,0 +1,27 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * Copyright (c) Camden Dixie O'Brien + */ + +#ifndef SYSTEM_UTILS_H +#define SYSTEM_UTILS_H + +#include + +/** + * Perform system initialization that must occur before any other + * components are initialized. + */ +void early_init(void); + +/** + * Return whether or not this is the first boot of the system. + */ +bool is_first_boot(void); + +/** + * Reboot the system, storing the current time beforehand. + */ +void reboot(void); + +#endif diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 2ad0e8b..4402b1c 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,5 +1,6 @@ idf_component_register( SRCS "main.c" INCLUDE_DIRS "." - REQUIRES buttons console_wrapper display settings sound time wifi + REQUIRES + buttons console_wrapper display settings sound system_utils time wifi ) diff --git a/main/main.c b/main/main.c index 893d710..4100ab0 100644 --- a/main/main.c +++ b/main/main.c @@ -9,11 +9,14 @@ #include "display.h" #include "settings.h" #include "sound.h" +#include "system_utils.h" #include "time_manager.h" #include "wifi.h" void app_main(void) { + early_init(); + console_init(); settings_init(); wifi_init();