Split system settings to separate config file
This commit is contained in:
+3
-3
@@ -66,7 +66,7 @@ static void settings_bulkread_cb(BulkRead *bulk, uint32_t chunk, uint8_t *buffer
|
||||
}
|
||||
|
||||
IniWriter iw = iw_init((char *)buffer, bulk->offset, chunk);
|
||||
settings_build_ini(&iw);
|
||||
settings_build_units_ini(&iw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +80,7 @@ static TF_Result lst_ini_export(TinyFrame *tf, TF_Msg *msg)
|
||||
assert_param(bulk);
|
||||
|
||||
bulk->frame_id = msg->frame_id;
|
||||
bulk->len = settings_get_ini_len();
|
||||
bulk->len = settings_get_units_ini_len();
|
||||
bulk->read = settings_bulkread_cb;
|
||||
bulk->userdata = NULL;
|
||||
|
||||
@@ -124,7 +124,7 @@ static TF_Result lst_ini_import(TinyFrame *tf, TF_Msg *msg)
|
||||
assert_param(bulk);
|
||||
|
||||
bulk->frame_id = msg->frame_id;
|
||||
bulk->len = settings_get_ini_len();
|
||||
bulk->len = settings_get_units_ini_len();
|
||||
bulk->write = settings_bulkwrite_cb;
|
||||
|
||||
settings_load_ini_begin();
|
||||
|
||||
+55
-24
@@ -209,33 +209,63 @@ static void savebuf_flush(PayloadBuilder *pb, bool final)
|
||||
fls_printf("\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write system settings to INI (without section)
|
||||
*/
|
||||
void settings_build_ini(IniWriter *iw)
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
static void ini_preamble(IniWriter *iw, const char *filename)
|
||||
{
|
||||
// File header
|
||||
iw_hdr_comment(iw, "CONFIG.INI");
|
||||
iw_hdr_comment(iw, filename);
|
||||
iw_hdr_comment(iw, "GEX v%s on %s", GEX_VERSION, GEX_PLATFORM);
|
||||
iw_hdr_comment(iw, "built %s at %s", __DATE__, __TIME__);
|
||||
iw_cmt_newline(iw);
|
||||
|
||||
iw_comment(iw, "Overwrite this file to change settings.");
|
||||
iw_comment(iw, "Close the LOCK jumper to save them to Flash.");
|
||||
}
|
||||
|
||||
systemsettings_build_ini(iw);
|
||||
/**
|
||||
* Write system settings to INI (without section)
|
||||
*/
|
||||
void settings_build_units_ini(IniWriter *iw)
|
||||
{
|
||||
ini_preamble(iw, "UNITS.INI");
|
||||
|
||||
ureg_build_ini(iw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write system settings to INI (without section)
|
||||
*/
|
||||
void settings_build_system_ini(IniWriter *iw)
|
||||
{
|
||||
ini_preamble(iw, "SYSTEM.INI");
|
||||
|
||||
systemsettings_build_ini(iw);
|
||||
}
|
||||
|
||||
uint32_t settings_get_units_ini_len(void)
|
||||
{
|
||||
// this writer is configured to skip everything, so each written byte will decrement the skip count
|
||||
IniWriter iw = iw_init(NULL, 0xFFFFFFFF, 1); // count is never used, we use 1 because 0 means we're full
|
||||
settings_build_units_ini(&iw);
|
||||
// now we just check how many bytes were skipped
|
||||
return 0xFFFFFFFF - iw.skip;
|
||||
}
|
||||
|
||||
uint32_t settings_get_system_ini_len(void)
|
||||
{
|
||||
// same as above
|
||||
IniWriter iw = iw_init(NULL, 0xFFFFFFFF, 1);
|
||||
settings_build_system_ini(&iw);
|
||||
return 0xFFFFFFFF - iw.skip;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
void settings_load_ini_begin(void)
|
||||
{
|
||||
SystemSettings.modified = true;
|
||||
|
||||
// load defaults
|
||||
systemsettings_loadDefaults();
|
||||
ureg_remove_all_units();
|
||||
SystemSettings.pristine = true;
|
||||
}
|
||||
|
||||
void settings_load_ini_key(const char *restrict section, const char *restrict key, const char *restrict value)
|
||||
@@ -244,25 +274,35 @@ void settings_load_ini_key(const char *restrict section, const char *restrict ke
|
||||
static char namebuf[INI_KEY_MAX];
|
||||
|
||||
if (streq(section, "SYSTEM")) {
|
||||
|
||||
if (SystemSettings.pristine) {
|
||||
SystemSettings.pristine = false;
|
||||
systemsettings_loadDefaults();
|
||||
}
|
||||
|
||||
// system is always at the top
|
||||
systemsettings_load_ini(key, value);
|
||||
}
|
||||
else if (streq(section, "UNITS")) {
|
||||
|
||||
if (SystemSettings.pristine) {
|
||||
SystemSettings.pristine = false;
|
||||
ureg_remove_all_units();
|
||||
}
|
||||
|
||||
// this will always come before individual units config
|
||||
// install or tear down units as described by the config
|
||||
ureg_instantiate_by_ini(key, value);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// not a standard section, may be some unit config
|
||||
// all unit sections contain the colon character [TYPE:NAME]
|
||||
// all unit sections contain the colon character [TYPE:NAME@CALLSIGN]
|
||||
const char *nameptr = strchr(section, ':');
|
||||
const char *csptr = strchr(section, '@');
|
||||
|
||||
dbg("cs = %s", csptr);
|
||||
if (nameptr && csptr) {
|
||||
strncpy(namebuf, nameptr+1, csptr - nameptr - 1);
|
||||
uint8_t cs = (uint8_t) avr_atoi(csptr + 1);
|
||||
dbg("cs is %d", cs);
|
||||
dbg("name is %s", namebuf);
|
||||
ureg_load_unit_ini_key(namebuf, key, value, cs);
|
||||
} else {
|
||||
dbg("! Bad config key: [%s] %s = %s", section, key, value);
|
||||
@@ -276,12 +316,3 @@ void settings_load_ini_end(void)
|
||||
dbg("Some units failed to init!!");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t settings_get_ini_len(void)
|
||||
{
|
||||
// this writer is configured to skip everything, so each written byte will decrement the skip count
|
||||
IniWriter iw = iw_init(NULL, 0xFFFFFFFF, 1);
|
||||
settings_build_ini(&iw);
|
||||
// now we just check how many bytes were skipped
|
||||
return 0xFFFFFFFF - iw.skip;
|
||||
}
|
||||
|
||||
+17
-4
@@ -51,16 +51,29 @@ void settings_load_ini_key(const char *restrict section, const char *restrict ke
|
||||
void settings_load_ini_end(void);
|
||||
|
||||
/**
|
||||
* Write all settings to a iniwriter
|
||||
* Write UNITS.INI to a iniwriter
|
||||
* @param iw - writer handle
|
||||
*/
|
||||
void settings_build_ini(IniWriter *iw);
|
||||
void settings_build_units_ini(IniWriter *iw);
|
||||
|
||||
/**
|
||||
* Get total settings len (caution: this is expensive, works by dummy-printing everything)
|
||||
* Get UNITS.INI len (expensive, uses dummy read)
|
||||
*
|
||||
* @return bytes
|
||||
*/
|
||||
uint32_t settings_get_ini_len(void);
|
||||
uint32_t settings_get_units_ini_len(void);
|
||||
|
||||
/**
|
||||
* Write SYSTEM.INI to iniwriter
|
||||
* @param iw - writer handle
|
||||
*/
|
||||
void settings_build_system_ini(IniWriter *iw);
|
||||
|
||||
/**
|
||||
* Get SYSTEM.INI len (expensive, uses dummy read)
|
||||
*
|
||||
* @return bytes
|
||||
*/
|
||||
uint32_t settings_get_system_ini_len(void);
|
||||
|
||||
#endif //GEX_SETTINGS_H
|
||||
|
||||
@@ -17,6 +17,7 @@ struct system_settings {
|
||||
// Support flags put here for scoping, but not atcually part of the persistent settings
|
||||
volatile bool editable; //!< True if we booted with the LOCK jumper removed
|
||||
volatile bool modified; //!< True if user did any change to the settings (checked when the LOCK jumper is replaced)
|
||||
volatile bool pristine; //!< Marks unknown state before we reach first section marker that determines what file it is
|
||||
};
|
||||
|
||||
extern struct system_settings SystemSettings;
|
||||
|
||||
@@ -477,6 +477,8 @@ void ureg_build_ini(IniWriter *iw)
|
||||
count++;
|
||||
}
|
||||
li = li->next;
|
||||
|
||||
if (iw->count == 0) return; // avoid printing discarded tail
|
||||
}
|
||||
re = re->next;
|
||||
iw_newline(iw);
|
||||
@@ -487,6 +489,8 @@ void ureg_build_ini(IniWriter *iw)
|
||||
while (li != NULL) {
|
||||
export_unit_do(li, iw);
|
||||
li = li->next;
|
||||
|
||||
if (iw->count == 0) return; // avoid printing discarded tail
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef GEX_PLAT_COMPAT_H
|
||||
#define GEX_PLAT_COMPAT_H
|
||||
|
||||
#define VFS_DRIVE_NAME "GEX"
|
||||
|
||||
// -------- Static buffers ---------
|
||||
#define TSK_STACK_MAIN 220 // USB / VFS task stack size
|
||||
#define TSK_STACK_MSG 200 // TF message handler task stack size
|
||||
|
||||
+2
-2
@@ -193,8 +193,8 @@ static bool detect_conf(const uint8_t *data, uint32_t size)
|
||||
// and may not be known for a while - we cannot use that to detect anything, unless we buffer the entire file
|
||||
// (a bad idea)
|
||||
|
||||
// TODO detect config file
|
||||
return data[0] == '#'; // here we just assume everything is INI
|
||||
// Our INI files always start with two hashes
|
||||
return size >= 2 && data[0] == '#' && data[1] == '#';
|
||||
}
|
||||
|
||||
static void iniparser_cb(const char *section, const char *key, const char *value, void *userData)
|
||||
|
||||
+17
-15
@@ -25,32 +25,34 @@
|
||||
#include "vfs_manager.h"
|
||||
#include "str_utils.h"
|
||||
|
||||
const vfs_filename_t daplink_drive_name = "VIRTUALFS";
|
||||
const vfs_filename_t daplink_drive_name = VFS_DRIVE_NAME;
|
||||
|
||||
// File callback to be used with vfs_add_file to return file contents
|
||||
static uint32_t read_file_config_ini(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors)
|
||||
static uint32_t read_file_units_ini(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors)
|
||||
{
|
||||
vfs_printf("Read config.ini");
|
||||
vfs_printf("Read UNITS.INI");
|
||||
|
||||
const uint32_t avail = num_sectors*VFS_SECTOR_SIZE;
|
||||
const uint32_t skip = sector_offset*VFS_SECTOR_SIZE;
|
||||
|
||||
IniWriter iw = iw_init((char *)data, skip, avail);
|
||||
settings_build_ini(&iw);
|
||||
settings_build_units_ini(&iw);
|
||||
|
||||
return avail - iw.count;
|
||||
}
|
||||
|
||||
static uint32_t read_file_system_ini(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors)
|
||||
{
|
||||
vfs_printf("Read SYSTEM.INI");
|
||||
|
||||
////
|
||||
//static void write_file_config_ini(uint32_t sector_offset, const uint8_t *data, uint32_t num_sectors)
|
||||
//{
|
||||
// vfs_printf("Write CONFIG.INI, so %d, ns %d", sector_offset, num_sectors);
|
||||
//
|
||||
// for(uint32_t i=0;i<num_sectors*VFS_SECTOR_SIZE;i++) {
|
||||
// PRINTF("%c", data[i]);
|
||||
// }
|
||||
//}
|
||||
const uint32_t avail = num_sectors*VFS_SECTOR_SIZE;
|
||||
const uint32_t skip = sector_offset*VFS_SECTOR_SIZE;
|
||||
|
||||
IniWriter iw = iw_init((char *)data, skip, avail);
|
||||
settings_build_system_ini(&iw);
|
||||
|
||||
return avail - iw.count;
|
||||
}
|
||||
|
||||
|
||||
void vfs_user_build_filesystem(void)
|
||||
@@ -60,8 +62,8 @@ void vfs_user_build_filesystem(void)
|
||||
// Setup the filesystem based on target parameters
|
||||
vfs_init(daplink_drive_name, 0/*unused "disk size"*/);
|
||||
|
||||
// Write is done using a stream, this is never called
|
||||
vfs_create_file("CONFIG INI", read_file_config_ini, NULL, settings_get_ini_len());
|
||||
vfs_create_file("UNITS INI", read_file_units_ini, NULL, settings_get_units_ini_len());
|
||||
vfs_create_file("SYSTEM INI", read_file_system_ini, NULL, settings_get_system_ini_len());
|
||||
}
|
||||
|
||||
// Callback to handle changes to the root directory. Should be used with vfs_set_file_change_callback
|
||||
|
||||
Reference in New Issue
Block a user