Split system settings to separate config file

sipo
Ondřej Hruška 6 years ago
parent 0af90eccbf
commit 37f712f054
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 6
      comm/messages.c
  2. 79
      framework/settings.c
  3. 21
      framework/settings.h
  4. 1
      framework/system_settings.h
  5. 4
      framework/unit_registry.c
  6. 2
      platform/plat_compat.h
  7. 4
      vfs/file_stream.c
  8. 32
      vfs/vfs_user.c

@ -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();

@ -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;
}

@ -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

@ -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)

@ -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");
const uint32_t avail = num_sectors*VFS_SECTOR_SIZE;
const uint32_t skip = sector_offset*VFS_SECTOR_SIZE;
////
//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]);
// }
//}
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

Loading…
Cancel
Save