From 5c885c7722fa8469cdaaf49a5c4a1668781ce6b2 Mon Sep 17 00:00:00 2001 From: Our Air Quality Date: Thu, 24 Nov 2016 09:41:39 +1100 Subject: [PATCH] sysparam: export the 'compact' function, added it to the editor. (#213) --- core/include/sysparam.h | 11 ++++++++ core/sysparam.c | 30 +++++++++++++++++----- examples/sysparam_editor/sysparam_editor.c | 4 +++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/core/include/sysparam.h b/core/include/sysparam.h index 6fe48b8..60084be 100644 --- a/core/include/sysparam.h +++ b/core/include/sysparam.h @@ -138,6 +138,17 @@ sysparam_status_t sysparam_create_area(uint32_t base_addr, uint16_t num_sectors, */ sysparam_status_t sysparam_get_info(uint32_t *base_addr, uint32_t *num_sectors); +/** Compact the sysparam area. + * + * This also flattens the log. + * + * @retval ::SYSPARAM_OK Completed successfully + * @retval ::SYSPARAM_ERR_NOINIT No current sysparam area is active + * @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data + * @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash + */ +sysparam_status_t sysparam_compact(); + /** Get the value associated with a key * * This is the core "get value" function. It will retrieve the value for the diff --git a/core/sysparam.c b/core/sysparam.c index f00f161..084a2be 100644 --- a/core/sysparam.c +++ b/core/sysparam.c @@ -407,7 +407,7 @@ static inline sysparam_status_t _delete_entry(uint32_t addr) { * the result to the alternate region, then make the new alternate region the * active one. * - * @param key_id A pointer to the "current" key ID. + * @param key_id A pointer to the "current" key ID, or NULL if none. * * NOTE: The value corresponding to the passed key ID will not be written to * the output (because it is assumed it will be overwritten as the next step @@ -424,7 +424,7 @@ static sysparam_status_t _compact_params(struct sysparam_context *ctx, int *key_ uint16_t binary_flag; uint16_t num_sectors = _sysparam_info.region_size / sdk_flashchip.sector_size; - debug(1, "compacting region (current size %d, expect to recover %d%s bytes)...", _sysparam_info.end_addr - _sysparam_info.cur_base, ctx->compactable, (ctx->unused_keys > 0) ? "+ (unused keys present)" : ""); + debug(1, "compacting region (current size %d, expect to recover %d%s bytes)...", _sysparam_info.end_addr - _sysparam_info.cur_base, ctx ? ctx->compactable : 0, (ctx && ctx->unused_keys > 0) ? "+ (unused keys present)" : ""); status = _format_region(new_base, num_sectors); if (status < 0) return status; status = sysparam_iter_start(&iter); @@ -442,7 +442,7 @@ static sysparam_status_t _compact_params(struct sysparam_context *ctx, int *key_ if (status < 0) break; addr += ENTRY_SIZE(iter.key_len); - if ((iter.ctx->entry.idflags & ENTRY_MASK_ID) == *key_id) { + if (key_id && (iter.ctx->entry.idflags & ENTRY_MASK_ID) == *key_id) { // Update key_id to have the correct id for the compacted result *key_id = current_key_id; // Don't copy the old value, since we'll just be deleting it @@ -476,10 +476,12 @@ static sysparam_status_t _compact_params(struct sysparam_context *ctx, int *key_ _sysparam_info.end_addr = addr; _sysparam_info.force_compact = false; - // Fix up ctx so it doesn't point to invalid stuff - memset(ctx, 0, sizeof(*ctx)); - ctx->addr = addr; - ctx->max_key_id = current_key_id; + if (ctx) { + // Fix up ctx so it doesn't point to invalid stuff + memset(ctx, 0, sizeof(*ctx)); + ctx->addr = addr; + ctx->max_key_id = current_key_id; + } debug(1, "done compacting (current size %d)", _sysparam_info.end_addr - _sysparam_info.cur_base); @@ -634,6 +636,20 @@ sysparam_status_t sysparam_get_info(uint32_t *base_addr, uint32_t *num_sectors) return SYSPARAM_OK; } +sysparam_status_t sysparam_compact() { + xSemaphoreTake(_sysparam_info.sem, portMAX_DELAY); + sysparam_status_t status; + + if (_sysparam_info.cur_base) { + status = _compact_params(NULL, NULL); + } else { + status = SYSPARAM_ERR_NOINIT; + } + + xSemaphoreGive(_sysparam_info.sem); + return status; +} + sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t *actual_length, bool *is_binary) { struct sysparam_context ctx; sysparam_status_t status; diff --git a/examples/sysparam_editor/sysparam_editor.c b/examples/sysparam_editor/sysparam_editor.c index a959348..0b58efd 100644 --- a/examples/sysparam_editor/sysparam_editor.c +++ b/examples/sysparam_editor/sysparam_editor.c @@ -31,6 +31,7 @@ void usage(void) { " = -- Set to text \n" " : -- Set to binary value represented as hex\n" " dump -- Show all currently set keys/values\n" + " compact -- Compact the sysparam area\n" " reformat -- Reinitialize (clear) the sysparam area\n" " echo-off -- Disable input echo\n" " echo-on -- Enable input echo\n" @@ -211,6 +212,9 @@ void sysparam_editor_task(void *pvParameters) { } else if (!strcmp(cmd_buffer, "dump")) { printf("Dumping all params:\n"); status = dump_params(); + } else if (!strcmp(cmd_buffer, "compact")) { + printf("Compacting...\n"); + status = sysparam_compact(); } else if (!strcmp(cmd_buffer, "reformat")) { printf("Re-initializing region...\n"); status = sysparam_create_area(base_addr, num_sectors, true);