Skip to content

Commit

Permalink
rg_system: Boot config in no longer using rg_settings
Browse files Browse the repository at this point in the history
The main advantage is that we can now easily pass boot config via the RTC memory rather than the SD card.
  • Loading branch information
ducalex committed Nov 29, 2024
1 parent 4768aff commit 7c38f5c
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 51 deletions.
3 changes: 0 additions & 3 deletions components/retro-go/rg_settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ static cJSON *json_root(const char *name, bool set_dirty)
name = rg_basename(rg_system_get_app()->romPath);
else if (name == NS_WIFI)
name = "wifi";
else if (name == NS_BOOT)
name = "boot";

cJSON *branch = cJSON_GetObjectItem(config_root, name);
if (!branch)
Expand Down Expand Up @@ -80,7 +78,6 @@ void rg_settings_init(void)
{
config_root = cJSON_CreateObject();
json_root(NS_GLOBAL, 0);
json_root(NS_BOOT, 0);
}

void rg_settings_commit(void)
Expand Down
1 change: 0 additions & 1 deletion components/retro-go/rg_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#define NS_APP ((char *)1)
#define NS_FILE ((char *)2)
#define NS_WIFI ((char *)3)
#define NS_BOOT ((char *)4)

void rg_settings_init(void);
void rg_settings_commit(void);
Expand Down
107 changes: 60 additions & 47 deletions components/retro-go/rg_system.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ typedef struct
rg_stats_t statistics;
} panic_trace_t;

typedef struct
{
uint32_t magicWord;
char name[32];
char args[256];
uint32_t flags;
} boot_config_t;

typedef struct
{
int32_t totalFrames, fullFrames, partFrames, ticks;
Expand Down Expand Up @@ -78,6 +86,7 @@ static struct

// The trace will survive a software reset
static RTC_NOINIT_ATTR panic_trace_t panicTrace;
static RTC_NOINIT_ATTR boot_config_t bootConfig;
static RTC_NOINIT_ATTR time_t rtcValue;
static bool panicTraceCleared = false;
static bool exitCalled = false;
Expand All @@ -87,9 +96,6 @@ static rg_stats_t statistics;
static rg_app_t app;
static rg_task_t tasks[8];

static const char *SETTING_BOOT_NAME = "BootName";
static const char *SETTING_BOOT_ARGS = "BootArgs";
static const char *SETTING_BOOT_FLAGS = "BootFlags";
static const char *SETTING_TIMEZONE = "Timezone";
static const char *SETTING_INDICATOR_MASK = "Indicators";

Expand Down Expand Up @@ -117,6 +123,35 @@ IRAM_ATTR void esp_panic_putchar_hook(char c)
logbuf_putc(&panicTrace, c);
}

static bool update_boot_config(const char *part, const char *name, const char *args, uint32_t flags)
{
memset(&bootConfig, 0, sizeof(bootConfig));
bootConfig.magicWord = RG_STRUCT_MAGIC;
strncpy(bootConfig.name, name ?: "", sizeof(bootConfig.name));
strncpy(bootConfig.args, args ?: "", sizeof(bootConfig.args));
bootConfig.flags = flags;
rg_storage_write_file(RG_BASE_PATH_CACHE "/boot.bin", &bootConfig, sizeof(bootConfig), 0);

#if defined(ESP_PLATFORM)
// Check if the OTA settings are already correct, and if so do not call esp_ota_set_boot_partition
// This is simply to avoid an unecessary flash write...
const esp_partition_t *current = esp_ota_get_boot_partition();
if (current && part && strncmp(current->label, part, 16) == 0)
{
RG_LOGI("Boot partition already set to desired app!");
return true;
}
esp_err_t err = esp_ota_set_boot_partition(esp_partition_find_first(
ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, part));
if (err != ESP_OK)
{
RG_LOGE("esp_ota_set_boot_partition returned 0x%02X!", err);
return false;
}
#endif
return true;
}

