PERSISTENT_STORAGE usage flag

This commit is contained in:
Triss 2021-08-26 03:52:06 +02:00
parent befced7132
commit 4015b7bf42
8 changed files with 99 additions and 17 deletions

View File

@ -1,4 +1,5 @@
option(USE_USBCDC_FOR_STDIO "Export an extra USB-CDC interface for stdio, instead of echoing it to a UART port (and requiring UART loopback for receiving stdio output on a host computer)." OFF) option(USE_USBCDC_FOR_STDIO "Export an extra USB-CDC interface for stdio, instead of echoing it to a UART port (and requiring UART loopback for receiving stdio output on a host computer)." OFF)
option(PERSISTENT_STORAGE "Use persistent storage (usually on-chip/on-board flash) to save the current mode, and settings of modes" ON)
set(FAMILY "rp2040" CACHE STRING "Board/MCU family, decides which drivers to use. Set to RP2040 by default.") set(FAMILY "rp2040" CACHE STRING "Board/MCU family, decides which drivers to use. Set to RP2040 by default.")
set(BOARD "raspberry_pi_pico" CACHE STRING "Board used, determines the pinout. Defaults to the Raspberry Pi Pico.") set(BOARD "raspberry_pi_pico" CACHE STRING "Board used, determines the pinout. Defaults to the Raspberry Pi Pico.")
@ -46,7 +47,7 @@ if(FAMILY STREQUAL "rp2040")
if(USE_USBCDC_FOR_STDIO) if(USE_USBCDC_FOR_STDIO)
# we're going to manually implement this case # we're going to manually implement this case
#pico_enable_stdio_uart(${PROJECT} 0) #pico_enable_stdio_uart(${PROJECT} 0)
target_compile_definitions(${PROJECT} PUBLIC USE_USBCDC_FOR_STDIO=1 PICO_STDIO_USB=1) target_compile_definitions(${PROJECT} PUBLIC USE_USBCDC_FOR_STDIO=1)
else() else()
#pico_enable_stdio_uart(${PROJECT} 1) #pico_enable_stdio_uart(${PROJECT} 1)
endif() endif()
@ -95,10 +96,14 @@ target_sources(${PROJECT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_sump/sump_hw.c ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_sump/sump_hw.c
) )
if(USE_USBCDC_FOR_STDIO) if(USE_USBCDC_FOR_STDIO)
target_compile_definitions(${PROJECT} PUBLIC USE_USBCDC_FOR_STDIO=1)
target_sources(${PROJECT} PUBLIC target_sources(${PROJECT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/cdc_stdio.c ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/cdc_stdio.c
) )
endif() endif()
if (PERSISTENT_STORAGE)
target_compile_definitions(${PROJECT} PUBLIC PERSISTENT_STORAGE=1)
endif()
target_include_directories(${PROJECT} PUBLIC target_include_directories(${PROJECT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/ ${CMAKE_CURRENT_SOURCE_DIR}/src/
${CMAKE_CURRENT_SOURCE_DIR}/libco/ ${CMAKE_CURRENT_SOURCE_DIR}/libco/

View File

@ -32,7 +32,11 @@ int main() {
vndcfg_thread = co_derive(vndcfg_stack, sizeof vndcfg_stack, vndcfg_thread_fn); vndcfg_thread = co_derive(vndcfg_stack, sizeof vndcfg_stack, vndcfg_thread_fn);
thread_enter(vndcfg_thread); thread_enter(vndcfg_thread);
#if defined(PERSISTENT_STORAGE) && defined(DBOARD_HAS_STORAGE)
int startupmode = storage_init(); int startupmode = storage_init();
#else
int startupmode = -1;
#endif
modes_init(startupmode); modes_init(startupmode);
if (mode_current) mode_current->enter(); if (mode_current) mode_current->enter();

View File

@ -5,6 +5,7 @@
#include "alloc.h" #include "alloc.h"
#include "board.h" /* bsp_reset_bootloader() */ #include "board.h" /* bsp_reset_bootloader() */
#include "mode.h" #include "mode.h"
#include "storage.h"
extern struct mode m_01_default, m_03_jscan, m_04_sump; extern struct mode m_01_default, m_03_jscan, m_04_sump;
@ -171,3 +172,13 @@ void modes_switch(uint8_t newmode) {
if (mode_current) mode_current->enter(); if (mode_current) mode_current->enter();
} }
#if defined(PERSISTENT_STORAGE) && defined(DBOARD_HAS_STORAGE)
void tud_umount_cb(void) {
storage_flush_data();
}
void tud_suspend_cb(bool remote_wakeup_en) {
(void)remote_wakeup_en;
storage_flush_data();
}
#endif

View File

@ -5,13 +5,15 @@
#include "mode.h" #include "mode.h"
#include "storage.h" #include "storage.h"
#ifndef DBOARD_HAS_STORAGE #if !defined(PERSISTENT_STORAGE) || !defined(DBOARD_HAS_STORAGE)
int storage_init(void) { return -1; } /*int storage_init(void) { return -1; }
void storage_flush_data(void) { } bool storage_flush_data(void) { return false; }
struct mode_info storage_mode_get_size(int _) { struct mode_info storage_mode_get_size(int _) {
(void)_; return (struct mode_info){ .size = 0, .version = 0 }; (void)_; return (struct mode_info){ .size = 0, .version = 0 };
} }
void storage_mode_read(int _, void* __) { (void)_; (void)__; } void storage_mode_read(int _, void* __, size_t ___, size_t ____) {
(void)_; (void)__; (void)___; (void)____;
}*/
#else #else
#include "storage_internal.h" #include "storage_internal.h"
@ -144,7 +146,7 @@ struct mode_info storage_mode_get_info(int mode) {
#undef DEF_RETVAL #undef DEF_RETVAL
} }
void storage_mode_read(int mode, void* dst) { void storage_mode_read(int mode, void* dst, size_t offset, size_t maxlen) {
if (mode >= 16 || !header_valid || mode <= 0) return; if (mode >= 16 || !header_valid || mode <= 0) return;
for (size_t i = 0; i < header_tmp.nmodes; ++i) { for (size_t i = 0; i < header_tmp.nmodes; ++i) {
@ -175,8 +177,10 @@ void storage_mode_read(int mode, void* dst) {
mode_bad |= 1<<mode; return; mode_bad |= 1<<mode; return;
} }
if (offset >= mdsize) return;
// skip hash check in this case // skip hash check in this case
storage_read(dst, mdoffset, mdsize); storage_read(dst, mdoffset + offset, mdsize < maxlen ? mdsize : maxlen);
return; return;
} }
} }

View File

@ -32,7 +32,7 @@ struct mode_info {
// functions mode-specific code can use to retrieve the save data // functions mode-specific code can use to retrieve the save data
struct mode_info storage_mode_get_info(int mode); // returns size=0 for none found struct mode_info storage_mode_get_info(int mode); // returns size=0 for none found
void storage_mode_read(int mode, void* dst); void storage_mode_read(int mode, void* dst, size_t offset, size_t maxlen);
// global functions // global functions
@ -40,7 +40,10 @@ void storage_mode_read(int mode, void* dst);
int storage_init(void); int storage_init(void);
// flush edits if anything has been edited // flush edits if anything has been edited
void storage_flush_data(void); bool storage_flush_data(void);
bool storage_priv_mode_has(int mode);
void* storage_priv_get_header_ptr(void);
#endif #endif

View File

@ -5,11 +5,11 @@
#include "mode.h" #include "mode.h"
#include "storage.h" #include "storage.h"
#ifdef DBOARD_HAS_STORAGE #if defined(PERSISTENT_STORAGE) && defined(DBOARD_HAS_STORAGE)
#include "storage_internal.h" #include "storage_internal.h"
static bool storage_mode_has(int i) { bool storage_priv_mode_has(int i) {
if (mode_list[i]->storage.stclass == mode_storage_none) return false; if (mode_list[i]->storage.stclass == mode_storage_none) return false;
if (mode_list[i]->storage.get_size == NULL) return false; if (mode_list[i]->storage.get_size == NULL) return false;
if (mode_list[i]->storage.get_data == NULL) return false; if (mode_list[i]->storage.get_data == NULL) return false;
@ -17,6 +17,9 @@ static bool storage_mode_has(int i) {
return true; return true;
} }
void* storage_priv_get_header_ptr(void) {
return &header_tmp;
}
static struct mode_storage msto[16]; static struct mode_storage msto[16];
@ -38,7 +41,7 @@ static size_t storage_allocate_new(void) {
for (enum mode_storage_class stcls = mode_storage_32b; stcls <= mode_storage_big; ++stcls) { for (enum mode_storage_class stcls = mode_storage_32b; stcls <= mode_storage_big; ++stcls) {
for (int mode = 1; mode < 16; ++mode) { for (int mode = 1; mode < 16; ++mode) {
if (mode_list[mode] == NULL || !storage_mode_has(mode)) continue; if (mode_list[mode] == NULL || !storage_priv_mode_has(mode)) continue;
if (mode_list[mode]->storage.stclass != stcls) continue; if (mode_list[mode]->storage.stclass != stcls) continue;
// too big for the class? don't write the data, then // too big for the class? don't write the data, then
@ -150,17 +153,20 @@ static void STORAGE_RAM_FUNC(storage_write_data)(void) {
// * try to save when unplugging??? // * try to save when unplugging???
} }
void storage_flush_data(void) { bool storage_flush_data(void) {
if (mode_bad != 0 || mode_current_id != header_tmp.curmode) { if (mode_bad != 0 || mode_current_id != header_tmp.curmode) {
storage_write_data(); storage_write_data();
return true;
} else for (int i = 1; i < 16; ++i) { } else for (int i = 1; i < 16; ++i) {
if (mode_list[i] == NULL || !storage_mode_has(i)) continue; if (mode_list[i] == NULL || !storage_priv_mode_has(i)) continue;
if (mode_list[i]->storage.is_dirty()) { if (mode_list[i]->storage.is_dirty()) {
storage_write_data(); storage_write_data();
return; return true;
} }
} }
return false;
} }
#endif #endif

View File

@ -18,6 +18,8 @@ static uint32_t rxavail, rxpos, txpos;
static int VND_N_CFG = 0; static int VND_N_CFG = 0;
extern uint8_t data_tmp[256];
void vnd_cfg_init(void) { void vnd_cfg_init(void) {
rxavail = 0; rxavail = 0;
rxpos = 0; rxpos = 0;
@ -191,6 +193,47 @@ void vnd_cfg_task(void) {
case cfg_cmd_get_infostr: case cfg_cmd_get_infostr:
vnd_cfg_write_str(cfg_resp_ok, INFO_PRODUCT(INFO_BOARDNAME)); vnd_cfg_write_str(cfg_resp_ok, INFO_PRODUCT(INFO_BOARDNAME));
break; break;
#if defined(PERSISTENT_STORAGE) && defined(DBOARD_HAS_STORAGE)
case cfg_cmd_storage_get_header:
vnd_cfg_write_resp(cfg_resp_ok, 256, storage_priv_get_header_ptr());
break;
case cfg_cmd_storage_get_modedata:
verbuf[0] = vnd_cfg_read_byte();
if (verbuf[0] == 0 || verbuf[0] >= 16 || mode_list[verbuf[0]] == NULL) {
vnd_cfg_write_resp(cfg_resp_nosuchmode, 0, NULL);
} else if (!storage_priv_mode_has(verbuf[0])) {
vnd_cfg_write_resp(cfg_resp_badarg, 0, NULL);
} else {
uint32_t len = storage_mode_get_info(verbuf[0]).size;
vnd_cfg_write_byte(cfg_resp_ok);
if (len < (1<<7)) {
vnd_cfg_write_byte(len);
} else if (len < (1<<14)) {
vnd_cfg_write_byte((len & 0x7f) | 0x80);
vnd_cfg_write_byte((len >> 7) & 0x7f);
} else {
vnd_cfg_write_byte((len & 0x7f) | 0x80);
vnd_cfg_write_byte(((len >> 7) & 0x7f) | 0x80);
vnd_cfg_write_byte(((len >> 14) & 0x7f));
}
for (size_t i = 0; i < len; i += sizeof data_tmp) {
size_t tosend = sizeof data_tmp;
if (tosend > len - i) tosend = len - i;
storage_mode_read(verbuf[0], data_tmp, i, tosend);
for (size_t ii = 0; ii < tosend; ++ii)
vnd_cfg_write_byte(data_tmp[ii]);
}
vnd_cfg_write_flush();
}
break;
case cfg_cmd_storage_flush_data:
verbuf[0] = storage_flush_data() ? 1 : 0;
vnd_cfg_write_resp(cfg_resp_ok, 1, verbuf);
break;
#endif
default: default:
vnd_cfg_write_resp(cfg_resp_illcmd, 0, NULL); vnd_cfg_write_resp(cfg_resp_illcmd, 0, NULL);
break; break;

View File

@ -30,6 +30,12 @@ enum cfg_cmd {
cfg_cmd_get_cur_mode = 0x02, cfg_cmd_get_cur_mode = 0x02,
cfg_cmd_set_cur_mode = 0x03, cfg_cmd_set_cur_mode = 0x03,
cfg_cmd_get_infostr = 0x04, cfg_cmd_get_infostr = 0x04,
#if defined(PERSISTENT_STORAGE) && defined(DBOARD_HAS_STORAGE)
cfg_cmd_storage_get_header = 0x0c,
cfg_cmd_storage_get_modedata = 0x0d,
cfg_cmd_storage_flush_data = 0x0e,
#endif
}; };
// common commands for every mode // common commands for every mode