commit c76f1725b324afe97521f01477c5289f91bcb164
parent 85050a73c523acaad3d18886c4e6cc3d32ffba3c
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date: Mon, 30 Mar 2026 20:57:32 -0300
Optimizar la escritura de parámetros en FLASH
Esto se obtiene escribiendo los parámetros en direcciones separadas en
la misma pagina, evitando tener que borrar toda la pagina cada vez que
se quiere actualizar. Y solo borrando una vez que la pagina se llena, lo
cual es cada 512 actualizaciones (se guardan 2 bytes en una pagina de
1024 bytes).
Diffstat:
1 file changed, 70 insertions(+), 27 deletions(-)
diff --git a/firmware/app/src/task_system.c b/firmware/app/src/task_system.c
@@ -18,13 +18,14 @@
#include "task_menu_attribute.h"
#include "task_menu_interface.h"
-#define G_TASK_SYS_CNT_INI 0ul
-#define G_TASK_SYS_TICK_CNT_INI 0ul
+#define G_TASK_SYS_CNT_INI 0ul
+#define G_TASK_SYS_TICK_CNT_INI 0ul
#define G_TASK_SYS_EEPROM_START_ADDR 0x0801FC00
+#define G_TASK_SYS_EEPROM_END_ADDR 0x0801FFF0
-#define DEL_SYS_MIN 0ul
-#define DEL_SYS_MED 50ul
-#define DEL_SYS_MAX 500ul
+#define DEL_SYS_MIN 0ul
+#define DEL_SYS_MED 50ul
+#define DEL_SYS_MAX 500ul
task_system_dta_t task_system_dta = {
DEL_SYS_MIN, ST_SYS_IDLE, EV_SYS_IDLE, false
@@ -34,7 +35,7 @@ task_system_dta_t task_system_dta = {
// Exported variables
volatile uint32_t g_task_system_tick;
-volatile uint32_t g_task_system_tick_cnt; // Updated every ms by SysTick Callback
+volatile uint32_t g_task_system_tick_cnt; // Updated every ms by SysTick callback
// Private function declaration
void task_system_statechart(void *parameters);
@@ -43,6 +44,7 @@ void task_system_rtc_increment_hour(void);
void task_system_rtc_increment_min(void);
void task_system_eeprom_read_param(void *parameters);
void task_system_eeprom_write_param(void *parameters);
+uint32_t task_system_eeprom_get_current_addr(void);
// Public function definition
void task_system_init(void *parameters)
@@ -134,50 +136,91 @@ void task_system_rtc_increment_min()
HAL_RTC_SetTime(&hrtc, &s_time, RTC_FORMAT_BIN);
}
+uint32_t task_system_eeprom_get_current_addr(void)
+{
+ uint32_t addr = G_TASK_SYS_EEPROM_START_ADDR;
+
+ while (G_TASK_SYS_EEPROM_END_ADDR > addr)
+ {
+ if (0xFFFF == *(uint16_t*)addr)
+ {
+ // Empty value found
+ return (addr - sizeof(uint16_t));
+ }
+ addr += sizeof(uint16_t);
+ }
+
+ // Page is full
+ return 0;
+}
+
void task_system_eeprom_read_param(void *parameters)
{
shared_data_type *p_shared_data = (shared_data_type *)parameters;
- p_shared_data->temp_set_point = *(uint16_t *)G_TASK_SYS_EEPROM_START_ADDR;
+
+ uint32_t addr = task_system_eeprom_get_current_addr();
+ if (0 == addr)
+ {
+ addr = G_TASK_SYS_EEPROM_END_ADDR;
+ }
+
+ p_shared_data->temp_set_point = *(uint16_t*)addr;
}
// To reduce the wear of flash its better to write the new variables on the same
-// page but on contiguous address, every time the variables are updated, and
-// only erase the flash once the page fills
+// page but on contiguous addresses every time the variables are updated, this
+// also has the benefit that there is no need to erase the full page all the
+// time but only once the page fills which after 512 writes (2 bytes on a page
+// of 1024 bytes).
void task_system_eeprom_write_param(void *parameters)
{
+ uint32_t new_addr, curr_addr;
shared_data_type *p_shared_data = (shared_data_type *)parameters;
- if(p_shared_data->temp_set_point == *(uint16_t *)G_TASK_SYS_EEPROM_START_ADDR)
+ curr_addr = task_system_eeprom_get_current_addr();
+
+ if(p_shared_data->temp_set_point == *(uint16_t *)curr_addr)
{
// No need to update if the value is the same
return;
}
+ uint16_t data[] = {
+ p_shared_data->temp_set_point
+ };
+
HAL_FLASH_Unlock();
- FLASH_EraseInitTypeDef erase = {0};
- uint32_t sector_error;
+ if (0 == curr_addr)
+ {
+ // Memory page is full
+ LOGGER_INFO("Memory page is full. Erasing full page...");
- erase.TypeErase = FLASH_TYPEERASE_PAGES;
- erase.PageAddress = G_TASK_SYS_EEPROM_START_ADDR;
- erase.NbPages = 1; // 1024 bytes
+ FLASH_EraseInitTypeDef erase = {0};
+ uint32_t sector_error;
- if(HAL_FLASHEx_Erase(&erase, §or_error) != HAL_OK)
- {
- HAL_FLASH_Lock();
- LOGGER_ERROR("Could erase flash at address %d",
- G_TASK_SYS_EEPROM_START_ADDR);
- return;
- }
+ erase.TypeErase = FLASH_TYPEERASE_PAGES;
+ erase.PageAddress = G_TASK_SYS_EEPROM_START_ADDR;
+ erase.NbPages = 1; // 1024 bytes
- uint16_t data[] = {
- p_shared_data->temp_set_point
- };
+ if(HAL_FLASHEx_Erase(&erase, §or_error) != HAL_OK)
+ {
+ HAL_FLASH_Lock();
+ LOGGER_ERROR("Could erase flash at address %d",
+ G_TASK_SYS_EEPROM_START_ADDR);
+ return;
+ }
- HAL_FLASH_Program(TYPEPROGRAM_HALFWORD,
- G_TASK_SYS_EEPROM_START_ADDR, *(uint64_t *)data);
+ new_addr = G_TASK_SYS_EEPROM_START_ADDR;
+ }
+ else
+ {
+ new_addr = (curr_addr + sizeof(uint16_t));
+ }
+ HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, new_addr, *(uint16_t *)data);
HAL_FLASH_Lock();
+ return;
}
void task_system_statechart(void *parameters)