static void update_memory_statistics(void)
{
#ifdef ESP_PLATFORM
Expand Down Expand Up @@ -442,16 +477,27 @@ rg_app_t *rg_system_init(int sampleRate, const rg_handlers_t *handlers, const rg
memset(&panicTrace, 0, sizeof(panicTrace));
panicTraceCleared = true;

// Check if we have a valid boot config (selected emulator, rom file, save state, etc)
if (bootConfig.magicWord != RG_STRUCT_MAGIC || app.isColdBoot)
{
memset(&bootConfig, 0, sizeof(bootConfig));
void *data_ptr = (void *)&bootConfig;
size_t data_len = sizeof(bootConfig);
rg_storage_read_file(RG_BASE_PATH_CACHE "/boot.bin", &data_ptr, &data_len, RG_FILE_USER_BUFFER);
}
if (bootConfig.magicWord == RG_STRUCT_MAGIC) // && strncmp(bootConfig.part, part, sizeof(bootConfig.part)) == 0
{
app.configNs = strdup(bootConfig.name);
app.bootArgs = strdup(bootConfig.args);
app.bootFlags = bootConfig.flags;
}
app.saveSlot = (app.bootFlags & RG_BOOT_SLOT_MASK) >> 4;
app.romPath = app.bootArgs;

update_memory_statistics();
app.lowMemoryMode = statistics.totalMemoryExt == 0;

rg_settings_init();
app.configNs = rg_settings_get_string(NS_BOOT, SETTING_BOOT_NAME, app.name);
app.bootArgs = rg_settings_get_string(NS_BOOT, SETTING_BOOT_ARGS, "");
app.bootFlags = rg_settings_get_number(NS_BOOT, SETTING_BOOT_FLAGS, 0);
app.saveSlot = (app.bootFlags & RG_BOOT_SLOT_MASK) >> 4;
app.romPath = app.bootArgs;
// app.isLauncher = strcmp(app.name, RG_APP_LAUNCHER) == 0; // Might be overriden after init
app.indicatorsMask = rg_settings_get_number(NS_GLOBAL, SETTING_INDICATOR_MASK, app.indicatorsMask);

rg_display_init();
Expand All @@ -476,13 +522,7 @@ rg_app_t *rg_system_init(int sampleRate, const rg_handlers_t *handlers, const rg
rg_gui_alert("External memory not detected", "Boot will continue but it will surely crash...");

if (app.bootFlags & RG_BOOT_ONCE)
{
rg_storage_delete(RG_BASE_PATH_CONFIG "/boot.json");
#ifdef ESP_PLATFORM
esp_ota_set_boot_partition(esp_partition_find_first(
ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, RG_APP_LAUNCHER));
#endif
}
update_boot_config(RG_APP_LAUNCHER, NULL, NULL, 0);

rg_task_create("rg_sysmon", &system_monitor_task, NULL, 3 * 1024, RG_TASK_PRIORITY_5, -1);
app.initialized = true;
Expand Down Expand Up @@ -868,36 +908,10 @@ void rg_system_switch_app(const char *partition, const char *name, const char *a
{
RG_LOGI("Switching to app %s (%s)", partition ?: "-", name ?: "-");

if (app.initialized)
{
rg_settings_set_string(NS_BOOT, SETTING_BOOT_NAME, name);
rg_settings_set_string(NS_BOOT, SETTING_BOOT_ARGS, args);
rg_settings_set_number(NS_BOOT, SETTING_BOOT_FLAGS, flags);
rg_settings_commit();
}
else
{
rg_storage_delete(RG_BASE_PATH_CONFIG "/boot.json");
}
#if defined(ESP_PLATFORM)
// Check if the OTA settings are already correct, and if so do not call esp_ota_set_boot_partition
// This is simply to avoid an unecessary flash write...
const esp_partition_t *current = esp_ota_get_boot_partition();
if (current && partition && strncmp(current->label, partition, 16) == 0)
{
RG_LOGI("Boot partition already set to desired app!");
if (update_boot_config(partition, name, args, flags))
rg_system_restart();
}
esp_err_t err = esp_ota_set_boot_partition(esp_partition_find_first(
ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, partition));
if (err != ESP_OK)
{
RG_LOGE("esp_ota_set_boot_partition returned 0x%02X!", err);
RG_PANIC("Unable to set boot app!");
}
rg_system_restart();
#endif
RG_PANIC("Switch not implemented!");

RG_PANIC("Failed to switch app!");
}

bool rg_system_have_app(const char *app)
Expand Down Expand Up @@ -1214,8 +1228,7 @@ static void emu_update_save_slot(uint8_t slot)
app.bootFlags &= ~RG_BOOT_SLOT_MASK;
app.bootFlags |= app.saveSlot << 4;
app.bootFlags |= RG_BOOT_RESUME;
rg_settings_set_number(NS_BOOT, SETTING_BOOT_FLAGS, app.bootFlags);
rg_settings_commit();
update_boot_config(NULL, app.configNs, app.bootArgs, app.bootFlags);
}

rg_storage_commit();
Expand Down

0 comments on commit 7c38f5c

Please sign in to comment.