Improve savedata module

This commit is contained in:
whowechina
2026-04-12 11:58:01 +08:00
parent c7b1982e06
commit bed3d689fa
8 changed files with 121 additions and 91 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ set(LWIP_ROOT ${PICO_SDK_PATH}/lib/lwip)
function(make_firmware board board_def)
pico_sdk_init()
add_executable(${board}
main.c slider.c rgb.c button.c save.c config.c commands.c
main.c slider.c rgb.c button.c savedata.c config.c commands.c
cli.c mpr121.c hebtn.c lzfx.c usb_descriptors.c ps4_feat.c)
target_compile_definitions(${board} PUBLIC ${board_def})
pico_enable_stdio_usb(${board} 1)
+9 -1
View File
@@ -7,8 +7,9 @@
#include "pico/stdio.h"
#include "pico/stdlib.h"
#include "pico/bootrom.h"
#include "pico/unique_id.h"
#include "cli.h"
#include "save.h"
#define MAX_COMMANDS 32
#define MAX_PARAMETERS 10
@@ -24,6 +25,13 @@ static int max_cmd_len = 0;
static int num_commands = 0;
uint64_t board_id_64()
{
pico_unique_board_id_t id;
pico_get_unique_board_id(&id);
return *(uint64_t *)(id.id);
}
void cli_register(const char *cmd, cmd_handler_t handler, const char *help)
{
if (num_commands < MAX_COMMANDS) {
+3 -3
View File
@@ -10,7 +10,7 @@
#include "config.h"
#include "slider.h"
#include "hebtn.h"
#include "save.h"
#include "savedata.h"
#include "cli.h"
#include "usb_descriptors.h"
@@ -190,7 +190,7 @@ static void handle_keymap(int argc, char *argv[])
diva_cfg->hid.joy_map = match;
disp_hid();
save_request(true);
savedata_request(true);
printf("Please replug the controller to apply the change.\n");
}
@@ -405,7 +405,7 @@ static void handle_debug(int argc, char *argv[])
static void handle_save()
{
save_request(true);
savedata_request(true);
}
static void handle_factory_reset()
+4 -4
View File
@@ -7,7 +7,7 @@
*/
#include "config.h"
#include "save.h"
#include "savedata.h"
diva_cfg_t *diva_cfg;
@@ -66,16 +66,16 @@ static void config_loaded()
void config_changed()
{
save_request(false);
savedata_request(false);
}
void config_factory_reset()
{
*diva_cfg = default_cfg;
save_request(true);
savedata_request(true);
}
void config_init()
{
diva_cfg = (diva_cfg_t *)save_alloc(sizeof(*diva_cfg), &default_cfg, config_loaded);
diva_cfg = (diva_cfg_t *)savedata_alloc(sizeof(*diva_cfg), &default_cfg, config_loaded);
}
+12 -10
View File
@@ -24,7 +24,7 @@
#include "board_defs.h"
#include "save.h"
#include "savedata.h"
#include "config.h"
#include "cli.h"
#include "commands.h"
@@ -196,15 +196,18 @@ static void run_lights()
}
}
static mutex_t core1_io_lock;
static void core1_init()
{
flash_safe_execute_core_init();
}
static void core1_loop()
{
core1_init();
while (1) {
if (mutex_try_enter(&core1_io_lock, NULL)) {
run_lights();
rgb_update();
mutex_exit(&core1_io_lock);
}
run_lights();
rgb_update();
cli_fps_count(1);
sleep_us(700);
}
@@ -219,7 +222,7 @@ static void core0_loop()
cli_run();
save_loop();
savedata_loop();
cli_fps_count(0);
button_update();
@@ -291,8 +294,7 @@ void init()
update_check();
config_init();
mutex_init(&core1_io_lock);
save_init(0xca44cafe, &core1_io_lock);
savedata_init(0xca44cafe);
slider_init();
rgb_init();
-27
View File
@@ -1,27 +0,0 @@
/*
* Controller Flash Save and Load
* WHowe <github.com/whowechina>
*/
#ifndef SAVE_H
#define SAVE_H
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "pico/multicore.h"
uint32_t board_id_32();
uint64_t board_id_64();
/* It's safer to lock other I/O ops during saving, so we need a locker */
typedef void (*io_locker_func)(bool pause);
void save_init(uint32_t magic, mutex_t *lock);
void save_loop();
void *save_alloc(size_t size, void *def, void (*after_load)());
void save_request(bool immediately);
#endif
+66 -45
View File
@@ -5,21 +5,20 @@
* Config is stored in last sector of flash
*/
#include "save.h"
#include "savedata.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <memory.h>
#include "bsp/board.h"
#include "pico/bootrom.h"
#include "pico/stdio.h"
#include "hardware/flash.h"
#include "pico/multicore.h"
#include "pico/unique_id.h"
static struct {
size_t size;
@@ -33,6 +32,9 @@ static uint32_t my_magic = 0xcafecafe;
#define SAVE_TIMEOUT_US 5000000
#define SAVE_SECTOR_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE)
#define GLOBAL_SECTOR_NUM 2
#define GLOBAL_SECTOR_SIZE (GLOBAL_SECTOR_NUM * FLASH_SECTOR_SIZE)
#define GLOBAL_SECTOR_OFFSET (SAVE_SECTOR_OFFSET - GLOBAL_SECTOR_SIZE)
typedef struct __attribute ((packed)) {
uint32_t magic;
@@ -47,26 +49,25 @@ static int data_page = -1;
static bool requesting_save = false;
static uint64_t requesting_time = 0;
static mutex_t *io_lock;
static void save_program()
static void do_write(void *param)
{
old_data = new_data;
data_page = (data_page + 1) % (FLASH_SECTOR_SIZE / FLASH_PAGE_SIZE);
printf("\nProgram Flash %d %8lx\n", data_page, old_data.magic);
if (mutex_enter_timeout_us(io_lock, 100000)) {
sleep_ms(10); /* wait for all io operations to finish */
uint32_t ints = save_and_disable_interrupts();
if (data_page == 0) {
flash_range_erase(SAVE_SECTOR_OFFSET, FLASH_SECTOR_SIZE);
}
flash_range_program(SAVE_SECTOR_OFFSET + data_page * FLASH_PAGE_SIZE,
(uint8_t *)&old_data, FLASH_PAGE_SIZE);
restore_interrupts(ints);
mutex_exit(io_lock);
}
static void save_program()
{
old_data = new_data;
data_page = (data_page + 1) % (FLASH_SECTOR_SIZE / FLASH_PAGE_SIZE);
printf("\nProgram Save %d %8lx ", data_page, old_data.magic);
if (flash_safe_execute(do_write, NULL, 1000) != PICO_OK) {
printf("Failed!\n");
} else {
printf("Program Flash Failed.\n");
printf("Done.\n");
}
}
@@ -94,7 +95,7 @@ static void save_load()
if (data_page < 0) {
load_default();
save_request(false);
savedata_request(false);
return;
}
@@ -110,37 +111,15 @@ static void save_loaded()
}
}
static union __attribute__((packed)) {
pico_unique_board_id_t id;
struct {
uint32_t id32h;
uint32_t id32l;
};
uint64_t id64;
} board_id;
uint32_t board_id_32()
{
pico_get_unique_board_id(&board_id.id);
return board_id.id32h ^ board_id.id32l;
}
uint64_t board_id_64()
{
pico_get_unique_board_id(&board_id.id);
return board_id.id64;
}
void save_init(uint32_t magic, mutex_t *locker)
void savedata_init(uint32_t magic)
{
my_magic = magic;
io_lock = locker;
save_load();
save_loop();
savedata_loop();
save_loaded();
}
void save_loop()
void savedata_loop()
{
if (requesting_save && (time_us_64() - requesting_time > SAVE_TIMEOUT_US)) {
requesting_save = false;
@@ -152,10 +131,16 @@ void save_loop()
}
}
void *save_alloc(size_t size, void *def, void (*after_load)())
void *savedata_alloc(size_t size, void *def, void (*after_load)())
{
size_t offset = 0;
if (module_num > 0) {
offset = modules[module_num - 1].offset + modules[module_num - 1].size;
}
if (offset + size > sizeof(default_data.data)) {
return NULL;
}
modules[module_num].size = size;
size_t offset = module_num > 0 ? modules[module_num - 1].offset + size : 0;
modules[module_num].offset = offset;
modules[module_num].after_load = after_load;
module_num++;
@@ -163,7 +148,7 @@ void *save_alloc(size_t size, void *def, void (*after_load)())
return new_data.data + offset;
}
void save_request(bool immediately)
void savedata_request(bool immediately)
{
if (!requesting_save) {
printf("Save requested.\n");
@@ -173,6 +158,42 @@ void save_request(bool immediately)
}
if (immediately) {
requesting_time = 0;
save_loop();
savedata_loop();
}
}
void savedata_read_global(size_t offset, void *data, size_t size)
{
if ((data == NULL) || (size == 0) || (offset >= GLOBAL_SECTOR_SIZE)) {
return;
}
if (size > GLOBAL_SECTOR_SIZE - offset) {
size = GLOBAL_SECTOR_SIZE - offset;
}
memcpy(data, (void *)(XIP_BASE + GLOBAL_SECTOR_OFFSET + offset), size);
}
static void do_write_global(void *param)
{
uintptr_t *p = (uintptr_t *)param;
const uint8_t *data = (const uint8_t *)p[0];
size_t size = (size_t)p[1];
flash_range_erase(GLOBAL_SECTOR_OFFSET, GLOBAL_SECTOR_NUM * FLASH_SECTOR_SIZE);
flash_range_program(GLOBAL_SECTOR_OFFSET, data, size);
}
void savedata_write_global(const void *data, size_t size)
{
static uintptr_t param[2];
param[0] = (uintptr_t)data;
param[1] = size;
printf("Program Global %8x ", GLOBAL_SECTOR_OFFSET);
if (flash_safe_execute(do_write_global, param, 1000) != PICO_OK) {
printf("Failed!\n");
} else {
printf("Done.\n");
}
}
+26
View File
@@ -0,0 +1,26 @@
/*
* Controller Flash Save and Load
* WHowe <github.com/whowechina>
*/
#ifndef SAVEDATA_H
#define SAVEDATA_H
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "pico/multicore.h"
/* It's safer to lock other I/O ops during saving, so we need a locker */
void savedata_init(uint32_t magic);
void savedata_loop();
void *savedata_alloc(size_t size, void *def, void (*after_load)());
void savedata_request(bool immediately);
void savedata_read_global(size_t offset, void *data, size_t size);
void savedata_write_global(const void *data, size_t size);
#endif