From e4fc877d319c44fc9673583bd9dcee01d9e0ddba Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Thu, 14 Oct 2021 16:54:27 -0400 Subject: [PATCH 01/43] shell comments for cfg_page --- examples/dtls-sock/cfg-page-shell.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 examples/dtls-sock/cfg-page-shell.c diff --git a/examples/dtls-sock/cfg-page-shell.c b/examples/dtls-sock/cfg-page-shell.c new file mode 100644 index 000000000000..31bd2cf72a79 --- /dev/null +++ b/examples/dtls-sock/cfg-page-shell.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2021 Michael Richardson + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include + +#include "mtd.h" +#include "cfg_page.h" +#include "od.h" +#include "board.h" + +static char cfg_page_temp[MTD_PAGE_SIZE]; + +int cfgpage_print_cmd(int argc, char **argv) +{ + (void)argc; + (void)argv; + if(mtd_read(cfgpage.dev, cfg_page_temp, 0, MTD_PAGE_SIZE) != 0) { + return -1; + } + + od_hex_dump_ext(cfg_page_temp, MTD_PAGE_SIZE, 16, 0); + + return 0; +} From e568eb146fa4ecc96f7b285bf954237b64e16228 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Thu, 14 Oct 2021 16:54:53 -0400 Subject: [PATCH 02/43] initial work on cfg_page --- drivers/cfg_page/Kconfig | 10 ++++ drivers/cfg_page/Makefile | 3 + drivers/cfg_page/cfg_page.c | 111 ++++++++++++++++++++++++++++++++++++ drivers/include/cfg_page.h | 46 +++++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 drivers/cfg_page/Kconfig create mode 100644 drivers/cfg_page/Makefile create mode 100644 drivers/cfg_page/cfg_page.c create mode 100644 drivers/include/cfg_page.h diff --git a/drivers/cfg_page/Kconfig b/drivers/cfg_page/Kconfig new file mode 100644 index 000000000000..5b10b27a2f86 --- /dev/null +++ b/drivers/cfg_page/Kconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2020 HAW Hamburg +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. +# + +config MODULE_CFG_PAGE + bool "Generic Configuration Data flash interface" + depends on TEST_KCONFIG diff --git a/drivers/cfg_page/Makefile b/drivers/cfg_page/Makefile new file mode 100644 index 000000000000..12846883c082 --- /dev/null +++ b/drivers/cfg_page/Makefile @@ -0,0 +1,3 @@ +include $(RIOTBASE)/Makefile.base + +USEPKG += nanocbor diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c new file mode 100644 index 000000000000..ec8f522ba5ce --- /dev/null +++ b/drivers/cfg_page/cfg_page.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2021 Michael Richardson + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup drivers_cfg_page + * @brief configuration data flash page + * @{ + * + * @file + * @brief configuration page access routines + * + * @author Michael Ricahrdson + * + * A Configuration Page consists of a fixed 16 byte header, followed by an indefinite map. + * The header is a CBOR sequence with 3 elements: + * 1) A CBOR-file-magic SEQUENCE with tag "RIOT" + * D9 D9F7 # tag(55799) + * DA 52494F54 # tag(1380536148) + * 63 # text(3) + * 424F52 # "BOR" + * 2) A single byte sequence counter, mod 24 (so 0 > 24) + * 01 # unsigned(1) + * 3) A 16-bit checksum of the previous 13 bytes. + * 19 3345 # unsigned(13125) + * 4) An indefinite map containing key/values. + * @} + */ + +#include +#include + +#include "cfg_page.h" + +#define ENABLE_DEBUG 1 +#include "debug.h" + +/* for MTD_1 */ +#include "board.h" + +int cfg_page_init(struct cfg_page_desc_t *cpd) +{ + DEBUG("cfg_page: init\n"); +#ifdef MTD_1 + cpd->dev = MTD_1; + mtd_init(cpd->dev); +#endif + + return 0; +} + +#define CBOR_SEQ_TAG 55800 /* per draft-ietf-cbor-file-magic */ +#define CFG_PAGE_RIOT_TAG 1380536148 /* 'RIOT' */ + +int cfg_page_validate(struct cfg_page_desc_t *cpd) +{ + unsigned char header_buffer[CFG_PAGE_HEADER_SIZE]; + nanocbor_value_t decoder; + uint32_t tagval = 0x12345678; + int16_t checksum = 0; + int8_t serialno = 0; + + /* read things in first */ + if(mtd_read(cpd->dev, header_buffer, 0, sizeof(CFG_PAGE_HEADER_SIZE)) != 0) { + return -1; + } + + /* validate the checksum */ + nanocbor_decoder_init(&decoder, header_buffer, CFG_PAGE_HEADER_SIZE); + + /* pull in the tags */ + if(nanocbor_get_tag(&decoder, &tagval) != NANOCBOR_OK + || tagval != CBOR_SEQ_TAG) { + return -1; + } + + if(nanocbor_get_tag(&decoder, &tagval) != NANOCBOR_OK + || tagval != CFG_PAGE_RIOT_TAG) { + return -1; + } + + if(nanocbor_get_bstr(&val, &bytes, &bytes_len) != NANOCBOR_OK + || bytes_len != 3 + || bytes[0]!= 'B' + || bytes[1]!= 'O' + || bytes[2]!= 'R') { + return -1; + } + + if(nanocbor_get_int8(&val, &serialno) != NANOCBOR_OK) { + return -1; + } + + /* calculate a 16-bit checksum across the bytes so far */ + int16_t calculated = crc16_ccitt_calc(header_buffer, (val->cur - header_buffer)); + + if(nanocbor_get_int16(&val, &checksum) != NANOCBOR_OK) { + return -1; + } + + if(calculated != checksum) { + return -1; + } + + /* Good News Everyone! */ + return 0; +} diff --git a/drivers/include/cfg_page.h b/drivers/include/cfg_page.h new file mode 100644 index 000000000000..fecf62d46196 --- /dev/null +++ b/drivers/include/cfg_page.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2021 Michael Richardson + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup cfg_page + * @ingroup notsure + * @brief Driver Configuration Pages + * + * @{ + * + * @file + * @brief Public interface for CFG Pages driver + * @author Michael Richardson + */ + +#ifndef CFG_PAGE_H +#define CFG_PAGE_H + +#include "mtd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name CFG page configuration + * @{ + */ +struct cfg_page_desc_t { + mtd_dev_t *dev; +}; + +extern int cfg_page_init(struct cfg_page_desc_t *cpd); +extern struct cfg_page_desc_t cfgpage; + +#ifdef __cplusplus +} +#endif + +#endif /* CFG_PAGE_H */ +/** @} */ From ce6855e05e75bf2783e9c02534fb96374d05c02d Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Thu, 14 Oct 2021 17:04:31 -0400 Subject: [PATCH 03/43] added CFG_PAGE options to native board --- boards/native/Makefile.features | 3 +++ boards/native/board_init.c | 25 +++++++++++++++++++++++++ boards/native/include/board.h | 9 +++++++++ 3 files changed, 37 insertions(+) diff --git a/boards/native/Makefile.features b/boards/native/Makefile.features index d0a5c35b1dc1..1a1f7f8f4272 100644 --- a/boards/native/Makefile.features +++ b/boards/native/Makefile.features @@ -11,3 +11,6 @@ FEATURES_PROVIDED += periph_qdec # Various other features (if any) FEATURES_PROVIDED += ethernet FEATURES_PROVIDED += motor_driver + +# Put other features for this board (in alphabetical order) +FEATURES_PROVIDED += riotboot diff --git a/boards/native/board_init.c b/boards/native/board_init.c index 7b331f08c07a..340a88342dc8 100644 --- a/boards/native/board_init.c +++ b/boards/native/board_init.c @@ -22,6 +22,11 @@ #include "mtd_native.h" #endif +#ifdef MODULE_CFG_PAGE +#include "cfg_page.h" +struct cfg_page_desc_t cfgpage; +#endif + /** * Nothing to initialize at the moment. * Turns the red LED on and the green LED off. @@ -32,6 +37,9 @@ void board_init(void) LED1_ON; puts("RIOT native board initialized."); +#ifdef MODULE_CFG_PAGE + cfg_page_init(&cfgpage); +#endif } #ifdef MODULE_MTD @@ -47,3 +55,20 @@ static mtd_native_dev_t mtd0_dev = { mtd_dev_t *mtd0 = (mtd_dev_t *)&mtd0_dev; #endif + +#ifdef MODULE_CFG_PAGE +#ifndef MTD1_SECTOR_NUM +#define MTD1_SECTOR_NUM 2 +#endif +static mtd_native_dev_t mtd1_dev = { + .dev = { + .driver = &native_flash_driver, + .sector_count = MTD1_SECTOR_NUM, + .pages_per_sector = MTD_SECTOR_SIZE / MTD_PAGE_SIZE, + .page_size = MTD_PAGE_SIZE, + }, + .fname = MTD_NATIVE_CFG_FILENAME, +}; + +mtd_dev_t *mtd1 = (mtd_dev_t *)&mtd1_dev; +#endif diff --git a/boards/native/include/board.h b/boards/native/include/board.h index 9a36e3b4c9f9..415062dc4b28 100644 --- a/boards/native/include/board.h +++ b/boards/native/include/board.h @@ -71,6 +71,9 @@ void _native_LED_RED_TOGGLE(void); #ifndef MTD_NATIVE_FILENAME #define MTD_NATIVE_FILENAME "MEMORY.bin" #endif +#ifndef MTD_NATIVE_CFG_FILENAME +#define MTD_NATIVE_CFG_FILENAME "CONFIG.bin" +#endif /** @} */ /** Default MTD device */ @@ -78,6 +81,12 @@ void _native_LED_RED_TOGGLE(void); /** mtd flash emulation device */ extern mtd_dev_t *mtd0; + +#ifdef MODULE_CFG_PAGE +#define MTD_1 mtd1 +extern mtd_dev_t *mtd1; +#endif + #endif #if defined(MODULE_SPIFFS) || DOXYGEN From f317b3d1cf62635dac603757d1f6c5252e79cbb3 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Sun, 17 Oct 2021 22:52:39 -0400 Subject: [PATCH 04/43] return serialno from cfg_page_validate, and remove debugging, fix integer get code --- drivers/cfg_page/cfg_page.c | 59 ++++++++++++++++++++----------- drivers/include/cfg_page.h | 1 + tests/driver_cfg_page/Makefile | 12 +++++++ tests/driver_cfg_page/Makefile.ci | 8 +++++ tests/driver_cfg_page/README.md | 7 ++++ tests/driver_cfg_page/main.c | 41 +++++++++++++++++++++ 6 files changed, 108 insertions(+), 20 deletions(-) create mode 100644 tests/driver_cfg_page/Makefile create mode 100644 tests/driver_cfg_page/Makefile.ci create mode 100644 tests/driver_cfg_page/README.md create mode 100644 tests/driver_cfg_page/main.c diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index ec8f522ba5ce..df114cf128a1 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -21,7 +21,7 @@ * 1) A CBOR-file-magic SEQUENCE with tag "RIOT" * D9 D9F7 # tag(55799) * DA 52494F54 # tag(1380536148) - * 63 # text(3) + * 43 # bytes(3) * 424F52 # "BOR" * 2) A single byte sequence counter, mod 24 (so 0 > 24) * 01 # unsigned(1) @@ -34,7 +34,10 @@ #include #include +#include "nanocbor/nanocbor.h" +#include "checksum/crc16_ccitt.h" #include "cfg_page.h" +#include "od.h" #define ENABLE_DEBUG 1 #include "debug.h" @@ -54,58 +57,74 @@ int cfg_page_init(struct cfg_page_desc_t *cpd) } #define CBOR_SEQ_TAG 55800 /* per draft-ietf-cbor-file-magic */ -#define CFG_PAGE_RIOT_TAG 1380536148 /* 'RIOT' */ +#define CFG_PAGE_RIOT_TAG 1380536148 /* 'RIOT' = 0x52 0x49 0x4f 0x54 */ -int cfg_page_validate(struct cfg_page_desc_t *cpd) +#ifndef CFG_PAGE_HEADER_SIZE +#define CFG_PAGE_HEADER_SIZE 16 +#endif + + +int cfg_page_validate(struct cfg_page_desc_t *cpd, int cfg_slot_no) { unsigned char header_buffer[CFG_PAGE_HEADER_SIZE]; nanocbor_value_t decoder; uint32_t tagval = 0x12345678; - int16_t checksum = 0; + uint16_t checksum = 0; int8_t serialno = 0; + const uint8_t *bytes = NULL; + size_t bytes_len; - /* read things in first */ - if(mtd_read(cpd->dev, header_buffer, 0, sizeof(CFG_PAGE_HEADER_SIZE)) != 0) { + /* read things in a specific block in first */ + if(mtd_read(cpd->dev, header_buffer, 0, CFG_PAGE_HEADER_SIZE) != 0) { + puts("read failed\n"); return -1; } + //od_hex_dump_ext(header_buffer, CFG_PAGE_HEADER_SIZE, 16, 0); + /* validate the checksum */ nanocbor_decoder_init(&decoder, header_buffer, CFG_PAGE_HEADER_SIZE); /* pull in the tags */ - if(nanocbor_get_tag(&decoder, &tagval) != NANOCBOR_OK - || tagval != CBOR_SEQ_TAG) { + if(nanocbor_get_tag(&decoder, &tagval) != NANOCBOR_OK) { return -1; } - if(nanocbor_get_tag(&decoder, &tagval) != NANOCBOR_OK - || tagval != CFG_PAGE_RIOT_TAG) { - return -1; + if(tagval != CBOR_SEQ_TAG) { + return -2; + } + + if(nanocbor_get_tag(&decoder, &tagval) != NANOCBOR_OK) { + return -3; } - if(nanocbor_get_bstr(&val, &bytes, &bytes_len) != NANOCBOR_OK + if(tagval != CFG_PAGE_RIOT_TAG) { + return -4; + } + + if(nanocbor_get_bstr(&decoder, &bytes, &bytes_len) != NANOCBOR_OK || bytes_len != 3 || bytes[0]!= 'B' || bytes[1]!= 'O' || bytes[2]!= 'R') { - return -1; + return -5; } - if(nanocbor_get_int8(&val, &serialno) != NANOCBOR_OK) { - return -1; + if(nanocbor_get_int8(&decoder, &serialno) < NANOCBOR_OK) { + return -6; } /* calculate a 16-bit checksum across the bytes so far */ - int16_t calculated = crc16_ccitt_calc(header_buffer, (val->cur - header_buffer)); + uint16_t calculated = crc16_ccitt_calc(header_buffer, (decoder.cur - header_buffer)); - if(nanocbor_get_int16(&val, &checksum) != NANOCBOR_OK) { - return -1; + if(nanocbor_get_uint16(&decoder, &checksum) < NANOCBOR_OK) { + return -7; } if(calculated != checksum) { - return -1; + return -8; } /* Good News Everyone! */ - return 0; + return serialno; } diff --git a/drivers/include/cfg_page.h b/drivers/include/cfg_page.h index fecf62d46196..a1da4ae0264a 100644 --- a/drivers/include/cfg_page.h +++ b/drivers/include/cfg_page.h @@ -36,6 +36,7 @@ struct cfg_page_desc_t { }; extern int cfg_page_init(struct cfg_page_desc_t *cpd); +extern int cfg_page_validate(struct cfg_page_desc_t *cpd, int cfg_slot_no); extern struct cfg_page_desc_t cfgpage; #ifdef __cplusplus diff --git a/tests/driver_cfg_page/Makefile b/tests/driver_cfg_page/Makefile new file mode 100644 index 000000000000..ccf1334ee785 --- /dev/null +++ b/tests/driver_cfg_page/Makefile @@ -0,0 +1,12 @@ +include ../Makefile.tests_common + +BOARD?= native +USEMODULE += mtd +USEMODULE += mtd_native +USEMODULE += cfg_page +USEMODULE += checksum +USEMODULE += od +USEPKG += nanocbor + + +include $(RIOTBASE)/Makefile.include diff --git a/tests/driver_cfg_page/Makefile.ci b/tests/driver_cfg_page/Makefile.ci new file mode 100644 index 000000000000..1152ca53bcbb --- /dev/null +++ b/tests/driver_cfg_page/Makefile.ci @@ -0,0 +1,8 @@ +BOARD_INSUFFICIENT_MEMORY := \ + arduino-duemilanove \ + arduino-leonardo \ + arduino-nano \ + arduino-uno \ + atmega328p \ + atmega328p-xplained-mini \ + # diff --git a/tests/driver_cfg_page/README.md b/tests/driver_cfg_page/README.md new file mode 100644 index 000000000000..f3b03fedc1dc --- /dev/null +++ b/tests/driver_cfg_page/README.md @@ -0,0 +1,7 @@ +# About +This is a manual test application for the CFG-PAGE driver. + +# Usage + +This test application will use the native target with a series of input files. + diff --git a/tests/driver_cfg_page/main.c b/tests/driver_cfg_page/main.c new file mode 100644 index 000000000000..70b44b9bb7a7 --- /dev/null +++ b/tests/driver_cfg_page/main.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 Michael Richardson + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief Test application for the CFG-PAGE driver + * + * @author Michael Richardson + * + * @} + */ + +#include +#include +#include + +#include "board.h" +#include "cfg_page.h" + +//static char cfg_page_temp[MTD_PAGE_SIZE]; + +int main(void) +{ + puts("CFG-PAGE test application starting..."); + + cfg_page_init(&cfgpage, 0); + + if(cfg_page_validate(&cfgpage) == 0) { + puts("succeed\n"); + } else { + puts("failed\n"); + } +} From f17368e8b39fde43e5a642b8219eba921bdf8b1f Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Tue, 19 Oct 2021 22:53:43 -0400 Subject: [PATCH 05/43] added cfg_page_format to initialize the new pages --- drivers/cfg_page/cfg_page.c | 77 ++++++++++++++++++++++++++++++++++++- drivers/include/cfg_page.h | 1 + 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index df114cf128a1..1add2f97e00e 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -73,9 +73,18 @@ int cfg_page_validate(struct cfg_page_desc_t *cpd, int cfg_slot_no) int8_t serialno = 0; const uint8_t *bytes = NULL; size_t bytes_len; + unsigned int byte_offset = 0; + + if(cfg_slot_no == 0) { + byte_offset = 0; + } else if(cfg_slot_no == 1) { + byte_offset = MTD_SECTOR_SIZE; + } else { + return -1; + } /* read things in a specific block in first */ - if(mtd_read(cpd->dev, header_buffer, 0, CFG_PAGE_HEADER_SIZE) != 0) { + if(mtd_read(cpd->dev, header_buffer, byte_offset, CFG_PAGE_HEADER_SIZE) != 0) { puts("read failed\n"); return -1; } @@ -128,3 +137,69 @@ int cfg_page_validate(struct cfg_page_desc_t *cpd, int cfg_slot_no) /* Good News Everyone! */ return serialno; } + +int cfg_page_format(struct cfg_page_desc_t *cpd, int cfg_slot_no, int serialno) +{ + unsigned char header_buffer[CFG_PAGE_HEADER_SIZE+2]; + nanocbor_encoder_t encoder; + unsigned int write_size=CFG_PAGE_HEADER_SIZE+2; + + nanocbor_encoder_init(&encoder, header_buffer, write_size); + + if(nanocbor_fmt_tag(&encoder, CBOR_SEQ_TAG) < 0) { + return -1; + } + + if(nanocbor_fmt_tag(&encoder, CFG_PAGE_RIOT_TAG) < 0) { + return -1; + } + + if(nanocbor_put_bstr(&encoder, (unsigned const char *)"BOR", 3) < 0) { + return -1; + } + + if(nanocbor_fmt_uint(&encoder, serialno) < NANOCBOR_OK) { + return -6; + } + + /* now calculate the CRC */ + /* calculate a 16-bit checksum across the bytes so far */ + uint16_t calculated = crc16_ccitt_calc(header_buffer, (encoder.cur - header_buffer)); + + if(nanocbor_fmt_uint(&encoder, calculated) < NANOCBOR_OK) { + return -7; + } + + /* now initialize an indefinite map, and stop code */ + if(nanocbor_fmt_map_indefinite(&encoder) < 0) { + return -8; + } + if(nanocbor_fmt_end_indefinite(&encoder) < 0) { + return -9; + } + + unsigned int byte_offset = 0; + if(cfg_slot_no == 0) { + byte_offset = 0; + } else if(cfg_slot_no == 1) { + byte_offset = MTD_SECTOR_SIZE; + } else { + return -1; + } + + /* read things in a specific block in first */ + printf("writing %d bytes to slot_no: %d, at offset: %u\n", write_size, + cfg_slot_no, byte_offset); + + od_hex_dump_ext(header_buffer, write_size, 16, 0); + + int error = 0; + if((error = mtd_write(cpd->dev, header_buffer, byte_offset, write_size)) != NANOCBOR_OK) { + printf("write failed: %d\n", error); + return -11; + } + + printf("formatted slot %u\n", cfg_slot_no); + return 0; +} + diff --git a/drivers/include/cfg_page.h b/drivers/include/cfg_page.h index a1da4ae0264a..853e06a628b7 100644 --- a/drivers/include/cfg_page.h +++ b/drivers/include/cfg_page.h @@ -37,6 +37,7 @@ struct cfg_page_desc_t { extern int cfg_page_init(struct cfg_page_desc_t *cpd); extern int cfg_page_validate(struct cfg_page_desc_t *cpd, int cfg_slot_no); +extern int cfg_page_format(struct cfg_page_desc_t *cpd, int cfg_slot_no, int slotno); extern struct cfg_page_desc_t cfgpage; #ifdef __cplusplus From 2e11c11403f6ceedf5b7d4d273dc50bedf398f9b Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Tue, 19 Oct 2021 22:59:48 -0400 Subject: [PATCH 06/43] moved slot selection code out of tester, into cfg_page_init --- drivers/cfg_page/cfg_page.c | 56 ++++++++++++++++++++++++++---------- drivers/include/cfg_page.h | 3 ++ tests/driver_cfg_page/main.c | 8 +----- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 1add2f97e00e..9d2acc739644 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -45,17 +45,6 @@ /* for MTD_1 */ #include "board.h" -int cfg_page_init(struct cfg_page_desc_t *cpd) -{ - DEBUG("cfg_page: init\n"); -#ifdef MTD_1 - cpd->dev = MTD_1; - mtd_init(cpd->dev); -#endif - - return 0; -} - #define CBOR_SEQ_TAG 55800 /* per draft-ietf-cbor-file-magic */ #define CFG_PAGE_RIOT_TAG 1380536148 /* 'RIOT' = 0x52 0x49 0x4f 0x54 */ @@ -85,7 +74,7 @@ int cfg_page_validate(struct cfg_page_desc_t *cpd, int cfg_slot_no) /* read things in a specific block in first */ if(mtd_read(cpd->dev, header_buffer, byte_offset, CFG_PAGE_HEADER_SIZE) != 0) { - puts("read failed\n"); + DEBUG("read failed\n"); return -1; } @@ -188,18 +177,55 @@ int cfg_page_format(struct cfg_page_desc_t *cpd, int cfg_slot_no, int serialno) } /* read things in a specific block in first */ - printf("writing %d bytes to slot_no: %d, at offset: %u\n", write_size, + DEBUG("writing %d bytes to slot_no: %d, at offset: %u\n", write_size, cfg_slot_no, byte_offset); od_hex_dump_ext(header_buffer, write_size, 16, 0); int error = 0; if((error = mtd_write(cpd->dev, header_buffer, byte_offset, write_size)) != NANOCBOR_OK) { - printf("write failed: %d\n", error); + DEBUG("write failed: %d\n", error); return -11; } - printf("formatted slot %u\n", cfg_slot_no); + DEBUG("formatted slot %u\n", cfg_slot_no); return 0; } +int cfg_page_init(struct cfg_page_desc_t *cpd) +{ + DEBUG("cfg_page: init\n"); +#ifdef MTD_1 + cpd->dev = MTD_1; + mtd_init(cpd->dev); +#endif + + int slot0_serial = cfg_page_validate(&cfgpage, 0); + int slot1_serial = cfg_page_validate(&cfgpage, 1); + cpd->active_page = 0; + + if(slot0_serial < 0 && slot1_serial < 0) { + DEBUG("Formatting cfg page %u\n", cpd->active_page); + cfg_page_format(&cfgpage, cfg_active_page, 0); + } else if(slot0_serial < 0 && slot1_serial >= 0) { + cpd->active_page = 1; + } else if(slot0_serial >= 0 && slot1_serial < 0) { + cpd->active_page = 0; + } else if(slot0_serial >= slot1_serial) { + cpd->active_page = 0; + } else { + cpd->active_page = 1; + } + + DEBUG("Using cfg page %u\n", cpd->active_page); + + /* + * now setup with a nanocbor writer, pointing at the end of the + * active page + */ + + + + return 0; +} + diff --git a/drivers/include/cfg_page.h b/drivers/include/cfg_page.h index 853e06a628b7..231bdc1def14 100644 --- a/drivers/include/cfg_page.h +++ b/drivers/include/cfg_page.h @@ -22,6 +22,7 @@ #define CFG_PAGE_H #include "mtd.h" +#include "nanocbor/nanocbor.h" #ifdef __cplusplus extern "C" { @@ -33,6 +34,8 @@ extern "C" { */ struct cfg_page_desc_t { mtd_dev_t *dev; + nanocbor_encoder_t writer; + uint8_t active_page; /* 0 or 1 */ }; extern int cfg_page_init(struct cfg_page_desc_t *cpd); diff --git a/tests/driver_cfg_page/main.c b/tests/driver_cfg_page/main.c index 70b44b9bb7a7..91c8cc991d38 100644 --- a/tests/driver_cfg_page/main.c +++ b/tests/driver_cfg_page/main.c @@ -31,11 +31,5 @@ int main(void) { puts("CFG-PAGE test application starting..."); - cfg_page_init(&cfgpage, 0); - - if(cfg_page_validate(&cfgpage) == 0) { - puts("succeed\n"); - } else { - puts("failed\n"); - } + cfg_page_init(&cfgpage); } From 6f16a3b5087c4a4d9653a05885739ba2152e734e Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 20 Oct 2021 14:27:32 -0400 Subject: [PATCH 07/43] changed struct cfg_page_desc_t to typedef added cfg_page_print added cfg_page_init_reader --- boards/native/board_init.c | 2 +- drivers/cfg_page/Makefile | 1 - drivers/cfg_page/Makefile.dep | 1 + drivers/cfg_page/cfg_page.c | 49 +++++++++++++----- drivers/cfg_page/cfg_page_print.c | 86 +++++++++++++++++++++++++++++++ drivers/include/cfg_page.h | 18 ++++--- tests/driver_cfg_page/main.c | 5 +- 7 files changed, 138 insertions(+), 24 deletions(-) create mode 100644 drivers/cfg_page/Makefile.dep create mode 100644 drivers/cfg_page/cfg_page_print.c diff --git a/boards/native/board_init.c b/boards/native/board_init.c index 340a88342dc8..1213ce115b91 100644 --- a/boards/native/board_init.c +++ b/boards/native/board_init.c @@ -24,7 +24,7 @@ #ifdef MODULE_CFG_PAGE #include "cfg_page.h" -struct cfg_page_desc_t cfgpage; +cfg_page_desc_t cfgpage; #endif /** diff --git a/drivers/cfg_page/Makefile b/drivers/cfg_page/Makefile index 12846883c082..f46397d24738 100644 --- a/drivers/cfg_page/Makefile +++ b/drivers/cfg_page/Makefile @@ -1,3 +1,2 @@ include $(RIOTBASE)/Makefile.base -USEPKG += nanocbor diff --git a/drivers/cfg_page/Makefile.dep b/drivers/cfg_page/Makefile.dep new file mode 100644 index 000000000000..fff52335fbbc --- /dev/null +++ b/drivers/cfg_page/Makefile.dep @@ -0,0 +1 @@ +USEPKG += nanocbor diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 9d2acc739644..dad802ddc8db 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -52,8 +52,22 @@ #define CFG_PAGE_HEADER_SIZE 16 #endif +int _calculate_slot_offset(unsigned int cfg_slot_no) +{ + int byte_offset = 0; -int cfg_page_validate(struct cfg_page_desc_t *cpd, int cfg_slot_no) + if(cfg_slot_no == 0) { + byte_offset = 0; + } else if(cfg_slot_no == 1) { + byte_offset = MTD_SECTOR_SIZE; + } else { + return -1; + } + return byte_offset; +} + + +int cfg_page_validate(cfg_page_desc_t *cpd, int cfg_slot_no) { unsigned char header_buffer[CFG_PAGE_HEADER_SIZE]; nanocbor_value_t decoder; @@ -127,7 +141,7 @@ int cfg_page_validate(struct cfg_page_desc_t *cpd, int cfg_slot_no) return serialno; } -int cfg_page_format(struct cfg_page_desc_t *cpd, int cfg_slot_no, int serialno) +int cfg_page_format(cfg_page_desc_t *cpd, int cfg_slot_no, int serialno) { unsigned char header_buffer[CFG_PAGE_HEADER_SIZE+2]; nanocbor_encoder_t encoder; @@ -167,14 +181,7 @@ int cfg_page_format(struct cfg_page_desc_t *cpd, int cfg_slot_no, int serialno) return -9; } - unsigned int byte_offset = 0; - if(cfg_slot_no == 0) { - byte_offset = 0; - } else if(cfg_slot_no == 1) { - byte_offset = MTD_SECTOR_SIZE; - } else { - return -1; - } + unsigned int byte_offset = _calculate_slot_offset(cfg_slot_no); /* read things in a specific block in first */ DEBUG("writing %d bytes to slot_no: %d, at offset: %u\n", write_size, @@ -192,7 +199,25 @@ int cfg_page_format(struct cfg_page_desc_t *cpd, int cfg_slot_no, int serialno) return 0; } -int cfg_page_init(struct cfg_page_desc_t *cpd) +int cfg_page_init_reader(cfg_page_desc_t *cpd, + unsigned char *cfg_page_buffer, size_t cfg_page_size, + nanocbor_value_t *cfg_page_reader) +{ + unsigned int byte_offset = _calculate_slot_offset(cpd->active_page); + + /* read in the whole page */ + if(mtd_read(cpd->dev, cfg_page_buffer, byte_offset, cfg_page_size) != 0) { + DEBUG("read failed\n"); + return -1; + } + + nanocbor_decoder_init(cfg_page_reader, cfg_page_buffer+CFG_PAGE_HEADER_SIZE, + cfg_page_size - CFG_PAGE_HEADER_SIZE); + + return 0; +} + +int cfg_page_init(cfg_page_desc_t *cpd) { DEBUG("cfg_page: init\n"); #ifdef MTD_1 @@ -206,7 +231,7 @@ int cfg_page_init(struct cfg_page_desc_t *cpd) if(slot0_serial < 0 && slot1_serial < 0) { DEBUG("Formatting cfg page %u\n", cpd->active_page); - cfg_page_format(&cfgpage, cfg_active_page, 0); + cfg_page_format(&cfgpage, cpd->active_page, 0); } else if(slot0_serial < 0 && slot1_serial >= 0) { cpd->active_page = 1; } else if(slot0_serial >= 0 && slot1_serial < 0) { diff --git a/drivers/cfg_page/cfg_page_print.c b/drivers/cfg_page/cfg_page_print.c new file mode 100644 index 000000000000..a6419806992c --- /dev/null +++ b/drivers/cfg_page/cfg_page_print.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2021 Michael Richardson + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup drivers_cfg_page + * @brief configuration data flash page + * @{ + * + * @file + * @brief configuration page debug routines + * + * @author Michael Ricahrdson + * + * @} + */ + +#include +#include + +#include "nanocbor/nanocbor.h" +#include "checksum/crc16_ccitt.h" +#include "cfg_page.h" +#include "od.h" + +#define ENABLE_DEBUG 1 +#include "debug.h" + +/* for MTD_1 */ +#include "board.h" + +int cfg_page_print(cfg_page_desc_t *cpd) +{ + static unsigned char cfg_page_temp[MTD_PAGE_SIZE]; + nanocbor_value_t reader; + nanocbor_value_t values; + + if(cfg_page_init_reader(cpd, cfg_page_temp, sizeof(cfg_page_temp), &reader) < 0) { + return -1; + } + + if(nanocbor_get_type(&reader) != NANOCBOR_TYPE_MAP || + nanocbor_enter_map(&reader, &values) != NANOCBOR_OK) { + return -2; + } + + while(!nanocbor_at_end(&values)) { + uint32_t key; + unsigned int type; + const uint8_t *str = NULL; + size_t len; + if(nanocbor_get_uint32(&values, &key) < 0) { + DEBUG("non interger key value found: %d", nanocbor_get_type(&values)); + return -3; + } + + type = nanocbor_get_type(&values); + printf("key: %u[type=%u]\n", key, type); + switch(type) { + case NANOCBOR_TYPE_BSTR: + if(nanocbor_get_bstr(&values, &str, &len) == NANOCBOR_OK) { + od_hex_dump_ext(str, len, 16, 0); + } + break; + + case NANOCBOR_TYPE_TSTR: + if(nanocbor_get_tstr(&values, &str, &len) == NANOCBOR_OK) { + /* XXX print as bounded string? */ + //od_hex_dump_ext(str, len, 16, 0); + printf(" value: %.*s\n", len, str); + } + break; + + default: + nanocbor_skip(&values); + } + + } + + return 0; +} + diff --git a/drivers/include/cfg_page.h b/drivers/include/cfg_page.h index 231bdc1def14..6ae4d14734aa 100644 --- a/drivers/include/cfg_page.h +++ b/drivers/include/cfg_page.h @@ -32,16 +32,20 @@ extern "C" { * @name CFG page configuration * @{ */ -struct cfg_page_desc_t { +typedef struct cfg_page_desc { mtd_dev_t *dev; nanocbor_encoder_t writer; uint8_t active_page; /* 0 or 1 */ -}; - -extern int cfg_page_init(struct cfg_page_desc_t *cpd); -extern int cfg_page_validate(struct cfg_page_desc_t *cpd, int cfg_slot_no); -extern int cfg_page_format(struct cfg_page_desc_t *cpd, int cfg_slot_no, int slotno); -extern struct cfg_page_desc_t cfgpage; +} cfg_page_desc_t; + +extern int cfg_page_init(cfg_page_desc_t *cpd); +extern int cfg_page_validate(cfg_page_desc_t *cpd, int cfg_slot_no); +extern int cfg_page_format(cfg_page_desc_t *cpd, int cfg_slot_no, int slotno); +extern int cfg_page_print(cfg_page_desc_t *cpd); +extern int cfg_page_init_reader(cfg_page_desc_t *cpd, + unsigned char *cfg_page_buffer, size_t cfg_page_size, + nanocbor_value_t *cfg_page_reader); +extern cfg_page_desc_t cfgpage; #ifdef __cplusplus } diff --git a/tests/driver_cfg_page/main.c b/tests/driver_cfg_page/main.c index 91c8cc991d38..cabf41c3e935 100644 --- a/tests/driver_cfg_page/main.c +++ b/tests/driver_cfg_page/main.c @@ -25,11 +25,10 @@ #include "board.h" #include "cfg_page.h" -//static char cfg_page_temp[MTD_PAGE_SIZE]; - int main(void) { puts("CFG-PAGE test application starting..."); - cfg_page_init(&cfgpage); + cfg_page_print(&cfgpage); + } From 23495ee97db1a4d5e89399a5dcfc1e316d198779 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 20 Oct 2021 14:29:09 -0400 Subject: [PATCH 08/43] test case exits when done to permit shell script driven tests --- tests/driver_cfg_page/main.c | 3 +++ tests/driver_cfg_page/maketest1 | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100755 tests/driver_cfg_page/maketest1 diff --git a/tests/driver_cfg_page/main.c b/tests/driver_cfg_page/main.c index cabf41c3e935..f60be63181e4 100644 --- a/tests/driver_cfg_page/main.c +++ b/tests/driver_cfg_page/main.c @@ -25,10 +25,13 @@ #include "board.h" #include "cfg_page.h" +#include "native_internal.h" + int main(void) { puts("CFG-PAGE test application starting..."); cfg_page_print(&cfgpage); + real_exit(0); } diff --git a/tests/driver_cfg_page/maketest1 b/tests/driver_cfg_page/maketest1 new file mode 100755 index 000000000000..86502a159f85 --- /dev/null +++ b/tests/driver_cfg_page/maketest1 @@ -0,0 +1,22 @@ +#!/bin/sh + +# d9 d9f8 # tag(55800) +# da 52494f54 # tag(1380536148) +# 43 # bytes(3) +# 424f52 # "BOR" +# 00 # unsigned(0) +# 19 c63b # unsigned(50747) - CRC16 of above. +# bf +# 01 # unsigned(1) +# 65 # text(5) +# 68656C6C6F # "hello" + + +( +echo "d9 d9 f8 da 52 49 4f 54 43 42 4f 52 " | pretty2diag.rb | diag2cbor.rb +echo "00 " | pretty2diag.rb | diag2cbor.rb +echo "19 c6 3b" | pretty2diag.rb | diag2cbor.rb +echo "bf 01 65 68656C6C6F ff" | pretty2diag.rb | diag2cbor.rb +) >TEST1.bin + +cp TEST1.bin CONFIG.bin && bin/native/tests_driver_cfg_page.elf \ No newline at end of file From 4b6ea52df3c1cae0d26fdc2390426339d50d08ba Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 20 Oct 2021 14:51:36 -0400 Subject: [PATCH 09/43] added two more test cases, document test1 --- tests/driver_cfg_page/maketest1 | 5 ++++- tests/driver_cfg_page/maketest2 | 30 ++++++++++++++++++++++++++ tests/driver_cfg_page/maketest3 | 37 +++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100755 tests/driver_cfg_page/maketest2 create mode 100755 tests/driver_cfg_page/maketest3 diff --git a/tests/driver_cfg_page/maketest1 b/tests/driver_cfg_page/maketest1 index 86502a159f85..04f87c1607ae 100755 --- a/tests/driver_cfg_page/maketest1 +++ b/tests/driver_cfg_page/maketest1 @@ -1,5 +1,8 @@ #!/bin/sh +# this test case is the most basic contents of "cfg_page" nvram. +# it has a single key (1) with value "hello" + # d9 d9f8 # tag(55800) # da 52494f54 # tag(1380536148) # 43 # bytes(3) @@ -19,4 +22,4 @@ echo "19 c6 3b" | pretty2diag.rb | diag2cbor.rb echo "bf 01 65 68656C6C6F ff" | pretty2diag.rb | diag2cbor.rb ) >TEST1.bin -cp TEST1.bin CONFIG.bin && bin/native/tests_driver_cfg_page.elf \ No newline at end of file +cp TEST1.bin CONFIG.bin && bin/native/tests_driver_cfg_page.elf diff --git a/tests/driver_cfg_page/maketest2 b/tests/driver_cfg_page/maketest2 new file mode 100755 index 000000000000..62ea5cf29722 --- /dev/null +++ b/tests/driver_cfg_page/maketest2 @@ -0,0 +1,30 @@ +#!/bin/sh + +# this test case has a slightly more complex content, where the first +# key (2) has a complex (array) value, which must be skipped and then +# key (1) with value "hello" + +# d9 d9f8 # tag(55800) +# da 52494f54 # tag(1380536148) +# 43 # bytes(3) +# 424f52 # "BOR" +# 00 # unsigned(0) +# 19 c63b # unsigned(50747) - CRC16 of above. +# bf +# 02 +# 82 # array(2) +# 01 # unsigned(1) +# 02 # unsigned(2) +# 01 # unsigned(1) +# 65 # text(5) +# 68656C6C6F # "hello" + + +( +echo "d9 d9 f8 da 52 49 4f 54 43 42 4f 52 " | pretty2cbor.rb +echo "00 " | pretty2cbor.rb +echo "19 c6 3b" | pretty2cbor.rb +(echo "bf "; echo "02 82 01 02 "; echo "01 65 68656C6C6F"; echo "ff") | pretty2cbor.rb +) >TEST2.bin + +cp TEST2.bin CONFIG.bin && bin/native/tests_driver_cfg_page.elf diff --git a/tests/driver_cfg_page/maketest3 b/tests/driver_cfg_page/maketest3 new file mode 100755 index 000000000000..0aa03fd944b3 --- /dev/null +++ b/tests/driver_cfg_page/maketest3 @@ -0,0 +1,37 @@ +#!/bin/sh + +# this test has a valid contents at slot 0, +# but has contents at slot 1 with a higher serial no. + +# d9 d9f8 # tag(55800) +# da 52494f54 # tag(1380536148) +# 43 # bytes(3) +# 424f52 # "BOR" +# 00 # unsigned(0) +# 19 c63b # unsigned(50747) - CRC16 of above. +# bf +# 02 +# 82 # array(2) +# 01 # unsigned(1) +# 02 # unsigned(2) +# 01 # unsigned(1) +# 65 # text(5) +# 68656C6C6F # "hello" + +echo -n >TEST3.bin + +( +echo "d9 d9 f8 da 52 49 4f 54 43 42 4f 52 " | pretty2cbor.rb +echo "00 " | pretty2cbor.rb +echo "19 c6 3b" | pretty2cbor.rb +(echo "bf "; echo "02 82 01 02 "; echo "01 65 68656C6C6F"; echo "ff") | pretty2cbor.rb +) | dd of=TEST3.bin bs=1 seek=0 status=none + +( +echo "d9 d9 f8 da 52 49 4f 54 43 42 4f 52 " | pretty2cbor.rb +echo "01 " | pretty2cbor.rb +echo "19 d6 1a" | pretty2cbor.rb +(echo "bf "; echo "02 82 04 05 "; echo "01 65 63 72 65 61 6d"; echo "ff") | pretty2cbor.rb +) | dd of=TEST3.bin bs=1 seek=4096 status=none + +cp TEST3.bin CONFIG.bin && bin/native/tests_driver_cfg_page.elf From d308f5df807ea795496d19c6bd7c5dc7ed5f4f81 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 20 Oct 2021 15:03:12 -0400 Subject: [PATCH 10/43] re-intend with RIOT style: bsd w/4-spaces --- drivers/cfg_page/cfg_page.c | 274 +++++++++++++++--------------- drivers/cfg_page/cfg_page_print.c | 78 ++++----- 2 files changed, 175 insertions(+), 177 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index dad802ddc8db..8483d24624a7 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -54,167 +54,167 @@ int _calculate_slot_offset(unsigned int cfg_slot_no) { - int byte_offset = 0; - - if(cfg_slot_no == 0) { - byte_offset = 0; - } else if(cfg_slot_no == 1) { - byte_offset = MTD_SECTOR_SIZE; - } else { - return -1; - } - return byte_offset; + int byte_offset = 0; + + if(cfg_slot_no == 0) { + byte_offset = 0; + } else if(cfg_slot_no == 1) { + byte_offset = MTD_SECTOR_SIZE; + } else { + return -1; + } + return byte_offset; } int cfg_page_validate(cfg_page_desc_t *cpd, int cfg_slot_no) { - unsigned char header_buffer[CFG_PAGE_HEADER_SIZE]; - nanocbor_value_t decoder; - uint32_t tagval = 0x12345678; - uint16_t checksum = 0; - int8_t serialno = 0; - const uint8_t *bytes = NULL; - size_t bytes_len; - unsigned int byte_offset = 0; - - if(cfg_slot_no == 0) { - byte_offset = 0; - } else if(cfg_slot_no == 1) { - byte_offset = MTD_SECTOR_SIZE; - } else { - return -1; - } - - /* read things in a specific block in first */ - if(mtd_read(cpd->dev, header_buffer, byte_offset, CFG_PAGE_HEADER_SIZE) != 0) { - DEBUG("read failed\n"); - return -1; - } - - //od_hex_dump_ext(header_buffer, CFG_PAGE_HEADER_SIZE, 16, 0); - - /* validate the checksum */ - nanocbor_decoder_init(&decoder, header_buffer, CFG_PAGE_HEADER_SIZE); - - /* pull in the tags */ - if(nanocbor_get_tag(&decoder, &tagval) != NANOCBOR_OK) { - return -1; - } - - if(tagval != CBOR_SEQ_TAG) { - return -2; - } - - if(nanocbor_get_tag(&decoder, &tagval) != NANOCBOR_OK) { - return -3; - } - - if(tagval != CFG_PAGE_RIOT_TAG) { - return -4; - } - - if(nanocbor_get_bstr(&decoder, &bytes, &bytes_len) != NANOCBOR_OK - || bytes_len != 3 - || bytes[0]!= 'B' - || bytes[1]!= 'O' - || bytes[2]!= 'R') { - return -5; - } - - if(nanocbor_get_int8(&decoder, &serialno) < NANOCBOR_OK) { - return -6; - } - - /* calculate a 16-bit checksum across the bytes so far */ - uint16_t calculated = crc16_ccitt_calc(header_buffer, (decoder.cur - header_buffer)); - - if(nanocbor_get_uint16(&decoder, &checksum) < NANOCBOR_OK) { - return -7; - } - - if(calculated != checksum) { - return -8; - } - - /* Good News Everyone! */ - return serialno; + unsigned char header_buffer[CFG_PAGE_HEADER_SIZE]; + nanocbor_value_t decoder; + uint32_t tagval = 0x12345678; + uint16_t checksum = 0; + int8_t serialno = 0; + const uint8_t *bytes = NULL; + size_t bytes_len; + unsigned int byte_offset = 0; + + if(cfg_slot_no == 0) { + byte_offset = 0; + } else if(cfg_slot_no == 1) { + byte_offset = MTD_SECTOR_SIZE; + } else { + return -1; + } + + /* read things in a specific block in first */ + if(mtd_read(cpd->dev, header_buffer, byte_offset, CFG_PAGE_HEADER_SIZE) != 0) { + DEBUG("read failed\n"); + return -1; + } + + //od_hex_dump_ext(header_buffer, CFG_PAGE_HEADER_SIZE, 16, 0); + + /* validate the checksum */ + nanocbor_decoder_init(&decoder, header_buffer, CFG_PAGE_HEADER_SIZE); + + /* pull in the tags */ + if(nanocbor_get_tag(&decoder, &tagval) != NANOCBOR_OK) { + return -1; + } + + if(tagval != CBOR_SEQ_TAG) { + return -2; + } + + if(nanocbor_get_tag(&decoder, &tagval) != NANOCBOR_OK) { + return -3; + } + + if(tagval != CFG_PAGE_RIOT_TAG) { + return -4; + } + + if(nanocbor_get_bstr(&decoder, &bytes, &bytes_len) != NANOCBOR_OK + || bytes_len != 3 + || bytes[0]!= 'B' + || bytes[1]!= 'O' + || bytes[2]!= 'R') { + return -5; + } + + if(nanocbor_get_int8(&decoder, &serialno) < NANOCBOR_OK) { + return -6; + } + + /* calculate a 16-bit checksum across the bytes so far */ + uint16_t calculated = crc16_ccitt_calc(header_buffer, (decoder.cur - header_buffer)); + + if(nanocbor_get_uint16(&decoder, &checksum) < NANOCBOR_OK) { + return -7; + } + + if(calculated != checksum) { + return -8; + } + + /* Good News Everyone! */ + return serialno; } int cfg_page_format(cfg_page_desc_t *cpd, int cfg_slot_no, int serialno) { - unsigned char header_buffer[CFG_PAGE_HEADER_SIZE+2]; - nanocbor_encoder_t encoder; - unsigned int write_size=CFG_PAGE_HEADER_SIZE+2; + unsigned char header_buffer[CFG_PAGE_HEADER_SIZE+2]; + nanocbor_encoder_t encoder; + unsigned int write_size=CFG_PAGE_HEADER_SIZE+2; - nanocbor_encoder_init(&encoder, header_buffer, write_size); + nanocbor_encoder_init(&encoder, header_buffer, write_size); - if(nanocbor_fmt_tag(&encoder, CBOR_SEQ_TAG) < 0) { - return -1; - } + if(nanocbor_fmt_tag(&encoder, CBOR_SEQ_TAG) < 0) { + return -1; + } - if(nanocbor_fmt_tag(&encoder, CFG_PAGE_RIOT_TAG) < 0) { - return -1; - } + if(nanocbor_fmt_tag(&encoder, CFG_PAGE_RIOT_TAG) < 0) { + return -1; + } - if(nanocbor_put_bstr(&encoder, (unsigned const char *)"BOR", 3) < 0) { - return -1; - } + if(nanocbor_put_bstr(&encoder, (unsigned const char *)"BOR", 3) < 0) { + return -1; + } - if(nanocbor_fmt_uint(&encoder, serialno) < NANOCBOR_OK) { - return -6; - } + if(nanocbor_fmt_uint(&encoder, serialno) < NANOCBOR_OK) { + return -6; + } - /* now calculate the CRC */ - /* calculate a 16-bit checksum across the bytes so far */ - uint16_t calculated = crc16_ccitt_calc(header_buffer, (encoder.cur - header_buffer)); + /* now calculate the CRC */ + /* calculate a 16-bit checksum across the bytes so far */ + uint16_t calculated = crc16_ccitt_calc(header_buffer, (encoder.cur - header_buffer)); - if(nanocbor_fmt_uint(&encoder, calculated) < NANOCBOR_OK) { - return -7; - } + if(nanocbor_fmt_uint(&encoder, calculated) < NANOCBOR_OK) { + return -7; + } - /* now initialize an indefinite map, and stop code */ - if(nanocbor_fmt_map_indefinite(&encoder) < 0) { - return -8; - } - if(nanocbor_fmt_end_indefinite(&encoder) < 0) { - return -9; - } + /* now initialize an indefinite map, and stop code */ + if(nanocbor_fmt_map_indefinite(&encoder) < 0) { + return -8; + } + if(nanocbor_fmt_end_indefinite(&encoder) < 0) { + return -9; + } - unsigned int byte_offset = _calculate_slot_offset(cfg_slot_no); + unsigned int byte_offset = _calculate_slot_offset(cfg_slot_no); - /* read things in a specific block in first */ - DEBUG("writing %d bytes to slot_no: %d, at offset: %u\n", write_size, - cfg_slot_no, byte_offset); + /* read things in a specific block in first */ + DEBUG("writing %d bytes to slot_no: %d, at offset: %u\n", write_size, + cfg_slot_no, byte_offset); - od_hex_dump_ext(header_buffer, write_size, 16, 0); + od_hex_dump_ext(header_buffer, write_size, 16, 0); - int error = 0; - if((error = mtd_write(cpd->dev, header_buffer, byte_offset, write_size)) != NANOCBOR_OK) { - DEBUG("write failed: %d\n", error); - return -11; - } + int error = 0; + if((error = mtd_write(cpd->dev, header_buffer, byte_offset, write_size)) != NANOCBOR_OK) { + DEBUG("write failed: %d\n", error); + return -11; + } - DEBUG("formatted slot %u\n", cfg_slot_no); - return 0; + DEBUG("formatted slot %u\n", cfg_slot_no); + return 0; } int cfg_page_init_reader(cfg_page_desc_t *cpd, unsigned char *cfg_page_buffer, size_t cfg_page_size, nanocbor_value_t *cfg_page_reader) { - unsigned int byte_offset = _calculate_slot_offset(cpd->active_page); + unsigned int byte_offset = _calculate_slot_offset(cpd->active_page); - /* read in the whole page */ - if(mtd_read(cpd->dev, cfg_page_buffer, byte_offset, cfg_page_size) != 0) { - DEBUG("read failed\n"); - return -1; - } + /* read in the whole page */ + if(mtd_read(cpd->dev, cfg_page_buffer, byte_offset, cfg_page_size) != 0) { + DEBUG("read failed\n"); + return -1; + } - nanocbor_decoder_init(cfg_page_reader, cfg_page_buffer+CFG_PAGE_HEADER_SIZE, - cfg_page_size - CFG_PAGE_HEADER_SIZE); + nanocbor_decoder_init(cfg_page_reader, cfg_page_buffer+CFG_PAGE_HEADER_SIZE, + cfg_page_size - CFG_PAGE_HEADER_SIZE); - return 0; + return 0; } int cfg_page_init(cfg_page_desc_t *cpd) @@ -230,16 +230,16 @@ int cfg_page_init(cfg_page_desc_t *cpd) cpd->active_page = 0; if(slot0_serial < 0 && slot1_serial < 0) { - DEBUG("Formatting cfg page %u\n", cpd->active_page); - cfg_page_format(&cfgpage, cpd->active_page, 0); + DEBUG("Formatting cfg page %u\n", cpd->active_page); + cfg_page_format(&cfgpage, cpd->active_page, 0); } else if(slot0_serial < 0 && slot1_serial >= 0) { - cpd->active_page = 1; + cpd->active_page = 1; } else if(slot0_serial >= 0 && slot1_serial < 0) { - cpd->active_page = 0; + cpd->active_page = 0; } else if(slot0_serial >= slot1_serial) { - cpd->active_page = 0; + cpd->active_page = 0; } else { - cpd->active_page = 1; + cpd->active_page = 1; } DEBUG("Using cfg page %u\n", cpd->active_page); @@ -249,8 +249,6 @@ int cfg_page_init(cfg_page_desc_t *cpd) * active page */ - - return 0; } diff --git a/drivers/cfg_page/cfg_page_print.c b/drivers/cfg_page/cfg_page_print.c index a6419806992c..33ab796ce82d 100644 --- a/drivers/cfg_page/cfg_page_print.c +++ b/drivers/cfg_page/cfg_page_print.c @@ -35,52 +35,52 @@ int cfg_page_print(cfg_page_desc_t *cpd) { - static unsigned char cfg_page_temp[MTD_PAGE_SIZE]; - nanocbor_value_t reader; - nanocbor_value_t values; + static unsigned char cfg_page_temp[MTD_PAGE_SIZE]; + nanocbor_value_t reader; + nanocbor_value_t values; - if(cfg_page_init_reader(cpd, cfg_page_temp, sizeof(cfg_page_temp), &reader) < 0) { - return -1; - } - - if(nanocbor_get_type(&reader) != NANOCBOR_TYPE_MAP || - nanocbor_enter_map(&reader, &values) != NANOCBOR_OK) { - return -2; - } + if(cfg_page_init_reader(cpd, cfg_page_temp, sizeof(cfg_page_temp), &reader) < 0) { + return -1; + } - while(!nanocbor_at_end(&values)) { - uint32_t key; - unsigned int type; - const uint8_t *str = NULL; - size_t len; - if(nanocbor_get_uint32(&values, &key) < 0) { - DEBUG("non interger key value found: %d", nanocbor_get_type(&values)); - return -3; + if(nanocbor_get_type(&reader) != NANOCBOR_TYPE_MAP || + nanocbor_enter_map(&reader, &values) != NANOCBOR_OK) { + return -2; } - type = nanocbor_get_type(&values); - printf("key: %u[type=%u]\n", key, type); - switch(type) { - case NANOCBOR_TYPE_BSTR: - if(nanocbor_get_bstr(&values, &str, &len) == NANOCBOR_OK) { - od_hex_dump_ext(str, len, 16, 0); - } - break; + while(!nanocbor_at_end(&values)) { + uint32_t key; + unsigned int type; + const uint8_t *str = NULL; + size_t len; + if(nanocbor_get_uint32(&values, &key) < 0) { + DEBUG("non interger key value found: %d", nanocbor_get_type(&values)); + return -3; + } - case NANOCBOR_TYPE_TSTR: - if(nanocbor_get_tstr(&values, &str, &len) == NANOCBOR_OK) { - /* XXX print as bounded string? */ - //od_hex_dump_ext(str, len, 16, 0); - printf(" value: %.*s\n", len, str); - } - break; + type = nanocbor_get_type(&values); + printf("key: %u[type=%u]\n", key, type); + switch(type) { + case NANOCBOR_TYPE_BSTR: + if(nanocbor_get_bstr(&values, &str, &len) == NANOCBOR_OK) { + od_hex_dump_ext(str, len, 16, 0); + } + break; - default: - nanocbor_skip(&values); - } + case NANOCBOR_TYPE_TSTR: + if(nanocbor_get_tstr(&values, &str, &len) == NANOCBOR_OK) { + /* XXX print as bounded string? */ + //od_hex_dump_ext(str, len, 16, 0); + printf(" value: %.*s\n", len, str); + } + break; - } + default: + nanocbor_skip(&values); + } + + } - return 0; + return 0; } From ff74bc7251b1b7f96f39883fe8280b2f852fe3eb Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 20 Oct 2021 15:03:31 -0400 Subject: [PATCH 11/43] added debug of crc value --- drivers/cfg_page/cfg_page.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 8483d24624a7..6d41a3a49a1c 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -134,6 +134,7 @@ int cfg_page_validate(cfg_page_desc_t *cpd, int cfg_slot_no) } if(calculated != checksum) { + DEBUG("slot:%d expected %04x got %04x\n", cfg_slot_no, calculated, checksum); return -8; } From 002a34d5ee07e25587e81bf2301304b4aa6ed8ff Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 20 Oct 2021 15:36:52 -0400 Subject: [PATCH 12/43] when initializing, make sure entire page is erased --- drivers/cfg_page/cfg_page.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 6d41a3a49a1c..637cf30e3cf5 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -188,9 +188,14 @@ int cfg_page_format(cfg_page_desc_t *cpd, int cfg_slot_no, int serialno) DEBUG("writing %d bytes to slot_no: %d, at offset: %u\n", write_size, cfg_slot_no, byte_offset); - od_hex_dump_ext(header_buffer, write_size, 16, 0); + //od_hex_dump_ext(header_buffer, write_size, 16, 0); int error = 0; + /* erase the entire page */ + if(mtd_erase(cpd->dev, byte_offset, MTD_PAGE_SIZE) != 0) { + DEBUG("erase failed\n"); + return -10; + } if((error = mtd_write(cpd->dev, header_buffer, byte_offset, write_size)) != NANOCBOR_OK) { DEBUG("write failed: %d\n", error); return -11; From aecaffdc50a732731f4f5f7fba02b2ab1197a59a Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 20 Oct 2021 16:22:54 -0400 Subject: [PATCH 13/43] prepare the flash file better: initialize to 0xff, and create proper sized file --- tests/driver_cfg_page/maketest3 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/driver_cfg_page/maketest3 b/tests/driver_cfg_page/maketest3 index 0aa03fd944b3..2fb5017663f2 100755 --- a/tests/driver_cfg_page/maketest3 +++ b/tests/driver_cfg_page/maketest3 @@ -18,20 +18,22 @@ # 65 # text(5) # 68656C6C6F # "hello" -echo -n >TEST3.bin +ruby -e 'print "\xff" * 8192;' >TEST3.bin ( echo "d9 d9 f8 da 52 49 4f 54 43 42 4f 52 " | pretty2cbor.rb echo "00 " | pretty2cbor.rb +# CRC echo "19 c6 3b" | pretty2cbor.rb (echo "bf "; echo "02 82 01 02 "; echo "01 65 68656C6C6F"; echo "ff") | pretty2cbor.rb -) | dd of=TEST3.bin bs=1 seek=0 status=none +) | dd of=TEST3.bin bs=1 seek=0 conv=notrunc status=none ( echo "d9 d9 f8 da 52 49 4f 54 43 42 4f 52 " | pretty2cbor.rb echo "01 " | pretty2cbor.rb +# CRC echo "19 d6 1a" | pretty2cbor.rb (echo "bf "; echo "02 82 04 05 "; echo "01 65 63 72 65 61 6d"; echo "ff") | pretty2cbor.rb -) | dd of=TEST3.bin bs=1 seek=4096 status=none +) | dd of=TEST3.bin bs=1 seek=4096 conv=notrunc status=none cp TEST3.bin CONFIG.bin && bin/native/tests_driver_cfg_page.elf From 49650f860912321b13451192b64a8bdd14603115 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 20 Oct 2021 16:50:07 -0400 Subject: [PATCH 14/43] initialize the flash space with 0xff properly --- tests/driver_cfg_page/maketest0 | 10 ++++++++++ tests/driver_cfg_page/maketest1 | 3 ++- tests/driver_cfg_page/maketest2 | 3 ++- 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100755 tests/driver_cfg_page/maketest0 diff --git a/tests/driver_cfg_page/maketest0 b/tests/driver_cfg_page/maketest0 new file mode 100755 index 000000000000..617f14729f16 --- /dev/null +++ b/tests/driver_cfg_page/maketest0 @@ -0,0 +1,10 @@ +#!/bin/sh + +# this test case is shows how a page is initialized if there is no valid signature + +ruby -e 'print "\xff" * 8192;' >CONFIG.bin +# very empty. + +bin/native/tests_driver_cfg_page.elf +cborseq2diag.rb CONFIG.bin + diff --git a/tests/driver_cfg_page/maketest1 b/tests/driver_cfg_page/maketest1 index 04f87c1607ae..ef5ca956a646 100755 --- a/tests/driver_cfg_page/maketest1 +++ b/tests/driver_cfg_page/maketest1 @@ -14,12 +14,13 @@ # 65 # text(5) # 68656C6C6F # "hello" +ruby -e 'print "\xff" * 8192;' >TEST1.bin ( echo "d9 d9 f8 da 52 49 4f 54 43 42 4f 52 " | pretty2diag.rb | diag2cbor.rb echo "00 " | pretty2diag.rb | diag2cbor.rb echo "19 c6 3b" | pretty2diag.rb | diag2cbor.rb echo "bf 01 65 68656C6C6F ff" | pretty2diag.rb | diag2cbor.rb -) >TEST1.bin +) | dd of=TEST1.bin bs=1 seek=0 conv=notrunc status=none cp TEST1.bin CONFIG.bin && bin/native/tests_driver_cfg_page.elf diff --git a/tests/driver_cfg_page/maketest2 b/tests/driver_cfg_page/maketest2 index 62ea5cf29722..a0f528fd610b 100755 --- a/tests/driver_cfg_page/maketest2 +++ b/tests/driver_cfg_page/maketest2 @@ -19,12 +19,13 @@ # 65 # text(5) # 68656C6C6F # "hello" +ruby -e 'print "\xff" * 8192;' >TEST2.bin ( echo "d9 d9 f8 da 52 49 4f 54 43 42 4f 52 " | pretty2cbor.rb echo "00 " | pretty2cbor.rb echo "19 c6 3b" | pretty2cbor.rb (echo "bf "; echo "02 82 01 02 "; echo "01 65 68656C6C6F"; echo "ff") | pretty2cbor.rb -) >TEST2.bin +) | dd of=TEST2.bin bs=1 seek=0 conv=notrunc status=none cp TEST2.bin CONFIG.bin && bin/native/tests_driver_cfg_page.elf From 1b76133ab549f3df38cd2c8dc7eb5b7f066efcfc Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 20 Oct 2021 17:14:31 -0400 Subject: [PATCH 15/43] cfg_page: coded cfg_page_get_value that returns _last_ key from map --- drivers/cfg_page/cfg_page.c | 45 ++++++++++++++++++++++++++++++--- drivers/include/cfg_page.h | 4 +++ tests/driver_cfg_page/main.c | 8 ++++++ tests/driver_cfg_page/maketest4 | 42 ++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 3 deletions(-) create mode 100755 tests/driver_cfg_page/maketest4 diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 637cf30e3cf5..45c12017b5e3 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -192,11 +192,11 @@ int cfg_page_format(cfg_page_desc_t *cpd, int cfg_slot_no, int serialno) int error = 0; /* erase the entire page */ - if(mtd_erase(cpd->dev, byte_offset, MTD_PAGE_SIZE) != 0) { - DEBUG("erase failed\n"); + if((error = mtd_erase(cpd->dev, byte_offset, MTD_SECTOR_SIZE)) != 0) { + DEBUG("erase failed: %d\n\n", error); return -10; } - if((error = mtd_write(cpd->dev, header_buffer, byte_offset, write_size)) != NANOCBOR_OK) { + if((error = mtd_write(cpd->dev, header_buffer, byte_offset, write_size)) != 0) { DEBUG("write failed: %d\n", error); return -11; } @@ -223,6 +223,45 @@ int cfg_page_init_reader(cfg_page_desc_t *cpd, return 0; } +static unsigned char cfg_page_active_buffer[MTD_PAGE_SIZE]; +int cfg_page_get_value(cfg_page_desc_t *cpd, uint32_t wantedkey, nanocbor_value_t *valuereader) +{ + nanocbor_value_t reader; + nanocbor_value_t values; + int ret = 0; + + if(cfg_page_init_reader(cpd, cfg_page_active_buffer, sizeof(cfg_page_active_buffer), &reader) < 0) { + return -1; + } + + if(nanocbor_get_type(&reader) != NANOCBOR_TYPE_MAP || + nanocbor_enter_map(&reader, &values) != NANOCBOR_OK) { + return -2; + } + + while(!nanocbor_at_end(&values)) { + uint32_t key = 0; + if(nanocbor_get_uint32(&values, &key) < 0) { + DEBUG("non interger key value found: %d", nanocbor_get_type(&values)); + return -3; + } + + if(key == wantedkey) { + /* found a key, but might not be last one */ + if(valuereader) { + /* make copy of reader so that caller can read out value */ + *valuereader = values; + ret = 1; + } + } + + /* skip the map value */ + nanocbor_skip(&values); + } + return ret; +} + + int cfg_page_init(cfg_page_desc_t *cpd) { DEBUG("cfg_page: init\n"); diff --git a/drivers/include/cfg_page.h b/drivers/include/cfg_page.h index 6ae4d14734aa..dd274d3ed562 100644 --- a/drivers/include/cfg_page.h +++ b/drivers/include/cfg_page.h @@ -35,6 +35,7 @@ extern "C" { typedef struct cfg_page_desc { mtd_dev_t *dev; nanocbor_encoder_t writer; + nanocbor_value_t reader; uint8_t active_page; /* 0 or 1 */ } cfg_page_desc_t; @@ -45,6 +46,9 @@ extern int cfg_page_print(cfg_page_desc_t *cpd); extern int cfg_page_init_reader(cfg_page_desc_t *cpd, unsigned char *cfg_page_buffer, size_t cfg_page_size, nanocbor_value_t *cfg_page_reader); +extern int cfg_page_get_value(cfg_page_desc_t *cpd, + uint32_t wantedkey, + nanocbor_value_t *valuereader); extern cfg_page_desc_t cfgpage; #ifdef __cplusplus diff --git a/tests/driver_cfg_page/main.c b/tests/driver_cfg_page/main.c index f60be63181e4..365a9ded58d2 100644 --- a/tests/driver_cfg_page/main.c +++ b/tests/driver_cfg_page/main.c @@ -29,8 +29,16 @@ int main(void) { + nanocbor_value_t valuereader; + const uint8_t *strvalue; + size_t strlen; puts("CFG-PAGE test application starting..."); + if(cfg_page_get_value(&cfgpage, 1, &valuereader) == 1 && + nanocbor_get_tstr(&valuereader, &strvalue, &strlen) == NANOCBOR_OK) { + printf("key: 1 found value: %.*s\n", strlen, strvalue); + } + cfg_page_print(&cfgpage); real_exit(0); diff --git a/tests/driver_cfg_page/maketest4 b/tests/driver_cfg_page/maketest4 new file mode 100755 index 000000000000..4a0fd70f7fda --- /dev/null +++ b/tests/driver_cfg_page/maketest4 @@ -0,0 +1,42 @@ +#!/bin/sh + +# this test has a valid contents at slot 0, +# but has contents at slot 1 with a higher serial no. + +# d9 d9f8 # tag(55800) +# da 52494f54 # tag(1380536148) +# 43 # bytes(3) +# 424f52 # "BOR" +# 00 # unsigned(0) +# 19 c63b # unsigned(50747) - CRC16 of above. +# bf +# 02 +# 82 # array(2) +# 01 # unsigned(1) +# 02 # unsigned(2) +# 01 # unsigned(1) +# 65 # text(5) +# 68656C6C6F # "hello" + +ruby -e 'print "\xff" * 8192;' >TEST3.bin + +( +echo "d9 d9 f8 da 52 49 4f 54 43 42 4f 52 " | pretty2cbor.rb +echo "00 " | pretty2cbor.rb +# CRC +echo "19 c6 3b" | pretty2cbor.rb +(echo "bf "; echo "02 82 01 02 "; echo "01 65 68656C6C6F"; echo "ff") | pretty2cbor.rb +) | dd of=TEST3.bin bs=1 seek=0 conv=notrunc status=none + +( +echo "d9 d9 f8 da 52 49 4f 54 43 42 4f 52 " | pretty2cbor.rb +echo "01 " | pretty2cbor.rb +# CRC +echo "19 d6 1a" | pretty2cbor.rb +(echo "bf "; echo "02 82 04 05 "; + echo "01 65 63 72 65 61 6d"; + echo "01 66 62 75 74 74 65 72"; + echo "ff") | pretty2cbor.rb +) | dd of=TEST3.bin bs=1 seek=4096 conv=notrunc status=none + +cp TEST3.bin CONFIG.bin && bin/native/tests_driver_cfg_page.elf From c1f302c32467bd77d7c12c46494ff8dcec94fdf5 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 20 Oct 2021 19:41:22 -0400 Subject: [PATCH 16/43] cfg_page: added cfg_page_set_str_value writer function and test --- drivers/cfg_page/cfg_page.c | 95 +++++++++++++++++++++++++++++++++++- drivers/include/cfg_page.h | 4 ++ tests/driver_cfg_page/main.c | 6 +++ 3 files changed, 104 insertions(+), 1 deletion(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 45c12017b5e3..0d06e014ef51 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -223,7 +223,7 @@ int cfg_page_init_reader(cfg_page_desc_t *cpd, return 0; } -static unsigned char cfg_page_active_buffer[MTD_PAGE_SIZE]; +static unsigned char cfg_page_active_buffer[MTD_SECTOR_SIZE]; int cfg_page_get_value(cfg_page_desc_t *cpd, uint32_t wantedkey, nanocbor_value_t *valuereader) { nanocbor_value_t reader; @@ -261,6 +261,99 @@ int cfg_page_get_value(cfg_page_desc_t *cpd, uint32_t wantedkey, nanocbor_value_ return ret; } +/* this one is a doozy! */ +static int cfg_page_swap_slotno(cfg_page_desc_t *cpd, nanocbor_value_t *reader) +{ + (void)cpd; + (void)reader; + printf("swap\n"); + return -1; +} + +int cfg_page_init_writer(cfg_page_desc_t *cpd, + nanocbor_encoder_t **writer, + uint8_t **begin, + size_t valuelen) +{ + nanocbor_value_t reader; + nanocbor_value_t values; + + /* start by bringin in the reader */ + if(cfg_page_init_reader(cpd, cfg_page_active_buffer, sizeof(cfg_page_active_buffer), &reader) < 0) { + return -1; + } + + if(nanocbor_get_type(&reader) != NANOCBOR_TYPE_MAP || + nanocbor_enter_map(&reader, &values) != NANOCBOR_OK) { + return -2; + } + + while(!nanocbor_at_end(&values)) { + nanocbor_skip(&values); /* key */ + nanocbor_skip(&values); /* value */ + } + nanocbor_leave_container(&reader, &values); + + /* we are now located at end of space */ + /* calculate how much space is left */ + size_t amountleft = reader.end - reader.cur; + if(valuelen > amountleft) { + /* move all values to other page and switch over there */ + cfg_page_swap_slotno(cpd, &reader); + DEBUG("swap slotno\n"); + } + + size_t writeoffset = (reader.cur-cfg_page_active_buffer); + DEBUG("found end of old values at: %u, amountleft=%u\n", + writeoffset, amountleft); + + /* initialize the writer at this location */ + if(writer) { + /* recalculate where ot write without screwing with const pointer */ + uint8_t *writehere = cfg_page_active_buffer + writeoffset; + if(begin) { + *begin = writehere; + } + nanocbor_encoder_init(*writer, writehere, amountleft); + } + return 0; +} + +int cfg_page_finish_writer(cfg_page_desc_t *cpd, + const uint8_t *writebegin, + nanocbor_encoder_t *writer) +{ + int error; + unsigned int byte_offset = _calculate_slot_offset(cpd->active_page); + + byte_offset += (writebegin - cfg_page_active_buffer); + + if((error = mtd_write(cpd->dev, writebegin, byte_offset, writer->len)) != 0) { + DEBUG("finish write failed: %d\n", error); + return -11; + } + return 0; +} + +int cfg_page_set_str_value(cfg_page_desc_t *cpd, uint32_t newkey, const uint8_t *strvalue, size_t strlen) +{ + nanocbor_encoder_t *writer; + uint8_t *begin; + + if(cfg_page_init_writer(cpd, &writer, &begin, strlen+2) < 0) { + return -1; + } + + nanocbor_fmt_uint(writer, newkey); + nanocbor_put_tstrn(writer, (const char *)strvalue, strlen); + + if(cfg_page_finish_writer(cpd, begin, writer) < 0) { + return -2; + } + + return 0; +} + int cfg_page_init(cfg_page_desc_t *cpd) { diff --git a/drivers/include/cfg_page.h b/drivers/include/cfg_page.h index dd274d3ed562..c28cd15543f7 100644 --- a/drivers/include/cfg_page.h +++ b/drivers/include/cfg_page.h @@ -49,6 +49,10 @@ extern int cfg_page_init_reader(cfg_page_desc_t *cpd, extern int cfg_page_get_value(cfg_page_desc_t *cpd, uint32_t wantedkey, nanocbor_value_t *valuereader); +extern int cfg_page_set_str_value(cfg_page_desc_t *cpd, + uint32_t newkey, + const uint8_t *strvalue, size_t strlen); + extern cfg_page_desc_t cfgpage; #ifdef __cplusplus diff --git a/tests/driver_cfg_page/main.c b/tests/driver_cfg_page/main.c index 365a9ded58d2..c15685853654 100644 --- a/tests/driver_cfg_page/main.c +++ b/tests/driver_cfg_page/main.c @@ -41,5 +41,11 @@ int main(void) cfg_page_print(&cfgpage); + if(cfg_page_set_str_value(&cfgpage, 1, (const uint8_t *)"bob", 3) != 0) { + printf("set key 1 failed\n"); + } + + cfg_page_print(&cfgpage); + real_exit(0); } From 7b8bff0cc70abbacb2b10e597981986c7b846afc Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Wed, 20 Oct 2021 19:56:29 -0400 Subject: [PATCH 17/43] cfg_page: correctly initialize test data with indefinite map, and then correctly back up one byte before writing. --- drivers/cfg_page/cfg_page.c | 3 ++- tests/driver_cfg_page/maketest1 | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 0d06e014ef51..26764fc4c094 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -303,7 +303,8 @@ int cfg_page_init_writer(cfg_page_desc_t *cpd, DEBUG("swap slotno\n"); } - size_t writeoffset = (reader.cur-cfg_page_active_buffer); + /* -1 to remove 0xff stop code */ + size_t writeoffset = (reader.cur-cfg_page_active_buffer)-1; DEBUG("found end of old values at: %u, amountleft=%u\n", writeoffset, amountleft); diff --git a/tests/driver_cfg_page/maketest1 b/tests/driver_cfg_page/maketest1 index ef5ca956a646..b065df72fb47 100755 --- a/tests/driver_cfg_page/maketest1 +++ b/tests/driver_cfg_page/maketest1 @@ -20,7 +20,7 @@ ruby -e 'print "\xff" * 8192;' >TEST1.bin echo "d9 d9 f8 da 52 49 4f 54 43 42 4f 52 " | pretty2diag.rb | diag2cbor.rb echo "00 " | pretty2diag.rb | diag2cbor.rb echo "19 c6 3b" | pretty2diag.rb | diag2cbor.rb -echo "bf 01 65 68656C6C6F ff" | pretty2diag.rb | diag2cbor.rb +echo "bf 01 65 68656C6C6F ff" | pretty2cbor.rb ) | dd of=TEST1.bin bs=1 seek=0 conv=notrunc status=none cp TEST1.bin CONFIG.bin && bin/native/tests_driver_cfg_page.elf From b2fa52c590d05adc5352d57981a5a1937135bcd8 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Thu, 21 Oct 2021 16:19:15 -0400 Subject: [PATCH 18/43] cfg_page: when writing, take care to split up the writes when they cross the boundary between sectors --- drivers/cfg_page/cfg_page.c | 24 +++++++++++++++++++++--- tests/driver_cfg_page/main.c | 7 +++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 26764fc4c094..84ecdbcfa3e0 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -326,13 +326,31 @@ int cfg_page_finish_writer(cfg_page_desc_t *cpd, { int error; unsigned int byte_offset = _calculate_slot_offset(cpd->active_page); + int lefttowrite = writer->cur - writebegin; + if(lefttowrite < 0) { + DEBUG("can not write %d bytes\n", lefttowrite); + return -12; + } byte_offset += (writebegin - cfg_page_active_buffer); - if((error = mtd_write(cpd->dev, writebegin, byte_offset, writer->len)) != 0) { - DEBUG("finish write failed: %d\n", error); - return -11; + while(lefttowrite > 0) { + size_t spot_on_page = (byte_offset % cpd->dev->page_size); + int left_on_page = cpd->dev->page_size - spot_on_page; + if(left_on_page > lefttowrite) { + left_on_page = lefttowrite; + } + + if(0) DEBUG("writing %u of %u bytes to offset: %u\n", left_on_page, lefttowrite, byte_offset); + if((error = mtd_write(cpd->dev, writebegin, byte_offset, left_on_page)) != 0) { + DEBUG("lefttowrite: %u finish write failed: %d\n", lefttowrite, error); + return -11; + } + lefttowrite -= left_on_page; + writebegin += left_on_page; + byte_offset += left_on_page; } + return 0; } diff --git a/tests/driver_cfg_page/main.c b/tests/driver_cfg_page/main.c index c15685853654..17852d9b90d9 100644 --- a/tests/driver_cfg_page/main.c +++ b/tests/driver_cfg_page/main.c @@ -32,6 +32,7 @@ int main(void) nanocbor_value_t valuereader; const uint8_t *strvalue; size_t strlen; + int i; puts("CFG-PAGE test application starting..."); if(cfg_page_get_value(&cfgpage, 1, &valuereader) == 1 && @@ -41,8 +42,10 @@ int main(void) cfg_page_print(&cfgpage); - if(cfg_page_set_str_value(&cfgpage, 1, (const uint8_t *)"bob", 3) != 0) { - printf("set key 1 failed\n"); + for(i=0; i<2048; i++) { + if(cfg_page_set_str_value(&cfgpage, 1, (const uint8_t *)"bob", 3) != 0) { + printf("set key 1 failed\n"); + } } cfg_page_print(&cfgpage); From 79bd61d81e06c020bd84268e018f40e5ef6e8acc Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 22 Oct 2021 11:56:28 -0400 Subject: [PATCH 19/43] cfg_page: added documentation on how cfg_page_swap_slotno is supposed to work --- drivers/cfg_page/cfg_page.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 84ecdbcfa3e0..4e5ccc345982 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -261,7 +261,23 @@ int cfg_page_get_value(cfg_page_desc_t *cpd, uint32_t wantedkey, nanocbor_value_ return ret; } -/* this one is a doozy! */ +/* + * process through all the attributes in the filled current space, + * copying the last value for each key into the new space. + * + * This is done by going through the old space looking for keys which + * have not been copied. + * Once a new has been found, it's location is remembered for later. + * The old space is processed looking for the last value, and when that is + * is found, it is copied to the new space. + * While processing the duplicate keys, each one is changed to keyid=0, + * which is not allowed. + * + * After the last value for a given key is found, then the process returns to the + * spot in the old space where the first instance of the current key was found. + * Processing resumes from there, ingoring keyid=0. + * + */ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd, nanocbor_value_t *reader) { (void)cpd; From 41e03f194a45290da99771ef2a4eeeee1eaba50e Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 22 Oct 2021 11:57:05 -0400 Subject: [PATCH 20/43] cfg_page: initialize the pointers correctly, and also point writer at cpd->writer if null --- drivers/cfg_page/cfg_page.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 4e5ccc345982..4000d6d62754 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -294,11 +294,15 @@ int cfg_page_init_writer(cfg_page_desc_t *cpd, nanocbor_value_t reader; nanocbor_value_t values; - /* start by bringin in the reader */ + /* start by bringin in the content */ + /* XXX could avoid this if we think the content is already loaded */ if(cfg_page_init_reader(cpd, cfg_page_active_buffer, sizeof(cfg_page_active_buffer), &reader) < 0) { return -1; } + /* XXX at this point, if cpd->writer is initialized, can return it immediately */ + /* but premature optimization, and there are caching issues here */ + if(nanocbor_get_type(&reader) != NANOCBOR_TYPE_MAP || nanocbor_enter_map(&reader, &values) != NANOCBOR_OK) { return -2; @@ -324,10 +328,13 @@ int cfg_page_init_writer(cfg_page_desc_t *cpd, DEBUG("found end of old values at: %u, amountleft=%u\n", writeoffset, amountleft); - /* initialize the writer at this location */ + /* initialize the writer at this location, using the writer in cpd->writer */ if(writer) { - /* recalculate where ot write without screwing with const pointer */ + /* recalculate where to write without screwing with const pointer */ uint8_t *writehere = cfg_page_active_buffer + writeoffset; + if(*writer == NULL) { + *writer = &cpd->writer; + } if(begin) { *begin = writehere; } @@ -372,8 +379,8 @@ int cfg_page_finish_writer(cfg_page_desc_t *cpd, int cfg_page_set_str_value(cfg_page_desc_t *cpd, uint32_t newkey, const uint8_t *strvalue, size_t strlen) { - nanocbor_encoder_t *writer; - uint8_t *begin; + nanocbor_encoder_t *writer = NULL; + uint8_t *begin = NULL; if(cfg_page_init_writer(cpd, &writer, &begin, strlen+2) < 0) { return -1; From 44de62ec96bb33f5fed745bd9b8bbe1a0599b520 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 22 Oct 2021 11:57:42 -0400 Subject: [PATCH 21/43] cfg_page: push the contents to just before the 4k page blows up --- tests/driver_cfg_page/main.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/tests/driver_cfg_page/main.c b/tests/driver_cfg_page/main.c index 17852d9b90d9..88a66118dc98 100644 --- a/tests/driver_cfg_page/main.c +++ b/tests/driver_cfg_page/main.c @@ -31,21 +31,31 @@ int main(void) { nanocbor_value_t valuereader; const uint8_t *strvalue; - size_t strlen; + size_t len; int i; puts("CFG-PAGE test application starting..."); if(cfg_page_get_value(&cfgpage, 1, &valuereader) == 1 && - nanocbor_get_tstr(&valuereader, &strvalue, &strlen) == NANOCBOR_OK) { - printf("key: 1 found value: %.*s\n", strlen, strvalue); + nanocbor_get_tstr(&valuereader, &strvalue, &len) == NANOCBOR_OK) { + printf("key: 1 found value: %.*s\n", len, strvalue); } cfg_page_print(&cfgpage); - for(i=0; i<2048; i++) { - if(cfg_page_set_str_value(&cfgpage, 1, (const uint8_t *)"bob", 3) != 0) { + for(i=0; i<127; i++) { + uint8_t buf2[16]; + snprintf((char *)buf2, 16, "bob%04x", i); + if(cfg_page_set_str_value(&cfgpage, 1, buf2, strlen((const char *)buf2)) != 0) { printf("set key 1 failed\n"); } + snprintf((char *)buf2, 16, "frank%04x", i); + if(cfg_page_set_str_value(&cfgpage, 2, buf2, strlen((const char *)buf2)) != 0) { + printf("set key 2 failed\n"); + } + snprintf((char *)buf2, 16, "george%04x", i); + if(cfg_page_set_str_value(&cfgpage, 3, buf2, strlen((const char *)buf2)) != 0) { + printf("set key 3 failed\n"); + } } cfg_page_print(&cfgpage); From e37b034439d773750607e643e83419749a25bf08 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 22 Oct 2021 12:05:20 -0400 Subject: [PATCH 22/43] cfg_page: cfg_page_print reads entire SECTOR rather than only PAGE of data --- drivers/cfg_page/cfg_page_print.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/cfg_page/cfg_page_print.c b/drivers/cfg_page/cfg_page_print.c index 33ab796ce82d..f2ce2494486e 100644 --- a/drivers/cfg_page/cfg_page_print.c +++ b/drivers/cfg_page/cfg_page_print.c @@ -35,7 +35,7 @@ int cfg_page_print(cfg_page_desc_t *cpd) { - static unsigned char cfg_page_temp[MTD_PAGE_SIZE]; + static unsigned char cfg_page_temp[MTD_SECTOR_SIZE]; nanocbor_value_t reader; nanocbor_value_t values; @@ -48,6 +48,8 @@ int cfg_page_print(cfg_page_desc_t *cpd) return -2; } + //printf("buffer is at: %p\n", cfg_page_temp); + while(!nanocbor_at_end(&values)) { uint32_t key; unsigned int type; @@ -59,7 +61,8 @@ int cfg_page_print(cfg_page_desc_t *cpd) } type = nanocbor_get_type(&values); - printf("key: %u[type=%u]\n", key, type); + printf("key: %02u[type=%02u] where=%p:%d ", key, type, values.cur, + values.cur-cfg_page_temp); switch(type) { case NANOCBOR_TYPE_BSTR: if(nanocbor_get_bstr(&values, &str, &len) == NANOCBOR_OK) { @@ -71,12 +74,13 @@ int cfg_page_print(cfg_page_desc_t *cpd) if(nanocbor_get_tstr(&values, &str, &len) == NANOCBOR_OK) { /* XXX print as bounded string? */ //od_hex_dump_ext(str, len, 16, 0); - printf(" value: %.*s\n", len, str); + printf(" value[%04u]: %.*s\n", len, len, str); } break; default: nanocbor_skip(&values); + printf("\n"); } } From ab48c8b03c3fa537ee543b775a903db6cd7e77e1 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 22 Oct 2021 21:54:53 -0400 Subject: [PATCH 23/43] cfg_page: refactor out initialization of header --- drivers/cfg_page/cfg_page.c | 41 +++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 4000d6d62754..c2f9c333034c 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -142,45 +142,56 @@ int cfg_page_validate(cfg_page_desc_t *cpd, int cfg_slot_no) return serialno; } -int cfg_page_format(cfg_page_desc_t *cpd, int cfg_slot_no, int serialno) -{ - unsigned char header_buffer[CFG_PAGE_HEADER_SIZE+2]; - nanocbor_encoder_t encoder; - unsigned int write_size=CFG_PAGE_HEADER_SIZE+2; +static int _cfg_page_format_stuff(nanocbor_encoder_t *encoder, + unsigned char *header_buffer, + int serialno) { - nanocbor_encoder_init(&encoder, header_buffer, write_size); - - if(nanocbor_fmt_tag(&encoder, CBOR_SEQ_TAG) < 0) { + if(nanocbor_fmt_tag(encoder, CBOR_SEQ_TAG) < 0) { return -1; } - if(nanocbor_fmt_tag(&encoder, CFG_PAGE_RIOT_TAG) < 0) { + if(nanocbor_fmt_tag(encoder, CFG_PAGE_RIOT_TAG) < 0) { return -1; } - if(nanocbor_put_bstr(&encoder, (unsigned const char *)"BOR", 3) < 0) { + if(nanocbor_put_bstr(encoder, (unsigned const char *)"BOR", 3) < 0) { return -1; } - if(nanocbor_fmt_uint(&encoder, serialno) < NANOCBOR_OK) { + if(nanocbor_fmt_uint(encoder, serialno) < NANOCBOR_OK) { return -6; } /* now calculate the CRC */ /* calculate a 16-bit checksum across the bytes so far */ - uint16_t calculated = crc16_ccitt_calc(header_buffer, (encoder.cur - header_buffer)); + uint16_t calculated = crc16_ccitt_calc(header_buffer, (encoder->cur - header_buffer)); - if(nanocbor_fmt_uint(&encoder, calculated) < NANOCBOR_OK) { + if(nanocbor_fmt_uint(encoder, calculated) < NANOCBOR_OK) { return -7; } /* now initialize an indefinite map, and stop code */ - if(nanocbor_fmt_map_indefinite(&encoder) < 0) { + if(nanocbor_fmt_map_indefinite(encoder) < 0) { return -8; } - if(nanocbor_fmt_end_indefinite(&encoder) < 0) { + if(nanocbor_fmt_end_indefinite(encoder) < 0) { return -9; } + return 0; +} + +int cfg_page_format(cfg_page_desc_t *cpd, int cfg_slot_no, int serialno) +{ + unsigned char header_buffer[CFG_PAGE_HEADER_SIZE+2]; + nanocbor_encoder_t encoder; + int ret; + unsigned int write_size=CFG_PAGE_HEADER_SIZE+2; + + nanocbor_encoder_init(&encoder, header_buffer, write_size); + + if((ret =_cfg_page_format_stuff(&encoder, header_buffer, serialno)) < 0) { + return ret; + } unsigned int byte_offset = _calculate_slot_offset(cfg_slot_no); From 7df4380a843646fb3341774b0c6e53fd74f0bf88 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 22 Oct 2021 23:19:29 -0400 Subject: [PATCH 24/43] cfg_page: remember what the highest active serial number is --- drivers/cfg_page/cfg_page.c | 127 ++++++++++++++++++++++++++++++++++-- drivers/include/cfg_page.h | 3 + 2 files changed, 125 insertions(+), 5 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index c2f9c333034c..70a97d78b0e7 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -33,6 +33,7 @@ #include #include +#include #include "nanocbor/nanocbor.h" #include "checksum/crc16_ccitt.h" @@ -289,12 +290,123 @@ int cfg_page_get_value(cfg_page_desc_t *cpd, uint32_t wantedkey, nanocbor_value_ * Processing resumes from there, ingoring keyid=0. * */ -static int cfg_page_swap_slotno(cfg_page_desc_t *cpd, nanocbor_value_t *reader) +static int cfg_page_swap_slotno(cfg_page_desc_t *cpd, nanocbor_value_t *oreader) { - (void)cpd; - (void)reader; - printf("swap\n"); - return -1; + unsigned char new_page[MTD_SECTOR_SIZE]; + nanocbor_encoder_t writer; + nanocbor_value_t reader, values, nreader2; + nanocbor_value_t okey1, value_st, okey2; + size_t value_len; + + if(cfg_page_init_reader(cpd, cfg_page_active_buffer, sizeof(cfg_page_active_buffer), &reader) < 0) { + return -1; + } + if(nanocbor_get_type(&reader) != NANOCBOR_TYPE_MAP || + nanocbor_enter_map(&reader, &values) != NANOCBOR_OK) { + return -2; + } + + /* setup writer, but do not initialize the header until we are done */ + nanocbor_encoder_init(&writer, + new_page+CFG_PAGE_HEADER_SIZE, + MTD_SECTOR_SIZE-CFG_PAGE_HEADER_SIZE); + + memset(new_page, 0xff, MTD_SECTOR_SIZE); + + //printf("old %u:\n", values.cur - cfg_page_active_buffer); + //od_hex_dump_ext(cfg_page_active_buffer, MTD_SECTOR_SIZE, 16, 0); + + while(!nanocbor_at_end(&values)) { + uint32_t key = 0; + int keysize = 0; + + /* keep track of where key is, so we can come back to stomp it */ + okey1 = reader; + if(nanocbor_get_uint32(&values, &key) < 0) { + /* what to do here is unclear */ + DEBUG("failed to get uint32\n"); + return -1; + } + if(key == 0) { + /* this key has already been moved, move on */ + //DEBUG("at %p key already processed\n", okey1.cur); + nanocbor_skip(&values); + continue; + } + /* calculate size of key that was just read */ + keysize = reader.cur - okey1.cur; + + /* not blanked out, so keep track of where value is */ + value_st = reader; + + /* skip the value */ + nanocbor_skip(&values); + value_len= reader.cur - value_st.cur; + + /* now run forward looking for newer keys with the same value */ + nreader2 = values; + DEBUG("process at %u for newest key=%u\n", nreader2.cur - cfg_page_active_buffer, key); + while(!nanocbor_at_end(&nreader2)) { + uint32_t nkey = 0; + + okey2 = nreader2; + if(nanocbor_get_uint32(&nreader2, &nkey) < 0) { + DEBUG("failed to get uint32 nkey\n"); + /* what to do here is unclear */ + return -1; + } + if(key != nkey) { + //DEBUG("different key %u=%u\n", nkey, key); + nanocbor_skip(&nreader2); + continue; + } + /* okay, it's the same */ + /* replace the values we had above */ + value_st = nreader2; + nanocbor_skip(&nreader2); + value_len= nreader2.cur - value_st.cur; + + /* reach back, and obliterate the key we had */ + /* has intimate knowledge of CBOR uint */ + //DEBUG("splatting old key %u %p\n", key, okey1.cur); + *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT; + if(keysize > 0) { + int i; + for(i=1; i < keysize; i++) { + ((uint8_t *)okey1.cur)[i] = 0; + } + } + + /* skip key forward */ + okey1 = okey2; + } + + /* at this point, key has the int value of the key */ + /* value_st has the last value that we've found. */ + /* previous instances of the same `key` have been turned to 0 */ + /* so, insert this stuff into the new_page */ + + DEBUG("writing key %u value[%u]\n", key, value_len); + nanocbor_fmt_uint(&writer, key); + /* memcpy! */ + writer.len += value_len; + if((size_t)(writer.end - writer.cur) >= value_len) { + memcpy(writer.cur, value_st.cur, value_len); + writer.cur += value_len; + } else { + return -4; + } + + } + + //printf("new:\n"); + //od_hex_dump_ext(new_page, MTD_SECTOR_SIZE, 16, 0); + + + (void)oreader; + /* now setup reader to point to where the new page ends */ + /* some book keeping needed on cpd->? */ + return 0; } int cfg_page_init_writer(cfg_page_desc_t *cpd, @@ -423,14 +535,19 @@ int cfg_page_init(cfg_page_desc_t *cpd) if(slot0_serial < 0 && slot1_serial < 0) { DEBUG("Formatting cfg page %u\n", cpd->active_page); cfg_page_format(&cfgpage, cpd->active_page, 0); + cfgpage.active_serialno = 0; } else if(slot0_serial < 0 && slot1_serial >= 0) { cpd->active_page = 1; + cfgpage.active_serialno = slot1_serial; } else if(slot0_serial >= 0 && slot1_serial < 0) { cpd->active_page = 0; + cfgpage.active_serialno = slot0_serial; } else if(slot0_serial >= slot1_serial) { cpd->active_page = 0; + cfgpage.active_serialno = slot0_serial; } else { cpd->active_page = 1; + cfgpage.active_serialno = slot1_serial; } DEBUG("Using cfg page %u\n", cpd->active_page); diff --git a/drivers/include/cfg_page.h b/drivers/include/cfg_page.h index c28cd15543f7..37b3dced38df 100644 --- a/drivers/include/cfg_page.h +++ b/drivers/include/cfg_page.h @@ -37,8 +37,11 @@ typedef struct cfg_page_desc { nanocbor_encoder_t writer; nanocbor_value_t reader; uint8_t active_page; /* 0 or 1 */ + uint8_t active_serialno; } cfg_page_desc_t; +#define CFG_PAGE_HEADER_SIZE 16 + extern int cfg_page_init(cfg_page_desc_t *cpd); extern int cfg_page_validate(cfg_page_desc_t *cpd, int cfg_slot_no); extern int cfg_page_format(cfg_page_desc_t *cpd, int cfg_slot_no, int slotno); From 1e50742d41b7d50cb8e6b072ea715708ac5c6c75 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Sat, 23 Oct 2021 19:01:53 -0400 Subject: [PATCH 25/43] cfg_page: move initialize of map into page_format --- drivers/cfg_page/cfg_page.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 70a97d78b0e7..3b2b91807380 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -171,13 +171,6 @@ static int _cfg_page_format_stuff(nanocbor_encoder_t *encoder, return -7; } - /* now initialize an indefinite map, and stop code */ - if(nanocbor_fmt_map_indefinite(encoder) < 0) { - return -8; - } - if(nanocbor_fmt_end_indefinite(encoder) < 0) { - return -9; - } return 0; } @@ -193,6 +186,13 @@ int cfg_page_format(cfg_page_desc_t *cpd, int cfg_slot_no, int serialno) if((ret =_cfg_page_format_stuff(&encoder, header_buffer, serialno)) < 0) { return ret; } + /* now initialize an indefinite map, and stop code */ + if(nanocbor_fmt_map_indefinite(&encoder) < 0) { + return -8; + } + if(nanocbor_fmt_end_indefinite(&encoder) < 0) { + return -9; + } unsigned int byte_offset = _calculate_slot_offset(cfg_slot_no); From d3144f73366044b5900e1d33b4675661a76da3f7 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Sat, 23 Oct 2021 19:02:42 -0400 Subject: [PATCH 26/43] cfg_page: instead of re-initializing the end of values reader in the slot swap, just allow the writer to loop once --- drivers/cfg_page/cfg_page.c | 88 +++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 28 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 3b2b91807380..555b06c24667 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -290,13 +290,14 @@ int cfg_page_get_value(cfg_page_desc_t *cpd, uint32_t wantedkey, nanocbor_value_ * Processing resumes from there, ingoring keyid=0. * */ -static int cfg_page_swap_slotno(cfg_page_desc_t *cpd, nanocbor_value_t *oreader) +static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) { unsigned char new_page[MTD_SECTOR_SIZE]; nanocbor_encoder_t writer; nanocbor_value_t reader, values, nreader2; nanocbor_value_t okey1, value_st, okey2; size_t value_len; + int ret = 0; if(cfg_page_init_reader(cpd, cfg_page_active_buffer, sizeof(cfg_page_active_buffer), &reader) < 0) { return -1; @@ -399,13 +400,35 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd, nanocbor_value_t *oreader) } + /* + * now, initialize the newpage with serialno+1, and + * read it back in + */ + cpd->active_serialno++; + if(cpd->active_serialno > 23) { + cpd->active_serialno = 1; + } + nanocbor_encoder_init(&writer, new_page, CFG_PAGE_HEADER_SIZE); + if((ret = _cfg_page_format_stuff(&writer, new_page, cpd->active_serialno)) < 0) { + return ret; + } //printf("new:\n"); //od_hex_dump_ext(new_page, MTD_SECTOR_SIZE, 16, 0); + /* flip bit on which page is active */ + cpd->active_page = !cpd->active_page; + + unsigned int byte_offset = _calculate_slot_offset(cpd->active_page); + /* erase the entire page */ + if((ret = mtd_erase(cpd->dev, byte_offset, MTD_SECTOR_SIZE)) != 0) { + DEBUG("erase failed: %d\n\n",ret); + return -10; + } + if((ret = mtd_write(cpd->dev, new_page, byte_offset, MTD_SECTOR_SIZE)) != 0) { + DEBUG("write failed: %d\n", ret); + return -11; + } - (void)oreader; - /* now setup reader to point to where the new page ends */ - /* some book keeping needed on cpd->? */ return 0; } @@ -416,35 +439,44 @@ int cfg_page_init_writer(cfg_page_desc_t *cpd, { nanocbor_value_t reader; nanocbor_value_t values; + bool tryswap = 0; + size_t amountleft = 0; - /* start by bringin in the content */ - /* XXX could avoid this if we think the content is already loaded */ - if(cfg_page_init_reader(cpd, cfg_page_active_buffer, sizeof(cfg_page_active_buffer), &reader) < 0) { - return -1; - } + do { /* this at most twice */ - /* XXX at this point, if cpd->writer is initialized, can return it immediately */ - /* but premature optimization, and there are caching issues here */ + /* start by bringin in the content */ + /* XXX could avoid this if we think the content is already loaded */ + if(cfg_page_init_reader(cpd, cfg_page_active_buffer, sizeof(cfg_page_active_buffer), &reader) < 0) { + return -1; + } - if(nanocbor_get_type(&reader) != NANOCBOR_TYPE_MAP || - nanocbor_enter_map(&reader, &values) != NANOCBOR_OK) { - return -2; - } + /* XXX at this point, if cpd->writer is initialized, can return it immediately */ + /* but premature optimization, and there are caching issues here */ - while(!nanocbor_at_end(&values)) { - nanocbor_skip(&values); /* key */ - nanocbor_skip(&values); /* value */ - } - nanocbor_leave_container(&reader, &values); + if(nanocbor_get_type(&reader) != NANOCBOR_TYPE_MAP || + nanocbor_enter_map(&reader, &values) != NANOCBOR_OK) { + return -2; + } - /* we are now located at end of space */ - /* calculate how much space is left */ - size_t amountleft = reader.end - reader.cur; - if(valuelen > amountleft) { - /* move all values to other page and switch over there */ - cfg_page_swap_slotno(cpd, &reader); - DEBUG("swap slotno\n"); - } + while(!nanocbor_at_end(&values)) { + nanocbor_skip(&values); /* key */ + nanocbor_skip(&values); /* value */ + } + nanocbor_leave_container(&reader, &values); + + /* we are now located at end of space */ + /* calculate how much space is left */ + amountleft = reader.end - reader.cur; + if(valuelen > amountleft) { + if(tryswap) { + return -ENOSPC; + } + /* move all values to other page and switch over there */ + cfg_page_swap_slotno(cpd); + tryswap = 1; + DEBUG("swap slotno to %d\n", cpd->active_page); + } + } while(!tryswap); /* -1 to remove 0xff stop code */ size_t writeoffset = (reader.cur-cfg_page_active_buffer)-1; From 236e7c099a97b83103e484bc038a0f54eb8f055f Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Tue, 26 Oct 2021 10:20:32 -0400 Subject: [PATCH 27/43] cfg_page: rejig the loop when writing that does the slot swap. Moved where the header gets initialized so that a single writer is used --- drivers/cfg_page/cfg_page.c | 61 ++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 555b06c24667..77df58992649 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -209,7 +209,7 @@ int cfg_page_format(cfg_page_desc_t *cpd, int cfg_slot_no, int serialno) return -10; } if((error = mtd_write(cpd->dev, header_buffer, byte_offset, write_size)) != 0) { - DEBUG("write failed: %d\n", error); + DEBUG("fmt write failed: %d\n", error); return -11; } @@ -307,13 +307,24 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) return -2; } - /* setup writer, but do not initialize the header until we are done */ - nanocbor_encoder_init(&writer, - new_page+CFG_PAGE_HEADER_SIZE, - MTD_SECTOR_SIZE-CFG_PAGE_HEADER_SIZE); - memset(new_page, 0xff, MTD_SECTOR_SIZE); + /* setup writer */ + nanocbor_encoder_init(&writer,new_page,MTD_SECTOR_SIZE); + + /* setup the header: this should be deferred if this is real NAND */ + cpd->active_serialno++; + if(cpd->active_serialno > 23) { + cpd->active_serialno = 1; + } + if((ret =_cfg_page_format_stuff(&writer, new_page, cpd->active_serialno)) < 0) { + return ret; + } + /* now initialize an indefinite map, stop code implied by erase */ + if(nanocbor_fmt_map_indefinite(&writer) < 0) { + return -8; + } + //printf("old %u:\n", values.cur - cfg_page_active_buffer); //od_hex_dump_ext(cfg_page_active_buffer, MTD_SECTOR_SIZE, 16, 0); @@ -346,7 +357,7 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) /* now run forward looking for newer keys with the same value */ nreader2 = values; - DEBUG("process at %u for newest key=%u\n", nreader2.cur - cfg_page_active_buffer, key); + //DEBUG("process at %u for newest key=%u\n", nreader2.cur - cfg_page_active_buffer, key); while(!nanocbor_at_end(&nreader2)) { uint32_t nkey = 0; @@ -357,7 +368,7 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) return -1; } if(key != nkey) { - //DEBUG("different key %u=%u\n", nkey, key); + DEBUG("different key %u=%u\n", nkey, key); nanocbor_skip(&nreader2); continue; } @@ -369,7 +380,7 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) /* reach back, and obliterate the key we had */ /* has intimate knowledge of CBOR uint */ - //DEBUG("splatting old key %u %p\n", key, okey1.cur); + DEBUG("splatting old key %u %p\n", key, okey1.cur); *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT; if(keysize > 0) { int i; @@ -404,16 +415,8 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) * now, initialize the newpage with serialno+1, and * read it back in */ - cpd->active_serialno++; - if(cpd->active_serialno > 23) { - cpd->active_serialno = 1; - } - nanocbor_encoder_init(&writer, new_page, CFG_PAGE_HEADER_SIZE); - if((ret = _cfg_page_format_stuff(&writer, new_page, cpd->active_serialno)) < 0) { - return ret; - } - //printf("new:\n"); - //od_hex_dump_ext(new_page, MTD_SECTOR_SIZE, 16, 0); + printf("new:\n"); + od_hex_dump_ext(new_page, MTD_SECTOR_SIZE, 16, 0); /* flip bit on which page is active */ cpd->active_page = !cpd->active_page; @@ -425,7 +428,7 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) return -10; } if((ret = mtd_write(cpd->dev, new_page, byte_offset, MTD_SECTOR_SIZE)) != 0) { - DEBUG("write failed: %d\n", ret); + DEBUG("swap write to %u page: %u failed: %d\n", byte_offset, cpd->active_page, ret); return -11; } @@ -439,14 +442,16 @@ int cfg_page_init_writer(cfg_page_desc_t *cpd, { nanocbor_value_t reader; nanocbor_value_t values; - bool tryswap = 0; + bool foundspace = 0; + bool tryswap = 0; size_t amountleft = 0; - do { /* this at most twice */ - + while(!foundspace) { + DEBUG("finding end of valid values: %d\n", tryswap); /* start by bringin in the content */ /* XXX could avoid this if we think the content is already loaded */ if(cfg_page_init_reader(cpd, cfg_page_active_buffer, sizeof(cfg_page_active_buffer), &reader) < 0) { + DEBUG("cfg_page: failed to init reader\n"); return -1; } @@ -455,6 +460,7 @@ int cfg_page_init_writer(cfg_page_desc_t *cpd, if(nanocbor_get_type(&reader) != NANOCBOR_TYPE_MAP || nanocbor_enter_map(&reader, &values) != NANOCBOR_OK) { + DEBUG("cfg_page: failed to process map\n"); return -2; } @@ -469,14 +475,19 @@ int cfg_page_init_writer(cfg_page_desc_t *cpd, amountleft = reader.end - reader.cur; if(valuelen > amountleft) { if(tryswap) { + DEBUG("cfg_page: did not found space after swap: %u > %u\n", valuelen, amountleft); return -ENOSPC; } /* move all values to other page and switch over there */ cfg_page_swap_slotno(cpd); - tryswap = 1; DEBUG("swap slotno to %d\n", cpd->active_page); + foundspace = 0; + tryswap = 1; + } else { + foundspace = 1; } - } while(!tryswap); + } + /* -1 to remove 0xff stop code */ size_t writeoffset = (reader.cur-cfg_page_active_buffer)-1; From 3fcd06655d77bbd40b657a4f87e53b6f6b27b285 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Thu, 28 Oct 2021 14:54:25 -0400 Subject: [PATCH 28/43] cfg_page: make sure that last copy of key is splatted after it is copied --- drivers/cfg_page/cfg_page.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 77df58992649..effb969cb4af 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -273,6 +273,21 @@ int cfg_page_get_value(cfg_page_desc_t *cpd, uint32_t wantedkey, nanocbor_value_ return ret; } +static void _cfg_page_splat_key(nanocbor_value_t okey1, int keysize) +{ + *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT; + if(keysize > 0) { + /* + * XXX this is not right. It needs to make a TYPE_UINT which is + * multiple bytes + */ + int i; + for(i=1; i < keysize; i++) { + ((uint8_t *)okey1.cur)[i] = 0; + } + } +} + /* * process through all the attributes in the filled current space, * copying the last value for each key into the new space. @@ -381,13 +396,7 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) /* reach back, and obliterate the key we had */ /* has intimate knowledge of CBOR uint */ DEBUG("splatting old key %u %p\n", key, okey1.cur); - *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT; - if(keysize > 0) { - int i; - for(i=1; i < keysize; i++) { - ((uint8_t *)okey1.cur)[i] = 0; - } - } + _cfg_page_splat_key(okey1, keysize); /* skip key forward */ okey1 = okey2; @@ -409,6 +418,8 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) return -4; } + /* now splat the last copy of the key, since it is copied */ + _cfg_page_splat_key(okey1, keysize); } /* From 908898ee8f8ae5f87401ecee22d0ed85b976a1d6 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Thu, 28 Oct 2021 15:00:04 -0400 Subject: [PATCH 29/43] cfg_page: deal with keys that are bigger than one byte --- drivers/cfg_page/cfg_page.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index effb969cb4af..024843613fff 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -275,12 +275,29 @@ int cfg_page_get_value(cfg_page_desc_t *cpd, uint32_t wantedkey, nanocbor_value_ static void _cfg_page_splat_key(nanocbor_value_t okey1, int keysize) { - *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT; + switch(keysize) { + case 1: + *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT; + break; + + case 1+2: + *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_BYTE; + break; + + case 1+4: + *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_SHORT; + break; + + case 1+8: + *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_WORD; + break; + + case 1+16: + *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_WORD; + break; + } if(keysize > 0) { - /* - * XXX this is not right. It needs to make a TYPE_UINT which is - * multiple bytes - */ + /* make a zero of a bigger size */ int i; for(i=1; i < keysize; i++) { ((uint8_t *)okey1.cur)[i] = 0; From 831ef3f305503bba643800ba0e0b5e2bddef4ccc Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Thu, 28 Oct 2021 15:04:42 -0400 Subject: [PATCH 30/43] cfg_page: test with bigger key values --- tests/driver_cfg_page/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/driver_cfg_page/main.c b/tests/driver_cfg_page/main.c index 88a66118dc98..3b779762d2c2 100644 --- a/tests/driver_cfg_page/main.c +++ b/tests/driver_cfg_page/main.c @@ -42,18 +42,19 @@ int main(void) cfg_page_print(&cfgpage); - for(i=0; i<127; i++) { + for(i=0; i<128; i++) { + printf("writing iteration %d\n", i); uint8_t buf2[16]; snprintf((char *)buf2, 16, "bob%04x", i); if(cfg_page_set_str_value(&cfgpage, 1, buf2, strlen((const char *)buf2)) != 0) { printf("set key 1 failed\n"); } snprintf((char *)buf2, 16, "frank%04x", i); - if(cfg_page_set_str_value(&cfgpage, 2, buf2, strlen((const char *)buf2)) != 0) { + if(cfg_page_set_str_value(&cfgpage, 32, buf2, strlen((const char *)buf2)) != 0) { printf("set key 2 failed\n"); } snprintf((char *)buf2, 16, "george%04x", i); - if(cfg_page_set_str_value(&cfgpage, 3, buf2, strlen((const char *)buf2)) != 0) { + if(cfg_page_set_str_value(&cfgpage, 65537, buf2, strlen((const char *)buf2)) != 0) { printf("set key 3 failed\n"); } } From a872ab33a4995dbb6e463d3816486be88371f0e3 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Thu, 28 Oct 2021 15:38:49 -0400 Subject: [PATCH 31/43] cfg_page: clean up some debug for better readability --- drivers/cfg_page/cfg_page.c | 4 ++-- drivers/cfg_page/cfg_page_print.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 024843613fff..1717d6efacc8 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -475,7 +475,7 @@ int cfg_page_init_writer(cfg_page_desc_t *cpd, size_t amountleft = 0; while(!foundspace) { - DEBUG("finding end of valid values: %d\n", tryswap); + //DEBUG("finding end of valid values: %d\n", tryswap); /* start by bringin in the content */ /* XXX could avoid this if we think the content is already loaded */ if(cfg_page_init_reader(cpd, cfg_page_active_buffer, sizeof(cfg_page_active_buffer), &reader) < 0) { @@ -519,7 +519,7 @@ int cfg_page_init_writer(cfg_page_desc_t *cpd, /* -1 to remove 0xff stop code */ size_t writeoffset = (reader.cur-cfg_page_active_buffer)-1; - DEBUG("found end of old values at: %u, amountleft=%u\n", + DEBUG("found end of old values at: %04u, amountleft=%04u\n", writeoffset, amountleft); /* initialize the writer at this location, using the writer in cpd->writer */ diff --git a/drivers/cfg_page/cfg_page_print.c b/drivers/cfg_page/cfg_page_print.c index f2ce2494486e..265b99913334 100644 --- a/drivers/cfg_page/cfg_page_print.c +++ b/drivers/cfg_page/cfg_page_print.c @@ -61,7 +61,7 @@ int cfg_page_print(cfg_page_desc_t *cpd) } type = nanocbor_get_type(&values); - printf("key: %02u[type=%02u] where=%p:%d ", key, type, values.cur, + printf("key: %06u[type=%02u] where=%p:%d ", key, type, values.cur, values.cur-cfg_page_temp); switch(type) { case NANOCBOR_TYPE_BSTR: From 2ef4655dd5c816051d0889e282d311b1bad6f498 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Thu, 28 Oct 2021 15:39:03 -0400 Subject: [PATCH 32/43] cfg_page: deal with key size of 0 --- drivers/cfg_page/cfg_page.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 1717d6efacc8..ebf6e9ce5d1d 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -276,25 +276,29 @@ int cfg_page_get_value(cfg_page_desc_t *cpd, uint32_t wantedkey, nanocbor_value_ static void _cfg_page_splat_key(nanocbor_value_t okey1, int keysize) { switch(keysize) { - case 1: + case 0: *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT; break; - case 1+2: + case 1: *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_BYTE; break; - case 1+4: + case 2: *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_SHORT; break; - case 1+8: + case 4: *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_WORD; break; - case 1+16: - *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_WORD; + case 8: + *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_LONG; break; + + default: + DEBUG("bad keysize: %d\n", keysize); + return; } if(keysize > 0) { /* make a zero of a bigger size */ From 9885e8756fb1fc9eee9f9cb2449ad83dc2868a6a Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 29 Oct 2021 14:44:27 -0400 Subject: [PATCH 33/43] cfg_page: rework splat code, then realized that calculation of key size was wrong, fixed that. Test with one byte keys --- drivers/cfg_page/cfg_page.c | 83 ++++++++++++++++++++---------------- tests/driver_cfg_page/main.c | 7 ++- 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index ebf6e9ce5d1d..50890b14daed 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -275,38 +275,39 @@ int cfg_page_get_value(cfg_page_desc_t *cpd, uint32_t wantedkey, nanocbor_value_ static void _cfg_page_splat_key(nanocbor_value_t okey1, int keysize) { - switch(keysize) { - case 0: - *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT; - break; - - case 1: - *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_BYTE; - break; - - case 2: - *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_SHORT; - break; - - case 4: - *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_WORD; - break; - - case 8: - *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_LONG; - break; - - default: - DEBUG("bad keysize: %d\n", keysize); - return; - } - if(keysize > 0) { - /* make a zero of a bigger size */ - int i; - for(i=1; i < keysize; i++) { - ((uint8_t *)okey1.cur)[i] = 0; - } - } + DEBUG("splat keysize: %d\n", keysize); + switch(keysize) { + case 1: + *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT; /* zero */ + break; + + case 1+1: + *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_BYTE; + break; + + case 1+2: + *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_SHORT; + break; + + case 1+4: + *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_WORD; + break; + + case 1+8: + *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT+NANOCBOR_SIZE_LONG; + break; + + default: + DEBUG("bad keysize: %d\n", keysize); + return; + } + if(keysize > 0) { + /* make a zero of a bigger size */ + int i; + for(i=1; i < keysize; i++) { + ((uint8_t *)okey1.cur)[i] = 0; + } + } } /* @@ -369,10 +370,15 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) int keysize = 0; /* keep track of where key is, so we can come back to stomp it */ - okey1 = reader; + okey1 = values; if(nanocbor_get_uint32(&values, &key) < 0) { /* what to do here is unclear */ DEBUG("failed to get uint32\n"); + + printf("old %04x:\n", values.cur - cfg_page_active_buffer); + od_hex_dump_ext(cfg_page_active_buffer, MTD_SECTOR_SIZE, 16, 0); + printf("new:\n"); + od_hex_dump_ext(new_page, MTD_SECTOR_SIZE, 16, 0); return -1; } if(key == 0) { @@ -382,14 +388,14 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) continue; } /* calculate size of key that was just read */ - keysize = reader.cur - okey1.cur; + keysize = values.cur - okey1.cur; /* not blanked out, so keep track of where value is */ - value_st = reader; + value_st = values; /* skip the value */ nanocbor_skip(&values); - value_len= reader.cur - value_st.cur; + value_len= values.cur - value_st.cur; /* now run forward looking for newer keys with the same value */ nreader2 = values; @@ -408,6 +414,9 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) nanocbor_skip(&nreader2); continue; } + /* calculate size of key that was just read */ + keysize = nreader2.cur - okey2.cur; + /* okay, it's the same */ /* replace the values we had above */ value_st = nreader2; @@ -416,7 +425,7 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) /* reach back, and obliterate the key we had */ /* has intimate knowledge of CBOR uint */ - DEBUG("splatting old key %u %p\n", key, okey1.cur); + DEBUG("splatting old key %u %03x\n", key, okey1.cur - cfg_page_active_buffer); _cfg_page_splat_key(okey1, keysize); /* skip key forward */ diff --git a/tests/driver_cfg_page/main.c b/tests/driver_cfg_page/main.c index 3b779762d2c2..158f5904d56f 100644 --- a/tests/driver_cfg_page/main.c +++ b/tests/driver_cfg_page/main.c @@ -48,14 +48,17 @@ int main(void) snprintf((char *)buf2, 16, "bob%04x", i); if(cfg_page_set_str_value(&cfgpage, 1, buf2, strlen((const char *)buf2)) != 0) { printf("set key 1 failed\n"); + break; } snprintf((char *)buf2, 16, "frank%04x", i); - if(cfg_page_set_str_value(&cfgpage, 32, buf2, strlen((const char *)buf2)) != 0) { + if(cfg_page_set_str_value(&cfgpage, 21, buf2, strlen((const char *)buf2)) != 0) { printf("set key 2 failed\n"); + break; } snprintf((char *)buf2, 16, "george%04x", i); - if(cfg_page_set_str_value(&cfgpage, 65537, buf2, strlen((const char *)buf2)) != 0) { + if(cfg_page_set_str_value(&cfgpage, 17, buf2, strlen((const char *)buf2)) != 0) { printf("set key 3 failed\n"); + break; } } From eb99f27460dff457fa030b78ddb669bce95d1fa0 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 29 Oct 2021 14:46:14 -0400 Subject: [PATCH 34/43] cfg_page: turn off some debugging --- drivers/cfg_page/cfg_page.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 50890b14daed..c2a07ac1e7de 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -275,7 +275,7 @@ int cfg_page_get_value(cfg_page_desc_t *cpd, uint32_t wantedkey, nanocbor_value_ static void _cfg_page_splat_key(nanocbor_value_t okey1, int keysize) { - DEBUG("splat keysize: %d\n", keysize); + //DEBUG("splat keysize: %d\n", keysize); switch(keysize) { case 1: *((uint8_t *)okey1.cur) = NANOCBOR_TYPE_UINT; /* zero */ @@ -375,10 +375,10 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) /* what to do here is unclear */ DEBUG("failed to get uint32\n"); - printf("old %04x:\n", values.cur - cfg_page_active_buffer); - od_hex_dump_ext(cfg_page_active_buffer, MTD_SECTOR_SIZE, 16, 0); - printf("new:\n"); - od_hex_dump_ext(new_page, MTD_SECTOR_SIZE, 16, 0); + //printf("old %04x:\n", values.cur - cfg_page_active_buffer); + //od_hex_dump_ext(cfg_page_active_buffer, MTD_SECTOR_SIZE, 16, 0); + //printf("new:\n"); + //od_hex_dump_ext(new_page, MTD_SECTOR_SIZE, 16, 0); return -1; } if(key == 0) { @@ -406,11 +406,15 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) okey2 = nreader2; if(nanocbor_get_uint32(&nreader2, &nkey) < 0) { DEBUG("failed to get uint32 nkey\n"); + //printf("old %04x:\n", values.cur - cfg_page_active_buffer); + //od_hex_dump_ext(cfg_page_active_buffer, MTD_SECTOR_SIZE, 16, 0); + //printf("new:\n"); + //od_hex_dump_ext(new_page, MTD_SECTOR_SIZE, 16, 0); /* what to do here is unclear */ return -1; } if(key != nkey) { - DEBUG("different key %u=%u\n", nkey, key); + //DEBUG("different key %u=%u\n", nkey, key); nanocbor_skip(&nreader2); continue; } @@ -425,7 +429,7 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) /* reach back, and obliterate the key we had */ /* has intimate knowledge of CBOR uint */ - DEBUG("splatting old key %u %03x\n", key, okey1.cur - cfg_page_active_buffer); + //DEBUG("splatting old key %u %03x\n", key, okey1.cur - cfg_page_active_buffer); _cfg_page_splat_key(okey1, keysize); /* skip key forward */ @@ -456,8 +460,8 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) * now, initialize the newpage with serialno+1, and * read it back in */ - printf("new:\n"); - od_hex_dump_ext(new_page, MTD_SECTOR_SIZE, 16, 0); + //printf("new:\n"); + //od_hex_dump_ext(new_page, MTD_SECTOR_SIZE, 16, 0); /* flip bit on which page is active */ cpd->active_page = !cpd->active_page; @@ -532,8 +536,7 @@ int cfg_page_init_writer(cfg_page_desc_t *cpd, /* -1 to remove 0xff stop code */ size_t writeoffset = (reader.cur-cfg_page_active_buffer)-1; - DEBUG("found end of old values at: %04u, amountleft=%04u\n", - writeoffset, amountleft); + //DEBUG("found end of old values at: %04u, amountleft=%04u\n",writeoffset, amountleft); /* initialize the writer at this location, using the writer in cpd->writer */ if(writer) { From bfde7756dc7bd11fd429e7454c52be21325a1c5a Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 29 Oct 2021 15:01:08 -0400 Subject: [PATCH 35/43] cfg_page: bump test to 256 to get two iterations of slot swap --- tests/driver_cfg_page/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/driver_cfg_page/main.c b/tests/driver_cfg_page/main.c index 158f5904d56f..e064b3ed7131 100644 --- a/tests/driver_cfg_page/main.c +++ b/tests/driver_cfg_page/main.c @@ -42,7 +42,7 @@ int main(void) cfg_page_print(&cfgpage); - for(i=0; i<128; i++) { + for(i=0; i<256; i++) { printf("writing iteration %d\n", i); uint8_t buf2[16]; snprintf((char *)buf2, 16, "bob%04x", i); From 45aefe821f6bc3f81b2e3fc062549afda6a0d193 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 29 Oct 2021 15:04:56 -0400 Subject: [PATCH 36/43] cfg_page: move to variety of key sizes --- tests/driver_cfg_page/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/driver_cfg_page/main.c b/tests/driver_cfg_page/main.c index e064b3ed7131..972dd3b68c65 100644 --- a/tests/driver_cfg_page/main.c +++ b/tests/driver_cfg_page/main.c @@ -51,12 +51,12 @@ int main(void) break; } snprintf((char *)buf2, 16, "frank%04x", i); - if(cfg_page_set_str_value(&cfgpage, 21, buf2, strlen((const char *)buf2)) != 0) { + if(cfg_page_set_str_value(&cfgpage, 37, buf2, strlen((const char *)buf2)) != 0) { printf("set key 2 failed\n"); break; } snprintf((char *)buf2, 16, "george%04x", i); - if(cfg_page_set_str_value(&cfgpage, 17, buf2, strlen((const char *)buf2)) != 0) { + if(cfg_page_set_str_value(&cfgpage, 65537, buf2, strlen((const char *)buf2)) != 0) { printf("set key 3 failed\n"); break; } From c0b3fb8044ea8fac73316d75918fb7c199814b65 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 29 Oct 2021 16:15:51 -0400 Subject: [PATCH 37/43] cfg_page: stock mtd_write only supports MTD_PAGE_SIZE blocks --- drivers/cfg_page/cfg_page.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index c2a07ac1e7de..4771e3c2ae63 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -472,11 +472,19 @@ static int cfg_page_swap_slotno(cfg_page_desc_t *cpd) DEBUG("erase failed: %d\n\n",ret); return -10; } - if((ret = mtd_write(cpd->dev, new_page, byte_offset, MTD_SECTOR_SIZE)) != 0) { - DEBUG("swap write to %u page: %u failed: %d\n", byte_offset, cpd->active_page, ret); - return -11; - } + /* mtd_write does not let us write multiple pages */ + u_int8_t *start = new_page; + int write_count = 0; + for(; write_count < MTD_SECTOR_SIZE; write_count += MTD_PAGE_SIZE) { + //DEBUG("writing offset:%d,%d from %p\n", write_count, byte_offset, start); + if((ret = mtd_write(cpd->dev, start, byte_offset, MTD_PAGE_SIZE)) != 0) { + DEBUG("swap write to %u page: %u failed: %d\n", byte_offset, cpd->active_page, ret); + return -11; + } + start += MTD_PAGE_SIZE; + byte_offset += MTD_PAGE_SIZE; + } return 0; } From 268f3582491ac2e5a1fde50ca27404bfdf745327 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 29 Oct 2021 18:03:25 -0400 Subject: [PATCH 38/43] cfg_page: added wrap around for serial numbers --- drivers/cfg_page/cfg_page.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 4771e3c2ae63..e5364281e3cd 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -637,6 +637,14 @@ int cfg_page_init(cfg_page_desc_t *cpd) } else if(slot0_serial >= 0 && slot1_serial < 0) { cpd->active_page = 0; cfgpage.active_serialno = slot0_serial; + } else if(slot0_serial == 0 && slot1_serial == 23) { + /* wrapped around */ + cpd->active_page = 0; + cfgpage.active_serialno = slot0_serial; + } else if(slot0_serial == 23 && slot1_serial == 0) { + /* wrapped around */ + cpd->active_page = 1; + cfgpage.active_serialno = slot1_serial; } else if(slot0_serial >= slot1_serial) { cpd->active_page = 0; cfgpage.active_serialno = slot0_serial; From 0e3f5a647f3c97ac75d08f243eee857c85847d04 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 29 Oct 2021 18:03:39 -0400 Subject: [PATCH 39/43] cfg_page: added documentation for functions --- drivers/include/cfg_page.h | 103 +++++++++++++++++++++++++++++++++++-- 1 file changed, 100 insertions(+), 3 deletions(-) diff --git a/drivers/include/cfg_page.h b/drivers/include/cfg_page.h index 37b3dced38df..a6267472a816 100644 --- a/drivers/include/cfg_page.h +++ b/drivers/include/cfg_page.h @@ -29,8 +29,7 @@ extern "C" { #endif /** - * @name CFG page configuration - * @{ + * @brief CFG PAGE configuration object */ typedef struct cfg_page_desc { mtd_dev_t *dev; @@ -42,20 +41,118 @@ typedef struct cfg_page_desc { #define CFG_PAGE_HEADER_SIZE 16 +/** + * @brief Initialize the configuration page descriptor on @cpd object. + * + * This will initialize the cfg_page subsystem to start. + * Typically, there is a global cfg_page_desc_t called cfgpage. + * + * The initialization system will validate the CRC of each of the two possible slots + * and if both are correct, it will take the slot with the higher serialno. + * Serial numbers go from 0 to 23, and then will wrap around to 0 after 23. + * + * @param[in] cpd the global context + * @return negative value for error, 0 on success + */ extern int cfg_page_init(cfg_page_desc_t *cpd); + +/** + * @brief Validate a page of configuration variables. Normally does not need to be + * called, use cfg_page_init. + * + * This function will validate the CRC on the initial 16 byte header, and then + * validate that all the magic numbers are in place. It will return the decoded + * serial number if successful, negative value if not. + * + * @param[in] cpd the global context + * @param[in] cfg_slot_no which of two pages to validate + * @return The positive serial number (0->23) if valid. Negative if not. + */ extern int cfg_page_validate(cfg_page_desc_t *cpd, int cfg_slot_no); -extern int cfg_page_format(cfg_page_desc_t *cpd, int cfg_slot_no, int slotno); + +/** + * @brief This function will intialize a page number with a header and serial number. + * It inserts a 12 byte header to identify the page as a configuration variable + * page, a one byte serial number and a CRC. All encoded in CBOR. + * The total is 16 bytes of overhead. + * + * The page will then have an indefinite map opened, and then immediately ended with a stop + * code. The entire sector (typically 4k) will then be erased and this entire structure + * written to flash. + * + * @param[in] cpd the global context + * @param[in] cfg_slot_no which of two pages to write to. + * @param[in] serialno the serial number to write to the page + * @return 0 on success, negative on error + */ +extern int cfg_page_format(cfg_page_desc_t *cpd, int cfg_slot_no, int serialno); + +/** + * @brief Dumb the contents of the active page to the console. + * This auxiliary function can be used in debugging. + * + * @param[in] cpd the global context + * @return 0 on success, negative on error + */ extern int cfg_page_print(cfg_page_desc_t *cpd); + +/** + * @brief This function will intialize a nanocbor reader so that the keys and values + * can be read out. This is a low-level interface. + * + * This function figures out which is the correct page to read, and then reads the + * entire page in. The decoder is also initialized. + * While an arbirary page can be used, the module includes a static buffer that + * is used internally. + * + * This function is not yet (prematurely) optimized to retain the loaded data across calls. + * + * @param[in] cpd the global context + * @param[in] cfg_page_buffer some ram to keep the mapping + * @param[in] cfg_page_size the size of the buffer + * @param[out] cfg_page_reader a NANOCBOR reader to be initialized + * @return 0 on success, negative on error + */ extern int cfg_page_init_reader(cfg_page_desc_t *cpd, unsigned char *cfg_page_buffer, size_t cfg_page_size, nanocbor_value_t *cfg_page_reader); + +/** + * @brief This function will find the value associated with a given integer key. + * + * It will intialize the provided NANOCBOR reader to process the value. + * It will call cfg_page_init_reader to read all the values in. + * + * The last/most-recent value of the key will be returned + * + * @param[in] cpd the global context + * @param[in] wantedkey the unsigned int key to retrieve + * @param[out] valuereader a NANOCBOR reader to be initialized + * @return 0 on success, negative on error + */ extern int cfg_page_get_value(cfg_page_desc_t *cpd, uint32_t wantedkey, nanocbor_value_t *valuereader); + +/** + * @brief This function will write a bstr value associated with a given integer key. + * + * This function will append a new value to the page. + * + * @param[in] cpd the global context + * @param[in] wantedkey the unsigned int key to retrieve + * @param[in] strvalue a buffer of bytes to write + * @param[in] valuereader length of above buffer + * @return 0 on success, negative on error + */ extern int cfg_page_set_str_value(cfg_page_desc_t *cpd, uint32_t newkey, const uint8_t *strvalue, size_t strlen); +/** + * @brief This global is provided to describe the default set of cfg variables. + * + */ extern cfg_page_desc_t cfgpage; #ifdef __cplusplus From f132669a5f76d64acc99fec5584471884a89380c Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Sun, 31 Oct 2021 20:45:51 -0400 Subject: [PATCH 40/43] cfg_page: increment valuelen to accomodate key part --- drivers/cfg_page/cfg_page.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index e5364281e3cd..50d8c9ef5761 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -499,6 +499,9 @@ int cfg_page_init_writer(cfg_page_desc_t *cpd, bool tryswap = 0; size_t amountleft = 0; + /* increment valuelen by 5, to account for key */ + valuelen += 5; + while(!foundspace) { //DEBUG("finding end of valid values: %d\n", tryswap); /* start by bringin in the content */ From a71b1e4a59dc2c36a92b4a44cd9c6b71861cccc4 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Sun, 31 Oct 2021 20:46:18 -0400 Subject: [PATCH 41/43] cfg_page: nanocbor_at_end() seems to not end in some circumstances, TBD --- drivers/cfg_page/cfg_page.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index 50d8c9ef5761..bfb7c87d0038 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -520,15 +520,29 @@ int cfg_page_init_writer(cfg_page_desc_t *cpd, return -2; } - while(!nanocbor_at_end(&values)) { + int num = 0; + int max = 388; /* this is a limit that keeps nanocbor_at_end() from running away */ + while(!nanocbor_at_end(&values) && num < max) { nanocbor_skip(&values); /* key */ nanocbor_skip(&values); /* value */ + //DEBUG("%04d skipping %04x\n", num, values.cur - cfg_page_active_buffer); + num++; } + if(num == max) { + DEBUG("failed to find end: %03x %03x\n", + values.cur - cfg_page_active_buffer, + values.end - cfg_page_active_buffer + ); + od_hex_dump_ext(cfg_page_active_buffer, MTD_SECTOR_SIZE, 16, 0); + return -ENOSPC; + } + nanocbor_leave_container(&reader, &values); /* we are now located at end of space */ /* calculate how much space is left */ amountleft = reader.end - reader.cur; + DEBUG("end is found at num %d with %d left > %d needed\n", num, amountleft, valuelen); if(valuelen > amountleft) { if(tryswap) { DEBUG("cfg_page: did not found space after swap: %u > %u\n", valuelen, amountleft); From fede9cb7a804f423d370d265ca22c5cf69cf505e Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Sun, 31 Oct 2021 20:47:37 -0400 Subject: [PATCH 42/43] cfg_page: name test file TEST4.bin --- tests/driver_cfg_page/maketest4 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/driver_cfg_page/maketest4 b/tests/driver_cfg_page/maketest4 index 4a0fd70f7fda..8ef909a374c8 100755 --- a/tests/driver_cfg_page/maketest4 +++ b/tests/driver_cfg_page/maketest4 @@ -18,7 +18,7 @@ # 65 # text(5) # 68656C6C6F # "hello" -ruby -e 'print "\xff" * 8192;' >TEST3.bin +ruby -e 'print "\xff" * 8192;' >TEST4.bin ( echo "d9 d9 f8 da 52 49 4f 54 43 42 4f 52 " | pretty2cbor.rb @@ -26,7 +26,7 @@ echo "00 " | pretty2cbor.rb # CRC echo "19 c6 3b" | pretty2cbor.rb (echo "bf "; echo "02 82 01 02 "; echo "01 65 68656C6C6F"; echo "ff") | pretty2cbor.rb -) | dd of=TEST3.bin bs=1 seek=0 conv=notrunc status=none +) | dd of=TEST4.bin bs=1 seek=0 conv=notrunc status=none ( echo "d9 d9 f8 da 52 49 4f 54 43 42 4f 52 " | pretty2cbor.rb @@ -37,6 +37,6 @@ echo "19 d6 1a" | pretty2cbor.rb echo "01 65 63 72 65 61 6d"; echo "01 66 62 75 74 74 65 72"; echo "ff") | pretty2cbor.rb -) | dd of=TEST3.bin bs=1 seek=4096 conv=notrunc status=none +) | dd of=TEST4.bin bs=1 seek=4096 conv=notrunc status=none -cp TEST3.bin CONFIG.bin && bin/native/tests_driver_cfg_page.elf +cp TEST4.bin CONFIG.bin && bin/native/tests_driver_cfg_page.elf From 43fc31922ab34f864cde1b5b405681b14ceb6f43 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Sun, 31 Oct 2021 20:49:52 -0400 Subject: [PATCH 43/43] cfg_page: turn off debug --- drivers/cfg_page/cfg_page.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cfg_page/cfg_page.c b/drivers/cfg_page/cfg_page.c index bfb7c87d0038..450a2db0f9ac 100644 --- a/drivers/cfg_page/cfg_page.c +++ b/drivers/cfg_page/cfg_page.c @@ -40,7 +40,7 @@ #include "cfg_page.h" #include "od.h" -#define ENABLE_DEBUG 1 +#define ENABLE_DEBUG 0 #include "debug.h" /* for MTD_1 */