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(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(BOARD "raspberry_pi_pico" CACHE STRING "Board used, determines the pinout. Defaults to the Raspberry Pi Pico.")
@ -45,10 +46,10 @@ if(FAMILY STREQUAL "rp2040")
# need uart stdio, usb is busy doing other stuff
if(USE_USBCDC_FOR_STDIO)
# we're going to manually implement this case
#pico_enable_stdio_uart(${PROJECT} 0)
target_compile_definitions(${PROJECT} PUBLIC USE_USBCDC_FOR_STDIO=1 PICO_STDIO_USB=1)
#pico_enable_stdio_uart(${PROJECT} 0)
target_compile_definitions(${PROJECT} PUBLIC USE_USBCDC_FOR_STDIO=1)
else()
#pico_enable_stdio_uart(${PROJECT} 1)
#pico_enable_stdio_uart(${PROJECT} 1)
endif()
pico_enable_stdio_uart(${PROJECT} 1)
pico_enable_stdio_usb(${PROJECT} 0)
@ -95,10 +96,14 @@ target_sources(${PROJECT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_sump/sump_hw.c
)
if(USE_USBCDC_FOR_STDIO)
target_compile_definitions(${PROJECT} PUBLIC USE_USBCDC_FOR_STDIO=1)
target_sources(${PROJECT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/cdc_stdio.c
)
endif()
if (PERSISTENT_STORAGE)
target_compile_definitions(${PROJECT} PUBLIC PERSISTENT_STORAGE=1)
endif()
target_include_directories(${PROJECT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/
${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);
thread_enter(vndcfg_thread);
#if defined(PERSISTENT_STORAGE) && defined(DBOARD_HAS_STORAGE)
int startupmode = storage_init();
#else
int startupmode = -1;
#endif
modes_init(startupmode);
if (mode_current) mode_current->enter();

View File

@ -5,6 +5,7 @@
#include "alloc.h"
#include "board.h" /* bsp_reset_bootloader() */
#include "mode.h"
#include "storage.h"
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 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 "storage.h"
#ifndef DBOARD_HAS_STORAGE
int storage_init(void) { return -1; }
void storage_flush_data(void) { }
#if !defined(PERSISTENT_STORAGE) || !defined(DBOARD_HAS_STORAGE)
/*int storage_init(void) { return -1; }
bool storage_flush_data(void) { return false; }
struct mode_info storage_mode_get_size(int _) {
(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
#include "storage_internal.h"
@ -144,7 +146,7 @@ struct mode_info storage_mode_get_info(int mode) {
#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;
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;
}
if (offset >= mdsize) return;
// skip hash check in this case
storage_read(dst, mdoffset, mdsize);
storage_read(dst, mdoffset + offset, mdsize < maxlen ? mdsize : maxlen);
return;
}
}

View File

@ -32,7 +32,7 @@ struct mode_info {
// 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
void storage_mode_read(int mode, void* dst);
void storage_mode_read(int mode, void* dst, size_t offset, size_t maxlen);
// global functions
@ -40,7 +40,10 @@ void storage_mode_read(int mode, void* dst);
int storage_init(void);
// 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

View File

@ -5,11 +5,11 @@
#include "mode.h"
#include "storage.h"
#ifdef DBOARD_HAS_STORAGE
#if defined(PERSISTENT_STORAGE) && defined(DBOARD_HAS_STORAGE)
#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.get_size == 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;
}
void* storage_priv_get_header_ptr(void) {
return &header_tmp;
}
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 (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;
// 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???
}
void storage_flush_data(void) {
bool storage_flush_data(void) {
if (mode_bad != 0 || mode_current_id != header_tmp.curmode) {
storage_write_data();
return true;
} 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()) {
storage_write_data();
return;
return true;
}
}
return false;
}
#endif

View File

@ -18,6 +18,8 @@ static uint32_t rxavail, rxpos, txpos;
static int VND_N_CFG = 0;
extern uint8_t data_tmp[256];
void vnd_cfg_init(void) {
rxavail = 0;
rxpos = 0;
@ -191,6 +193,47 @@ void vnd_cfg_task(void) {
case cfg_cmd_get_infostr:
vnd_cfg_write_str(cfg_resp_ok, INFO_PRODUCT(INFO_BOARDNAME));
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:
vnd_cfg_write_resp(cfg_resp_illcmd, 0, NULL);
break;

View File

@ -30,6 +30,12 @@ enum cfg_cmd {
cfg_cmd_get_cur_mode = 0x02,
cfg_cmd_set_cur_mode = 0x03,
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