From 4440bcc43a1438671674df122b7aea367dbf2485 Mon Sep 17 00:00:00 2001 From: logicog Date: Thu, 9 Apr 2026 22:32:58 +0200 Subject: [PATCH 1/4] Fix reading configuration over flash block boundaries --- cmd_parser.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index c71ab01..dad3906 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -1165,6 +1165,7 @@ void execute_config(void) __banked strtox(passwd, PASSWORD); save_cmd = 0; + uint8_t cmd_idx = 0; do { flash_region.addr = pos; flash_region.len = FLASH_READ_BURST_SIZE; @@ -1172,21 +1173,23 @@ void execute_config(void) __banked __xdata uint8_t cfg_idx = 0; uint8_t c = 0; - do { - for (uint8_t cmd_idx = 0; cmd_idx < (CMD_BUF_SIZE - 1); cmd_idx++) { - c = flash_buf[cfg_idx++]; - if (c == 0 || c == '\n') { - cmd_buffer[cmd_idx] = '\0'; - if (cmd_idx && !cmd_tokenize()) - cmd_parser(); - if (c == 0) - goto config_done; - break; - } - - cmd_buffer[cmd_idx] = c; + while (cmd_idx < (CMD_BUF_SIZE - 1)) { + c = flash_buf[cfg_idx++]; + if (c == 0 || c == '\n') { + cmd_buffer[cmd_idx] = '\0'; + if (cmd_idx && !cmd_tokenize()) + cmd_parser(); + if (c == 0) + goto config_done; + cmd_idx = 0; + continue; } - } while(cfg_idx); + + cmd_buffer[cmd_idx] = c; + cmd_idx++; + if (!cfg_idx) + break; + } len_left -= FLASH_READ_BURST_SIZE; pos += FLASH_READ_BURST_SIZE; From c3530aaafc152ba674c185f7fb773c53523ae492 Mon Sep 17 00:00:00 2001 From: logicog Date: Tue, 14 Apr 2026 18:00:29 +0200 Subject: [PATCH 2/4] Handle error when configuration file cmd too long --- cmd_parser.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmd_parser.c b/cmd_parser.c index dad3906..8398163 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -1190,6 +1190,13 @@ void execute_config(void) __banked if (!cfg_idx) break; } + if (cmd_idx >= (CMD_BUF_SIZE - 1)) { + cmd_buffer[cmd_idx] = '\0'; + print_string("ERROR: Command too long: "); + print_string_x(cmd_buffer); + write_char('\n'); + goto config_done; + } len_left -= FLASH_READ_BURST_SIZE; pos += FLASH_READ_BURST_SIZE; From 1769528420a40c2889502791c6306aa7d202c85e Mon Sep 17 00:00:00 2001 From: logicog Date: Thu, 16 Apr 2026 20:06:53 +0200 Subject: [PATCH 3/4] Introduce global error variable, check during config execution --- cmd_parser.c | 34 +++++++++++++++++++++------------- rtl837x_common.h | 5 +++++ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index 8398163..ae95d38 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -67,6 +67,8 @@ __xdata signed char cmd_words_b[N_WORDS]; __xdata uint8_t cmd_history[CMD_HISTORY_SIZE]; __xdata uint16_t cmd_history_ptr; +// Error set by commands +__xdata uint8_t err_status; inline uint8_t isletter(uint8_t l) { @@ -860,6 +862,7 @@ uint8_t cmd_tokenize(void) __banked print_string_x(&cmd_buffer[0]); write_char('<'); write_char('\n'); #endif + err_status = ERR_OK; line_ptr = 0; is_white = 1; uint8_t word = 0; @@ -874,11 +877,14 @@ uint8_t cmd_tokenize(void) __banked line_ptr++; if (word >= N_WORDS - 1) { print_string("\ntoo many arguments, truncated"); + err_status = ERR_TOO_MANY_ARGUMENTS; return 1; } } - if (line_ptr == CMD_BUF_SIZE - 1) + if (line_ptr == CMD_BUF_SIZE - 1) { + err_status = ERR_CMD_TOO_LONG; return 1; + } cmd_words_b[word++] = line_ptr; cmd_words_b[word++] = -1; @@ -1173,12 +1179,23 @@ void execute_config(void) __banked __xdata uint8_t cfg_idx = 0; uint8_t c = 0; - while (cmd_idx < (CMD_BUF_SIZE - 1)) { + do { + if (cmd_idx >= (CMD_BUF_SIZE - 1)) { + cmd_buffer[cmd_idx] = '\0'; + print_string("ERROR: Command too long: "); + print_string_x(cmd_buffer); + write_char('\n'); + err_status = ERR_CMD_TOO_LONG; + goto config_done; + } c = flash_buf[cfg_idx++]; if (c == 0 || c == '\n') { cmd_buffer[cmd_idx] = '\0'; - if (cmd_idx && !cmd_tokenize()) + if (cmd_idx && !cmd_tokenize()) { cmd_parser(); + if (err_status) + goto config_done; + } if (c == 0) goto config_done; cmd_idx = 0; @@ -1187,16 +1204,7 @@ void execute_config(void) __banked cmd_buffer[cmd_idx] = c; cmd_idx++; - if (!cfg_idx) - break; - } - if (cmd_idx >= (CMD_BUF_SIZE - 1)) { - cmd_buffer[cmd_idx] = '\0'; - print_string("ERROR: Command too long: "); - print_string_x(cmd_buffer); - write_char('\n'); - goto config_done; - } + } while (cfg_idx); len_left -= FLASH_READ_BURST_SIZE; pos += FLASH_READ_BURST_SIZE; diff --git a/rtl837x_common.h b/rtl837x_common.h index c69d303..4fc8b8c 100644 --- a/rtl837x_common.h +++ b/rtl837x_common.h @@ -42,6 +42,11 @@ extern __xdata uint8_t sbuf[SBUF_SIZE]; // Size of the flash buffer used for writing to flash, must be a multiple of the flash page size (0x100) #define FLASH_BUF_SIZE 512 +// Errors for commands +#define ERR_OK 0 +#define ERR_TOO_MANY_ARGUMENTS 1 +#define ERR_CMD_TOO_LONG 2 + // For RX data, a propriatary RTL FRAME is inserted. Instead of 0x0800 for IPv4, // the RTL_FRAME_TAG_ID is used as part of an 8-byte tag. When VLAN is activated, // the VLAN tag is inserted after the RTL tag From e2717ef7ca7dc0e6aff4f8efd31a8faa7ed1b4f5 Mon Sep 17 00:00:00 2001 From: logicog Date: Fri, 17 Apr 2026 06:39:04 +0200 Subject: [PATCH 4/4] Count pages instead of bytes reading config in execute_config() --- cmd_parser.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index ae95d38..a63fec7 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -1162,10 +1162,14 @@ void clear_command_history(void) __banked #define FLASH_READ_BURST_SIZE 0x100 #define PASSWORD "1234" + +#if CONFIG_LEN % FLASH_READ_BURST_SIZE + #error "CONFIG_LEN not a multiple of FLASH_READ_BURST_SIZE" +#endif void execute_config(void) __banked { __xdata uint32_t pos = CONFIG_START; - __xdata uint16_t len_left = CONFIG_LEN; + __xdata uint8_t pages_left = CONFIG_LEN / FLASH_READ_BURST_SIZE; // Set default password, it can be overwritten in the configuration file strtox(passwd, PASSWORD); @@ -1206,9 +1210,9 @@ void execute_config(void) __banked cmd_idx++; } while (cfg_idx); - len_left -= FLASH_READ_BURST_SIZE; + pages_left--; pos += FLASH_READ_BURST_SIZE; - } while(len_left); + } while(pages_left); config_done: // Start saving commands to cmd_history