Split system settings to separate config file

sipo
Ondřej Hruška 7 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); 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); assert_param(bulk);
bulk->frame_id = msg->frame_id; 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->read = settings_bulkread_cb;
bulk->userdata = NULL; bulk->userdata = NULL;
@ -124,7 +124,7 @@ static TF_Result lst_ini_import(TinyFrame *tf, TF_Msg *msg)
assert_param(bulk); assert_param(bulk);
bulk->frame_id = msg->frame_id; bulk->frame_id = msg->frame_id;
bulk->len = settings_get_ini_len(); bulk->len = settings_get_units_ini_len();
bulk->write = settings_bulkwrite_cb; bulk->write = settings_bulkwrite_cb;
settings_load_ini_begin(); settings_load_ini_begin();

@ -209,33 +209,63 @@ static void savebuf_flush(PayloadBuilder *pb, bool final)
fls_printf("\r\n"); fls_printf("\r\n");
} }
/** // ---------------------------------------------------------------
* Write system settings to INI (without section)
*/ static void ini_preamble(IniWriter *iw, const char *filename)
void settings_build_ini(IniWriter *iw)
{ {
// File header // 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, "GEX v%s on %s", GEX_VERSION, GEX_PLATFORM);
iw_hdr_comment(iw, "built %s at %s", __DATE__, __TIME__); iw_hdr_comment(iw, "built %s at %s", __DATE__, __TIME__);
iw_cmt_newline(iw); iw_cmt_newline(iw);
iw_comment(iw, "Overwrite this file to change settings."); iw_comment(iw, "Overwrite this file to change settings.");
iw_comment(iw, "Close the LOCK jumper to save them to Flash."); 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); 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) void settings_load_ini_begin(void)
{ {
SystemSettings.modified = true; SystemSettings.modified = true;
SystemSettings.pristine = true;
// load defaults
systemsettings_loadDefaults();
ureg_remove_all_units();
} }
void settings_load_ini_key(const char *restrict section, const char *restrict key, const char *restrict value) 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]; static char namebuf[INI_KEY_MAX];
if (streq(section, "SYSTEM")) { if (streq(section, "SYSTEM")) {
if (SystemSettings.pristine) {
SystemSettings.pristine = false;
systemsettings_loadDefaults();
}
// system is always at the top // system is always at the top
systemsettings_load_ini(key, value); systemsettings_load_ini(key, value);
} }
else if (streq(section, "UNITS")) { else if (streq(section, "UNITS")) {
if (SystemSettings.pristine) {
SystemSettings.pristine = false;
ureg_remove_all_units();
}
// this will always come before individual units config // this will always come before individual units config
// install or tear down units as described by the config // install or tear down units as described by the config
ureg_instantiate_by_ini(key, value); ureg_instantiate_by_ini(key, value);
} else { }
else {
// not a standard section, may be some unit config // 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 *nameptr = strchr(section, ':');
const char *csptr = strchr(section, '@'); const char *csptr = strchr(section, '@');
dbg("cs = %s", csptr);
if (nameptr && csptr) { if (nameptr && csptr) {
strncpy(namebuf, nameptr+1, csptr - nameptr - 1); strncpy(namebuf, nameptr+1, csptr - nameptr - 1);
uint8_t cs = (uint8_t) avr_atoi(csptr + 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); ureg_load_unit_ini_key(namebuf, key, value, cs);
} else { } else {
dbg("! Bad config key: [%s] %s = %s", section, key, value); 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!!"); 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); void settings_load_ini_end(void);
/** /**
* Write all settings to a iniwriter * Write UNITS.INI to a iniwriter
* @param iw - writer handle * @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 * @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 #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 // 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 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 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; extern struct system_settings SystemSettings;

@ -477,6 +477,8 @@ void ureg_build_ini(IniWriter *iw)
count++; count++;
} }
li = li->next; li = li->next;
if (iw->count == 0) return; // avoid printing discarded tail
} }
re = re->next; re = re->next;
iw_newline(iw); iw_newline(iw);
@ -487,6 +489,8 @@ void ureg_build_ini(IniWriter *iw)
while (li != NULL) { while (li != NULL) {
export_unit_do(li, iw); export_unit_do(li, iw);
li = li->next; li = li->next;
if (iw->count == 0) return; // avoid printing discarded tail
} }
} }

@ -5,6 +5,8 @@
#ifndef GEX_PLAT_COMPAT_H #ifndef GEX_PLAT_COMPAT_H
#define GEX_PLAT_COMPAT_H #define GEX_PLAT_COMPAT_H
#define VFS_DRIVE_NAME "GEX"
// -------- Static buffers --------- // -------- Static buffers ---------
#define TSK_STACK_MAIN 220 // USB / VFS task stack size #define TSK_STACK_MAIN 220 // USB / VFS task stack size
#define TSK_STACK_MSG 200 // TF message handler 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 // and may not be known for a while - we cannot use that to detect anything, unless we buffer the entire file
// (a bad idea) // (a bad idea)
// TODO detect config file // Our INI files always start with two hashes
return data[0] == '#'; // here we just assume everything is INI return size >= 2 && data[0] == '#' && data[1] == '#';
} }
static void iniparser_cb(const char *section, const char *key, const char *value, void *userData) static void iniparser_cb(const char *section, const char *key, const char *value, void *userData)

@ -25,32 +25,34 @@
#include "vfs_manager.h" #include "vfs_manager.h"
#include "str_utils.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 // 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 avail = num_sectors*VFS_SECTOR_SIZE;
const uint32_t skip = sector_offset*VFS_SECTOR_SIZE; const uint32_t skip = sector_offset*VFS_SECTOR_SIZE;
IniWriter iw = iw_init((char *)data, skip, avail); IniWriter iw = iw_init((char *)data, skip, avail);
settings_build_ini(&iw); settings_build_units_ini(&iw);
return avail - iw.count; 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;
//static void write_file_config_ini(uint32_t sector_offset, const uint8_t *data, uint32_t num_sectors) const uint32_t skip = sector_offset*VFS_SECTOR_SIZE;
//{
// vfs_printf("Write CONFIG.INI, so %d, ns %d", sector_offset, num_sectors); IniWriter iw = iw_init((char *)data, skip, avail);
// settings_build_system_ini(&iw);
// for(uint32_t i=0;i<num_sectors*VFS_SECTOR_SIZE;i++) {
// PRINTF("%c", data[i]); return avail - iw.count;
// } }
//}
void vfs_user_build_filesystem(void) void vfs_user_build_filesystem(void)
@ -60,8 +62,8 @@ void vfs_user_build_filesystem(void)
// Setup the filesystem based on target parameters // Setup the filesystem based on target parameters
vfs_init(daplink_drive_name, 0/*unused "disk size"*/); vfs_init(daplink_drive_name, 0/*unused "disk size"*/);
// Write is done using a stream, this is never called vfs_create_file("UNITS INI", read_file_units_ini, NULL, settings_get_units_ini_len());
vfs_create_file("CONFIG INI", read_file_config_ini, NULL, settings_get_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 // Callback to handle changes to the root directory. Should be used with vfs_set_file_change_callback

Loading…
Cancel
Save