From 4440bcc43a1438671674df122b7aea367dbf2485 Mon Sep 17 00:00:00 2001 From: logicog Date: Thu, 9 Apr 2026 22:32:58 +0200 Subject: [PATCH 01/42] 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 41f0dad49dffb02e96544194b07594ebd229afdd Mon Sep 17 00:00:00 2001 From: feelfree69 Date: Mon, 13 Apr 2026 14:55:10 +0200 Subject: [PATCH 02/42] Add ability to assign a name to a port --- cmd_parser.c | 53 ++++++++++++++++++++++++++++++++++++----------- cmd_parser.h | 1 + html/main.js | 10 +++++++-- html/ports.html | 2 +- html/ports.js | 4 +++- html/stat.html | 2 +- html/stat.js | 12 ++++++----- httpd/page_impl.c | 6 ++++++ rtl837x_common.h | 3 +++ rtl837x_phy.c | 13 +++++++----- 10 files changed, 79 insertions(+), 27 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index 209a689..50c41e9 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -43,6 +43,9 @@ extern __xdata struct dhcp_state dhcp_state; __xdata uint8_t vlan_names[VLAN_NAMES_SIZE]; __xdata uint16_t vlan_ptr; + +__xdata char port_names[9][PORT_NAME_SIZE]; + extern __xdata uint16_t management_vlan; __xdata uint8_t gpio_last_value[8] = { 0 }; @@ -514,20 +517,47 @@ void parse_mirror(void) void parse_port(void) { - print_string("\nPORT "); + if (cmd_words_b[3] <= 0) { + print_string("\nUsage:"); + print_string("\nport [show|on|off]"); + print_string("\nport [10m|100m|1g|2g5|duplex] [half|full]"); + print_string("\nport name [custom port name]\n"); + return; + } + + if (cmd_buffer[cmd_words_b[1]] < '1' || cmd_buffer[cmd_words_b[1]] > '9' || cmd_buffer[cmd_words_b[1] + 1] != ' ' ) { + print_string("Illegal port number\n"); + return; + } phy_settings.port = cmd_buffer[cmd_words_b[1]] - '1'; phy_settings.port = machine.phys_to_log_port[phy_settings.port]; - print_byte(phy_settings.port); - if (machine.is_sfp[phy_settings.port]) { - print_string(" is SFP no PHY information available.\n"); - return; - } - if (cmd_words_b[2] <= 0) { - print_string("\nport [show|on|off|10m|100m|1g|2g5] [half|full]"); + if (phy_settings.port > machine.max_port || phy_settings.port < machine.min_port) { + print_string("This machine has no port with the specified number\n"); return; } + + print_string("Logical Port: "); print_byte(phy_settings.port); write_char('\n'); phy_settings.duplex = PHY_DUPLEX_BOTH; - if (cmd_compare(2, "10m")) { + + if (cmd_compare(2, "show")) { + print_string("Name: "); + print_string_x(port_names[phy_settings.port]); + if (!machine.is_sfp[phy_settings.port]) { + phy_show(phy_settings.port); + } + } else if (cmd_compare(2, "name")) { + uint8_t i = 0; + while ( (i < PORT_NAME_SIZE-1) && (cmd_buffer[cmd_words_b[3] + i] != '\0') ) { + port_names[phy_settings.port][i] = cmd_buffer[cmd_words_b[3] + i]; + i++; + } + port_names[phy_settings.port][i] = '\0'; + print_string("\nName set to: \""); + print_string_x(port_names[phy_settings.port]); + print_string("\"\n"); + } else if (machine.is_sfp[phy_settings.port]) { + print_string(" is SFP no PHY information available.\n"); + } else if (cmd_compare(2, "10m")) { print_string(" 10M\n"); phy_settings.speed = PHY_SPEED_10M; if (cmd_compare(3, "half")) @@ -570,9 +600,8 @@ void parse_port(void) else phy_settings.speed = PHY_DUPLEX_HALF; phy_set_duplex(); - } - if (cmd_compare(2, "show")) { - phy_show(phy_settings.port); + } else { + print_string("Unknown port command\n"); } } diff --git a/cmd_parser.h b/cmd_parser.h index dff8cf8..f35b2e8 100644 --- a/cmd_parser.h +++ b/cmd_parser.h @@ -7,6 +7,7 @@ extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE]; extern __xdata uint8_t cmd_available; +extern __xdata char port_names[9][PORT_NAME_SIZE]; uint8_t cmd_tokenize(void) __banked; void cmd_parser(void) __banked; diff --git a/html/main.js b/html/main.js index b29ccbe..1eb3f88 100644 --- a/html/main.js +++ b/html/main.js @@ -9,6 +9,7 @@ var pAdvertised = new Int8Array(10); var numPorts = 0; var logToPhysPort = new Int8Array(10); var physToLogPort = new Int8Array(10); +var portNames = new Array(10); var currentRequests = []; var currentCallback; function drawPorts() { @@ -136,6 +137,7 @@ function update(callback) { let n = p.portNum; logToPhysPort[p.logPort] = n; physToLogPort[n-1] = p.logPort; + portNames[p.logPort] = p.name; let pid = "port" + n; let ttid = "tt_" + n; n--; @@ -148,12 +150,17 @@ function update(callback) { var leds = psvg.contentDocument.getElementsByClassName("led"); if (leds[0] == null || leds[0].style == null) continue; + const portName = p.name || portNames[p.logPort] || ''; + var iHTML = ""; + iHTML += ""; if (p.enabled == 0) { pState[n] = -1; bgs[0].style.fill = "red"; leds[0].style.fill = "black"; leds[1].style.fill = "black"; psvg.style.opacity = 0.4; - tt.innerHTML = "Not enabled."; + iHTML += ""; + iHTML += "
Name:" + portName + "
Status:Not enabled.
"; + tt.innerHTML = iHTML; } else { psvg.style.opacity = 1.0; pState[n] = p.link; @@ -165,7 +172,6 @@ function update(callback) { leds[0].style.fill = "black"; leds[1].style.fill = "black"; psvg.style.opacity = 0.4 } - var iHTML = ""; iHTML += ""; if (p.isSFP) { pAdvertised[n] = 0; diff --git a/html/ports.html b/html/ports.html index 84fe41e..9e27808 100644 --- a/html/ports.html +++ b/html/ports.html @@ -11,7 +11,7 @@

Port Configuration

Link speed:" + linkS[p.link + 1] + "
- +
Port Current Link SpeedSet SpeedDisabledApply
Port Name Current Link SpeedSet SpeedDisabledApply

Configure Maximum Frame Size (MTU) forwarded at Port

diff --git a/html/ports.js b/html/ports.js index dedd741..6fc4f40 100644 --- a/html/ports.js +++ b/html/ports.js @@ -19,6 +19,8 @@ function createPortTable() { console.log("Table row: " + i + "pState: " + pState[i-2]); const tr = tbl.insertRow(); let td = tr.insertCell(); td.appendChild(document.createTextNode(`Port ${i}`)); + let portName = portNames[physToLogPort[i-1]] || ''; + td = tr.insertCell(); td.appendChild(document.createTextNode(portName)); td = tr.insertCell(); td.innerHTML = linkS[pState[i] + 1]; td = tr.insertCell(); td.innerHTML = sSelect.replaceAll("speed_sel", "speed_sel_" + i); td = tr.insertCell(); td.innerHTML = dSwitch.replaceAll("disable_port", "disable_port_" + i) @@ -66,7 +68,7 @@ function updatePortTable() { for (let i = 1; i <= numPorts ; i++) { if (pIsSFP[i-1]) continue; - tbl.rows[i].cells[1].innerHTML = `${linkS[pState[i-1]+1]}`; + tbl.rows[i].cells[2].innerHTML = `${linkS[pState[i-1]+1]}`; if (!clicked[i] && pState[i - 1] < 0) { document.getElementById('speed_sel_' + i).disabled = true; document.getElementById('disable_port_' + i).checked = true; diff --git a/html/stat.html b/html/stat.html index cb5cbfe..03b0367 100644 --- a/html/stat.html +++ b/html/stat.html @@ -38,7 +38,7 @@

Port Statistics

- +
Port link TX Good TX Bad RX Good RX Bad All Counters
Port Name link TX Good TX Bad RX Good RX Bad All Counters
diff --git a/html/stat.js b/html/stat.js index 51a7e10..8cb2afc 100644 --- a/html/stat.js +++ b/html/stat.js @@ -162,17 +162,19 @@ function fillStats() { if (tbl.rows.length > 1) { for (let i = 0; i < numPorts; i++) { console.log("Table Update row: " + i + " state " + pState[i] + " is " + linkS[pState[i] +1]); - tbl.rows[i+1].cells[1].innerHTML = `${linkS[pState[i]+1]}`; - tbl.rows[i+1].cells[2].innerHTML = `${txG[i]} pkts`; - tbl.rows[i+1].cells[3].innerHTML = `${txB[i]} pkts`; - tbl.rows[i+1].cells[4].innerHTML = `${rxG[i]} pkts`; - tbl.rows[i+1].cells[5].innerHTML = `${rxB[i]} pkts`; + tbl.rows[i+1].cells[2].innerHTML = `${linkS[pState[i]+1]}`; + tbl.rows[i+1].cells[3].innerHTML = `${txG[i]} pkts`; + tbl.rows[i+1].cells[4].innerHTML = `${txB[i]} pkts`; + tbl.rows[i+1].cells[5].innerHTML = `${rxG[i]} pkts`; + tbl.rows[i+1].cells[6].innerHTML = `${rxB[i]} pkts`; } } else { for (let i = 0; i < numPorts; i++) { console.log("Table row: " + i); const tr = tbl.insertRow(); let td = tr.insertCell(); td.appendChild(document.createTextNode(`Port ${i+1}`)); + let portName = portNames[physToLogPort[i]] || ''; + td = tr.insertCell(); td.appendChild(document.createTextNode(portName)); td = tr.insertCell(); td.appendChild(document.createTextNode(`${linkS[pState[i]+1]}`)); td = tr.insertCell(); td.appendChild(document.createTextNode(`${txG[i]} pkts`)); td = tr.insertCell();td.appendChild(document.createTextNode(`${txB[i]} pkts`)); diff --git a/httpd/page_impl.c b/httpd/page_impl.c index b49f356..b259221 100644 --- a/httpd/page_impl.c +++ b/httpd/page_impl.c @@ -13,6 +13,7 @@ #include "version.h" #include "machine.h" #include "page_impl.h" +#include "cmd_parser.h" // #define DEBUG #include "debug.h" @@ -633,6 +634,11 @@ void send_status(void) itoa_html(machine.log_to_phys_port[i]); slen += strtox(outbuf + slen, ",\"logPort\":"); itoa_html(i); + slen += strtox(outbuf + slen, ",\"name\":\""); + for (uint8_t j = 0; j < PORT_NAME_SIZE && port_names[i][j]; j++) { + char_to_html(port_names[i][j]); + } + slen += strtox(outbuf + slen, "\""); if (machine.is_sfp[i]) { slen += strtox(outbuf + slen, ",\"isSFP\":1,\"enabled\":"); diff --git a/rtl837x_common.h b/rtl837x_common.h index d34d02d..be03429 100644 --- a/rtl837x_common.h +++ b/rtl837x_common.h @@ -36,6 +36,9 @@ extern __xdata uint8_t sbuf[SBUF_SIZE]; // Size of the TCP Output buffer #define TCP_OUTBUF_SIZE 2500 +// Size of the port name, including the terminating null byte +#define PORT_NAME_SIZE 32 + // Size of the memory area dedicated to VLAN-names #define VLAN_NAMES_SIZE 1024 diff --git a/rtl837x_phy.c b/rtl837x_phy.c index 0846e9c..994551c 100644 --- a/rtl837x_phy.c +++ b/rtl837x_phy.c @@ -367,12 +367,15 @@ void phy_show(uint8_t port) __banked print_string("5G"); break; default: - print_string("10M"); + print_string("Down"); + } + + if ( (((v & 0x0600) >> 7) | ((v & 0x0030) >> 4)) <= 6) { // Link is up + if (v & 0x8) + print_string(" full duplex"); + else + print_string(" half duplex"); } - if (v & 0x8) - print_string(" full duplex"); - else - print_string(" half duplex"); phy_read(port, PHY_MMD_AN, PHY_ANEG_CTRL); v = SFR_DATA_U16; From e130777b2491aed4de9f32f055b1e6d3ab4f978b Mon Sep 17 00:00:00 2001 From: feelfree69 Date: Mon, 13 Apr 2026 14:55:50 +0200 Subject: [PATCH 03/42] serial console cosmetic change --- rtlplayground.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtlplayground.c b/rtlplayground.c index f0cf525..2da920e 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -1974,7 +1974,7 @@ void check_and_flash_update_image(void) __xdata uint16_t i = 0; __xdata uint16_t j = 0; __xdata uint8_t * __xdata bptr; - print_string("found update image! Checking integrity"); + print_string("found update image!\nChecking integrity"); flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing will fail set_sys_led_state(SYS_LED_FAST); crc_value = 0x0000; From b7ad67d336b53e44d291799a59009f6e6c9770d9 Mon Sep 17 00:00:00 2001 From: logicog Date: Fri, 10 Apr 2026 08:00:50 +0200 Subject: [PATCH 04/42] Make port isolation API available --- rtl837x_port.c | 4 ++-- rtl837x_port.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/rtl837x_port.c b/rtl837x_port.c index aa91a7a..4c12a51 100644 --- a/rtl837x_port.c +++ b/rtl837x_port.c @@ -463,14 +463,14 @@ void port_stats_print(void) __banked } -void port_isolate(register uint8_t port, __xdata uint16_t pmask) +void port_isolate(register uint8_t port, __xdata uint16_t pmask) __banked { if (port <= machine.max_port) REG_SET(RTL837X_PORT_ISOLATION_BASE + (port << 2), pmask); } -uint16_t port_isolation_get(register uint8_t port) +uint16_t port_isolation_get(register uint8_t port) __banked { if (port > machine.max_port) return 0; diff --git a/rtl837x_port.h b/rtl837x_port.h index 20132fb..9be1680 100644 --- a/rtl837x_port.h +++ b/rtl837x_port.h @@ -61,4 +61,7 @@ void port_eee_status(uint8_t port) __banked; void print_port_ingress_filter_mode(vlan_ingress_mode_t mode) __banked; bool port_ingress_vlan_filter_set(__xdata uint8_t port, __xdata bool enabled) __banked; bool port_ingress_vlan_filter_get(__xdata uint8_t port) __banked; +void port_isolate(register uint8_t port, __xdata uint16_t pmask) __banked; +uint16_t port_isolation_get(register uint8_t port) __banked; + #endif From b31179acbed72f60fb24fa24d54727993b8ea2dc Mon Sep 17 00:00:00 2001 From: feelfree69 Date: Mon, 13 Apr 2026 19:14:24 +0200 Subject: [PATCH 05/42] move extern declaration for port_names to trl837x_common.h --- cmd_parser.h | 1 - httpd/page_impl.c | 1 - rtl837x_common.h | 2 ++ 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd_parser.h b/cmd_parser.h index f35b2e8..dff8cf8 100644 --- a/cmd_parser.h +++ b/cmd_parser.h @@ -7,7 +7,6 @@ extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE]; extern __xdata uint8_t cmd_available; -extern __xdata char port_names[9][PORT_NAME_SIZE]; uint8_t cmd_tokenize(void) __banked; void cmd_parser(void) __banked; diff --git a/httpd/page_impl.c b/httpd/page_impl.c index b259221..270ddb3 100644 --- a/httpd/page_impl.c +++ b/httpd/page_impl.c @@ -13,7 +13,6 @@ #include "version.h" #include "machine.h" #include "page_impl.h" -#include "cmd_parser.h" // #define DEBUG #include "debug.h" diff --git a/rtl837x_common.h b/rtl837x_common.h index be03429..293c755 100644 --- a/rtl837x_common.h +++ b/rtl837x_common.h @@ -98,6 +98,8 @@ struct flash_region_t { uint16_t len; }; +extern __xdata char port_names[9][PORT_NAME_SIZE]; + extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2]; extern __xdata struct uip_eth_addr uip_ethaddr; From 036d9ca229992419ce4bbabc985a475c0ba2530d Mon Sep 17 00:00:00 2001 From: logicog Date: Fri, 10 Apr 2026 08:01:02 +0200 Subject: [PATCH 06/42] Add port isolation cmd --- cmd_parser.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/cmd_parser.c b/cmd_parser.c index 209a689..bda1910 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -371,6 +371,74 @@ err: print_string("Error: vlan (|show) [port][t/u]...\n"); } + +void parse_isolate(void) +{ + __xdata uint16_t members = 0; + + if (cmd_words_b[3] <= 0) + goto err; + + print_string("\nISOLATE "); + + __xdata int8_t port_configured = cmd_buffer[cmd_words_b[1]] - '1'; + port_configured = machine.phys_to_log_port[port_configured]; + if (isnumber(cmd_buffer[cmd_words_b[1] + 1])) // CPU-port, logical port 9 + port_configured = (port_configured + 1) * 10 + cmd_buffer[cmd_words_b[1] + 1] - '1'; + if (port_configured < 0 || port_configured > 9) + goto err; + + print_byte(port_configured); write_char('\n'); + + if (cmd_compare(2, "show")) { + members = port_isolation_get(port_configured); + for (uint8_t i = 0; i < 10; i++) { + if (members & 1) { + if (i < 9) + write_char(machine.log_to_phys_port[i] + '0'); + else + print_string("CPU"); + write_char(' '); + } + members >>= 1; + } + return; + } + + if (cmd_compare(2, "off")) { + for (uint8_t i = machine.min_port; i < machine.max_port; i++) + members |= ((uint16_t)1) << i; + members |= 0x200; // CPU-port + port_isolate(port_configured, members); + return; + } + + uint8_t w = 2; + while (cmd_words_b[w] > 0) { + __xdata uint8_t port; + if (isnumber(cmd_buffer[cmd_words_b[w]])) { + port = cmd_buffer[cmd_words_b[w]] - '1'; + if (isnumber(cmd_buffer[cmd_words_b[w] + 1])) { + port = (port + 1) * 10 + cmd_buffer[cmd_words_b[w] + 1] - '1'; // logical port + if (port != 9) // CPU port is logical port 9 + goto err; + } else { + port = machine.phys_to_log_port[port]; + if (port < machine.min_port || port > machine.max_port) + goto err; + } + members |= ((uint16_t)1) << port; + } + w++; + } + port_isolate(port_configured, members); + return; + +err: + print_string("Error: isolate [show|off] [port]...\n"); +} + + bool vlan_ingress_mode_parse(char c, vlan_ingress_mode_t *mode) { switch (c) { @@ -1289,6 +1357,8 @@ void cmd_parser(void) __banked port_pvid_set(port, pvid); } else if (cmd_compare(0, "vlan")) { parse_vlan(); + } else if (cmd_compare(0, "isolate")) { + parse_isolate(); } else if (cmd_compare(0, "mirror")) { parse_mirror(); } else if (cmd_compare(0, "lag")) { From 1683eef94b2696a8f36af792cf85387c3a9ec471 Mon Sep 17 00:00:00 2001 From: logicog Date: Tue, 14 Apr 2026 05:16:45 +0200 Subject: [PATCH 07/42] Fix bug where cmd_words[] is not properly initialized --- cmd_parser.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd_parser.c b/cmd_parser.c index bda1910..4523848 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -1146,7 +1146,10 @@ uint8_t cmd_tokenize(void) __banked line_ptr = 0; is_white = 1; uint8_t word = 0; - cmd_words_b[0] = -1; + + for (uint8_t i = 0; i < N_WORDS; i++) + cmd_words_b[i] = -1; + while (cmd_buffer[line_ptr] && line_ptr < CMD_BUF_SIZE - 1) { if (is_white && cmd_buffer[line_ptr] != ' ') { is_white = 0; From c3530aaafc152ba674c185f7fb773c53523ae492 Mon Sep 17 00:00:00 2001 From: logicog Date: Tue, 14 Apr 2026 18:00:29 +0200 Subject: [PATCH 08/42] 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 2565aeadf4ccddc4c1cec60115dedfc7b74f44da Mon Sep 17 00:00:00 2001 From: feelfree69 Date: Tue, 14 Apr 2026 18:28:13 +0200 Subject: [PATCH 09/42] Do no show empty names in tooltips --- html/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html/main.js b/html/main.js index 1eb3f88..8e50017 100644 --- a/html/main.js +++ b/html/main.js @@ -152,7 +152,7 @@ function update(callback) { continue; const portName = p.name || portNames[p.logPort] || ''; var iHTML = ""; - iHTML += ""; + if (portName) iHTML += ""; if (p.enabled == 0) { pState[n] = -1; bgs[0].style.fill = "red"; From 1769528420a40c2889502791c6306aa7d202c85e Mon Sep 17 00:00:00 2001 From: logicog Date: Thu, 16 Apr 2026 20:06:53 +0200 Subject: [PATCH 10/42] 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 11/42] 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 From 80ff1b25c9435b553568b817f821589cc8ce8501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 17 Apr 2026 21:30:58 +0200 Subject: [PATCH 12/42] Improve: cmd_compare(). Because `cmd` is guaranteed by the compiler to be NULL-terminated, we can make use of that to ensure the loop always ends. So we don't need to know when the next words starts. --- cmd_parser.c | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index c56105e..675c04b 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -92,26 +92,35 @@ inline uint8_t isnumber(uint8_t l) } -uint8_t cmd_compare(uint8_t start, uint8_t * __code cmd) +uint8_t cmd_compare(uint8_t start, __code uint8_t * cmd) { - if ((start > 0) && (cmd_words_b[start] <= 0) )// nothing on this word -> no match + if (cmd_words_len == 0 || start > (cmd_words_len - 1)) { return 0; - - signed char i; - signed char j = 0; - for (i = cmd_words_b[start]; i != cmd_words_b[start + 1] && cmd_buffer[i] != ' '; i++) { - i &= CMD_BUF_SIZE - 1; -// print_byte(i); write_char(':'); print_byte(j); write_char('#'); print_string("\n"); -// write_char('>'); write_char(cmd[j]); write_char('-'); write_char(cmd_buffer[i]); print_string("\n"); - if (!cmd[j]) // end of command reached, but cmd_buffer has more characters, so no match - return 0; - if (cmd_buffer[i] != cmd[j++]) - break; } -// write_char('.'); print_byte(i); write_char(':'); print_byte(j); write_char(','); print_byte (cmd[j-1]); -// write_char(','); print_byte(cmd[j]); - if ( ((i == cmd_words_b[start + 1]) || (cmd_buffer[i] == ' ')) && !cmd[j]) // next word reached and command fully matched - return 1; + uint8_t i = cmd_words_b[start]; + uint8_t j = 0; + + do { + uint8_t c = cmd[j]; + uint8_t b = cmd_buffer[i]; + + // cmd is garanteerd to be NULL-terminated. + if (c == '\0') { + if ((b == ' ') || (b == '\0')) { + // Match + return 1; + } + break; + } + if (b != c) { + break; + } + + j += 1; + i += 1; + } while (i < CMD_BUF_SIZE); + + // No match return 0; } From 8cbafaa34757d8ef37c22806e762acc9522a4e96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 17 Apr 2026 22:29:34 +0200 Subject: [PATCH 13/42] Change cmd_tokenize() it only stores valid locations and use a length field. --- cmd_parser.c | 63 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index 675c04b..1a11b36 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -58,14 +58,17 @@ __xdata uint8_t hexvalue[4] = { 0 }; __xdata uint8_t cmd_buffer[CMD_BUF_SIZE]; __xdata uint8_t cmd_available; -__xdata uint8_t line_ptr; -__xdata char is_white; __xdata char save_cmd; __xdata uint8_t ip[4]; -#define N_WORDS CMD_BUF_SIZE -__xdata signed char cmd_words_b[N_WORDS]; +// These variables combined create a Fixed-capacity vector/bounded buffer. +// `N_WORDS`: The total number of command arguments that can be tracked. +// `cmd_words_len` stores the number of arguments found inside `cmd_buffer` +// `cmd_words_b` stores the index into `cmd_buffer`, check `cmd_words_len` is index is valid. +#define N_WORDS 15 +__xdata uint8_t cmd_words_len; +__xdata uint8_t cmd_words_b[N_WORDS]; __xdata uint8_t cmd_history[CMD_HISTORY_SIZE]; __xdata uint16_t cmd_history_ptr; @@ -1176,6 +1179,8 @@ err: } // Parse command into words +// cmd_words_len contains the number of words found. +// cmd_words_b[] contains only start of a word offset. uint8_t cmd_tokenize(void) __banked { #ifdef DEBUG @@ -1184,33 +1189,41 @@ uint8_t cmd_tokenize(void) __banked write_char('<'); write_char('\n'); #endif err_status = ERR_OK; - line_ptr = 0; - is_white = 1; + uint8_t line_ptr = 0; + uint8_t is_white = 1; uint8_t word = 0; + uint8_t c = 0; - for (uint8_t i = 0; i < N_WORDS; i++) - cmd_words_b[i] = -1; - - while (cmd_buffer[line_ptr] && line_ptr < CMD_BUF_SIZE - 1) { - if (is_white && cmd_buffer[line_ptr] != ' ') { - is_white = 0; - cmd_words_b[word++] = line_ptr; + while(1) { + c = cmd_buffer[line_ptr]; + + if (c == '\0') { + // Store the word count + cmd_words_len = word; + break; } - if (cmd_buffer[line_ptr] == ' ') - is_white = 1; - line_ptr++; - if (word >= N_WORDS - 1) { - print_string("\ntoo many arguments, truncated"); - err_status = ERR_TOO_MANY_ARGUMENTS; + + if (line_ptr == CMD_BUF_SIZE - 1) { + err_status = ERR_CMD_TOO_LONG; return 1; } + + if (is_white && c != ' ') { + is_white = 0; + + cmd_words_b[word++] = line_ptr; + if (word >= N_WORDS) { + cmd_words_len = 0; + print_string("\ntoo many arguments, truncated"); + err_status = ERR_TOO_MANY_ARGUMENTS; + return 1; + } + } else if (c == ' ') { + is_white = 1; + } + + line_ptr++; } - 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; return 0; } From 1156f00f9583fdf3186c88f53b6b2e242bf10894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 17 Apr 2026 22:51:31 +0200 Subject: [PATCH 14/42] cmd_parser() make use of cmd_words_len --- cmd_parser.c | 91 +++++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index 1a11b36..11077aa 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -1274,6 +1274,7 @@ void cmd_parser(void) __banked print_string_x(&cmd_buffer[0]); write_char('<'); write_char('\n'); print_string("CMD-words: "); + print_byte(cmd_words_len); write_char(' '); print_byte(cmd_words_b[0]); write_char(' '); print_byte(cmd_words_b[1]); write_char(' '); print_byte(cmd_words_b[2]); write_char(' '); @@ -1282,7 +1283,7 @@ void cmd_parser(void) __banked print_byte(cmd_words_b[5]); write_char(' '); print_byte(cmd_words_b[6]); write_char('\n'); #endif - if (cmd_words_b[0] >= 0 && cmd_words_b[1] >= 0) { + if (cmd_words_len >= 1) { if (cmd_compare(0, "reset")) { print_string("\nRESET\n\n"); reset_chip(); @@ -1301,35 +1302,38 @@ void cmd_parser(void) __banked } } else if (cmd_compare(0, "stat")) { port_stats_print(); - } else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 's') { - print_string("\nSECURITY REGISTERS\n"); - // The following will only show something else than 0xff if it was programmed for a managed switch - print_string("Region 1: "); - flash_region.addr = 0x0001000; - flash_region.len = 40; - flash_read_security(); - print_string("\nRegion 2: "); - flash_region.addr = 0x0002000; - flash_region.len = 40; - flash_read_security(); - print_string("\nRegion 3: "); - flash_region.addr = 0x0003000; - flash_region.len = 40; - flash_read_security(); - } else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'j') { - print_string("\nJEDEC ID\n"); - flash_read_jedecid(); - } else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'u') { - print_string("\nUNIQUE ID (note: only 4 bytes are likely correct here!)\n"); - flash_read_uid(); - } else if (cmd_compare(0, "port") && cmd_words_b[1] > 0) { + } else if (cmd_compare(0, "flash") && cmd_words_len == 2) { + uint8_t c = cmd_buffer[cmd_words_b[1]]; + if (c == 's') { + print_string("\nSECURITY REGISTERS\n"); + // The following will only show something else than 0xff if it was programmed for a managed switch + print_string("Region 1: "); + flash_region.addr = 0x0001000; + flash_region.len = 40; + flash_read_security(); + print_string("\nRegion 2: "); + flash_region.addr = 0x0002000; + flash_region.len = 40; + flash_read_security(); + print_string("\nRegion 3: "); + flash_region.addr = 0x0003000; + flash_region.len = 40; + flash_read_security(); + } else if (c == 'j') { + print_string("\nJEDEC ID\n"); + flash_read_jedecid(); + } else if (c == 'u') { + print_string("\nUNIQUE ID (note: only 4 bytes are likely correct here!)\n"); + flash_read_uid(); + } + } else if (cmd_compare(0, "port")) { parse_port(); - } else if (cmd_compare(0, "mtu") && cmd_words_b[1] > 0) { + } else if (cmd_compare(0, "mtu")) { parse_mtu(); } else if (cmd_compare(0, "ip")) { if (cmd_compare(1, "dhcp")) { dhcp_start(); - } else if (cmd_words_b[2] < 0) { + } else if (cmd_words_len == 1) { print_string("Current IP: "); itoa(uip_hostaddr[0]); write_char('.'); itoa(uip_hostaddr[0] >> 8); write_char('.'); itoa(uip_hostaddr[1]); write_char('.'); itoa(uip_hostaddr[1] >> 8); @@ -1357,7 +1361,7 @@ void cmd_parser(void) __banked } } } else if (cmd_compare(0, "gw")) { - if (cmd_words_b[2] < 0) { + if (cmd_words_len == 1) { print_string("Current gw: "); itoa(uip_draddr[0]); write_char('.'); itoa(uip_draddr[0] >> 8); write_char('.'); itoa(uip_draddr[1]); write_char('.'); itoa(uip_draddr[1] >> 8); @@ -1372,7 +1376,7 @@ void cmd_parser(void) __banked } write_char('\n'); } else if (cmd_compare(0, "netmask")) { - if (cmd_words_b[2] < 0) { + if (cmd_words_len == 1) { print_string("Current netmask: "); itoa(uip_netmask[0]); write_char('.'); itoa(uip_netmask[0] >> 8); write_char('.'); itoa(uip_netmask[1]); write_char('.'); itoa(uip_netmask[1] >> 8); @@ -1408,7 +1412,7 @@ void cmd_parser(void) __banked stp_off(); stpEnabled = 0; } - } else if (cmd_compare(0, "pvid") && cmd_words_b[1] > 0 && cmd_words_b[2] > 0) { + } else if (cmd_compare(0, "pvid") && cmd_words_len == 3) { __xdata uint16_t pvid; uint8_t port; port = cmd_buffer[cmd_words_b[1]] - '1'; @@ -1478,22 +1482,21 @@ void cmd_parser(void) __banked } - if (save_cmd) { - uint8_t i; - for (i = 0; i < N_WORDS; i++) { - if (cmd_words_b[i] < 0) - break; - } - if (i < N_WORDS) { - i = cmd_words_b[--i]; - cmd_history_ptr = (cmd_history_ptr + i) & CMD_HISTORY_MASK; - __xdata uint16_t p = cmd_history_ptr; - cmd_history[cmd_history_ptr++] = '\n'; - do { - i--; - cmd_history[--p & CMD_HISTORY_MASK] = cmd_buffer[i]; - } while (i); - } + if (save_cmd && cmd_words_len) { + // Find end of the cmd-buffer, looking for the NULL-byte. + uint8_t i = cmd_words_b[cmd_words_len - 1]; + do { + i++; + } while(cmd_buffer[i] != '\0'); + + // Copy last cmd-buffer to history. + cmd_history_ptr = (cmd_history_ptr + i) & CMD_HISTORY_MASK; + __xdata uint16_t p = cmd_history_ptr; + cmd_history[cmd_history_ptr++] = '\n'; + do { + i--; + cmd_history[--p & CMD_HISTORY_MASK] = cmd_buffer[i]; + } while (i); } } } From 301577efc80536437ea77f287881ec273aebdf15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 17 Apr 2026 23:00:41 +0200 Subject: [PATCH 15/42] parse_vlan() make use of cmd_words_len. --- cmd_parser.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index 11077aa..34c0321 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -327,7 +327,7 @@ void parse_vlan(void) vlan_settings.members = 0; vlan_settings.tagged = 0; if (!atoi_short(&vlan_settings.vlan, cmd_words_b[1])) { - if (cmd_words_b[2] > 0 && cmd_buffer[cmd_words_b[2]] == 'd' && cmd_words_b[3] < 0) { + if (cmd_words_len == 3 && cmd_buffer[cmd_words_b[2]] == 'd') { vlan_delete(vlan_settings.vlan); return; } @@ -340,7 +340,7 @@ void parse_vlan(void) return; } uint8_t w = 2; - if (cmd_words_b[w] > 0 && isletter(cmd_buffer[cmd_words_b[w]])) { + if (cmd_words_len > w && isletter(cmd_buffer[cmd_words_b[w]])) { register uint8_t i = 0; vlan_names[vlan_ptr++] = hex[(vlan_settings.vlan >> 8) & 0xf]; vlan_names[vlan_ptr++] = hex[(vlan_settings.vlan >> 4) & 0xf] ; @@ -353,7 +353,7 @@ void parse_vlan(void) w++; print_string("<\n"); } - while (cmd_words_b[w] > 0) { + while (cmd_words_len > w) { __xdata uint8_t port; if (isnumber(cmd_buffer[cmd_words_b[w]])) { port = cmd_buffer[cmd_words_b[w]] - '1'; @@ -373,13 +373,13 @@ void parse_vlan(void) w++; } vlan_create(); - } else if (cmd_words_b[1] > 0 && cmd_compare(1, "show")) { + } else if (cmd_compare(1, "show")) { vlan_dump(); } else { goto err; } - if (cmd_words_b[2] > 0 && isletter(cmd_buffer[cmd_words_b[2]])) { + if (cmd_words_len >= 3 && isletter(cmd_buffer[cmd_words_b[2]])) { print_string("vlan_ptr "); print_short(vlan_ptr); write_char(':'); write_char('>'); print_string_x(&vlan_names[0]); write_char('<'); write_char('\n'); } From 2cdab5f9d903826683aad83dd99cbf4c9aefdce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 17 Apr 2026 23:02:25 +0200 Subject: [PATCH 16/42] parse_reg{set,get}() make use cmd_words_len. --- cmd_parser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index 34c0321..57ef402 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -737,7 +737,7 @@ void parse_regget(void) { uint16_t reg = 0; - if (cmd_words_b[1] < 0) { + if (cmd_words_len != 2) { goto err; } @@ -772,7 +772,7 @@ void parse_regset(void) { uint16_t reg = 0; - if (cmd_words_b[2] < 0) { + if (cmd_words_len != 2) { goto err; } From c7fb354f08a5911f79276bcd86c2a2369c53431d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 17 Apr 2026 23:07:39 +0200 Subject: [PATCH 17/42] parse_sds{get,set}() and parse_phy{get,set}() make use of cmd_words_len --- cmd_parser.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index 57ef402..f239cba 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -820,7 +820,7 @@ void parse_sdsget(void) { __xdata uint8_t sds_id, page, reg, hex_size; - if (cmd_words_b[1] < 0 || cmd_words_b[2] < 0 || cmd_words_b[3] < 0) { + if (cmd_words_len != 4) { goto err; } @@ -864,7 +864,7 @@ void parse_sdsset(void) __xdata uint8_t sds_id, page, reg, hex_size; __xdata uint16_t val; - if (cmd_words_b[1] < 0 || cmd_words_b[2] < 0 || cmd_words_b[3] < 0 || cmd_words_b[4] < 0) { + if (cmd_words_len != 5) { goto err; } @@ -919,7 +919,7 @@ void parse_phyget(void) __xdata uint8_t phy_id, dev_id, hex_size; __xdata uint16_t reg; - if (cmd_words_b[1] < 0 || cmd_words_b[2] < 0 || cmd_words_b[3] < 0) { + if (cmd_words_len != 4) { goto err; } @@ -965,7 +965,7 @@ void parse_physet(void) __xdata uint8_t phy_id, dev_id, hex_size; __xdata uint16_t reg, val; - if (cmd_words_b[1] < 0 || cmd_words_b[2] < 0 || cmd_words_b[3] < 0 || cmd_words_b[4] < 0) { + if (cmd_words_len != 5) { goto err; } From 0d698dc57230aae2e056d46d773b94c699225b6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 17 Apr 2026 23:32:18 +0200 Subject: [PATCH 18/42] parse_passwd() make use of cmd_words_len, change password memcpy. --- cmd_parser.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index f239cba..f7381de 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -1035,11 +1035,15 @@ void parse_rnd(void) void parse_passwd(void) { - if (cmd_words_b[2] > 0) { - signed char i; - signed char j = 0; - for (i = cmd_words_b[1]; (i != cmd_words_b[2] && i - cmd_words_b[1] < 20); i++) - passwd[j++] = cmd_buffer[i]; + // cmd_words_len can be more then 2 if a space in the password. + if (cmd_words_len >= 2) { + uint8_t i = cmd_words_b[1]; + uint8_t c = 0; + uint8_t j = 0; + do { + c = cmd_buffer[i++]; + passwd[j++] = c; + } while (c != '\0' && j < 20); passwd[j] = '\0'; return; } From 7380aeb10da4dddfb92e2c2548dce27925037b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 17 Apr 2026 23:38:30 +0200 Subject: [PATCH 19/42] parse_bw() make use of cmd_words_len --- cmd_parser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index f7381de..5bdad00 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -1114,7 +1114,7 @@ void parse_bw(void) __xdata uint8_t port; __xdata uint32_t bw = 0; - if (cmd_words_b[3] < 0) // Check for at least 2 arguments + if (cmd_words_len < 2) // Check for at least 2 arguments goto err; port = cmd_buffer[cmd_words_b[2]] - '1'; @@ -1128,7 +1128,7 @@ void parse_bw(void) return; } - if (cmd_words_b[4] < 0) // Check for at least 3 arguments + if (cmd_words_len < 4) // Check for at least 4 arguments goto err; if (cmd_compare(3, "drop")) { From 56e0d0a5d183e6217e06a53e6cccb40f67577c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 17 Apr 2026 23:51:30 +0200 Subject: [PATCH 20/42] parse_lag() make use of cmd_words_len --- cmd_parser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index 5bdad00..5da6778 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -259,12 +259,12 @@ void parse_lag(void) return; } - if (cmd_words_b[2] <= 0 || !isnumber(cmd_buffer[cmd_words_b[1]])) + if (cmd_words_len < 2 || !isnumber(cmd_buffer[cmd_words_b[1]])) goto err; group = cmd_buffer[cmd_words_b[1]] - '0'; uint8_t w = 2; - while (cmd_words_b[w + 1] > 0) { + while (w < cmd_words_len) { // write_char('|'); print_byte(w); write_char(':'); write_char(cmd_buffer[cmd_words_b[w]]); write_char('-'); uint8_t port; if (isnumber(cmd_buffer[cmd_words_b[w]])) { From 2acf2499d1870b34d2cf19589ed08cae85559e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 17 Apr 2026 23:52:51 +0200 Subject: [PATCH 21/42] parse_lag_hash() make use of cmd_words_len --- cmd_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd_parser.c b/cmd_parser.c index 5da6778..bd1f7cd 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -295,7 +295,7 @@ void parse_lag_hash(void) group = cmd_buffer[cmd_words_b[1]] - '0'; uint8_t w = 2; - while (cmd_words_b[w + 1] > 0) { + while (w < cmd_words_len) { if (cmd_compare(w, "spa")) hash |= LAG_HASH_SOURCE_PORT_NUMBER; else if (cmd_compare(w, "smac")) From 1fe236246ac057e32424f933883c1cec0f629f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 17 Apr 2026 23:55:46 +0200 Subject: [PATCH 22/42] parse_isolate() make use of cmd_words_len --- cmd_parser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index bd1f7cd..bbcfa77 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -393,7 +393,7 @@ void parse_isolate(void) { __xdata uint16_t members = 0; - if (cmd_words_b[3] <= 0) + if (cmd_words_len < 3) goto err; print_string("\nISOLATE "); @@ -431,7 +431,7 @@ void parse_isolate(void) } uint8_t w = 2; - while (cmd_words_b[w] > 0) { + while (w < cmd_words_len) { __xdata uint8_t port; if (isnumber(cmd_buffer[cmd_words_b[w]])) { port = cmd_buffer[cmd_words_b[w]] - '1'; From f71e869b976824e52f5a30e52e08bf6afde6e447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 00:02:01 +0200 Subject: [PATCH 23/42] parse_ingress() make use of cmd_words_len, refactor small parts --- cmd_parser.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index bbcfa77..acae573 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -476,7 +476,7 @@ bool vlan_ingress_mode_parse(char c, vlan_ingress_mode_t *mode) void parse_ingress(void) { - if (cmd_words_b[1] <= 0) { + if (cmd_words_len < 2) { goto err; } __xdata uint8_t log_port = 0; @@ -494,24 +494,25 @@ void parse_ingress(void) } return; } else { - for(uint8_t w = 1; cmd_words_b[w] > 0; w++) { - if (!isnumber(cmd_buffer[cmd_words_b[w]])) { + for(uint8_t w = 1; w < cmd_words_len; w++) { + uint8_t p = cmd_buffer[cmd_words_b[w]]; + if (!isnumber(p)) { continue; } - if (cmd_buffer[cmd_words_b[w]] - '1' > 9) { - print_string("Invalid physical port number: "); write_char(cmd_buffer[cmd_words_b[w]]); write_char('\n'); + if (p - '1' > 9) { + print_string("Invalid physical port number: "); write_char(p); write_char('\n'); continue; } - log_port = machine.phys_to_log_port[cmd_buffer[cmd_words_b[w]] - '1']; + log_port = machine.phys_to_log_port[p - '1']; if (!vlan_ingress_mode_parse(cmd_buffer[cmd_words_b[w] + 1], &mode)) { - print_string("Invalid ingress mode for port "); write_char(cmd_buffer[cmd_words_b[w]]); print_string(" in ingress command\n"); + print_string("Invalid ingress mode for port "); write_char(p); print_string(" in ingress command\n"); goto err; } if (!port_ingress_filter(log_port, mode)) { - print_string("Error setting ingress filter for port "); write_char(cmd_buffer[cmd_words_b[w]]); write_char('\n'); + print_string("Error setting ingress filter for port "); write_char(p); write_char('\n'); return; } - print_string("Port "); write_char(cmd_buffer[cmd_words_b[w]]); + print_string("Port "); write_char(p); print_string(" ingress filter set to: "); print_port_ingress_filter_mode(mode); write_char('\n'); } From 49c43082a3bf4f810bee3bf456e8b17b71c7a305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 00:10:32 +0200 Subject: [PATCH 24/42] parse_mirror() make use of cmd_words_len, refactor small parts --- cmd_parser.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index acae573..c1a4e90 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -554,18 +554,19 @@ void parse_mirror(void) return; } - if (!isnumber(cmd_buffer[cmd_words_b[1]])) { - print_string("Port missing: mirror [port][t/r]...\n"); + if (cmd_words_len < 2 || !isnumber(cmd_buffer[cmd_words_b[1]])) { + print_string("Port/command missing: mirror [status/off/ [port][t/r]]...\n"); return; } mirroring_port = cmd_buffer[cmd_words_b[1]] - '1'; if (isnumber(cmd_buffer[cmd_words_b[1] + 1])) mirroring_port = (mirroring_port + 1) * 10 + cmd_buffer[cmd_words_b[1] + 1] - '1'; - mirroring_port = machine.phys_to_log_port[mirroring_port]; + mirroring_port = machine.phys_to_log_port[mirroring_port]; + uint8_t w = 2; - while (cmd_words_b[w] > 0) { + while (w < cmd_words_len) { uint8_t port; if (isnumber(cmd_buffer[cmd_words_b[w]])) { port = cmd_buffer[cmd_words_b[w]] - '1'; From abe3513bc63cbf279379cbe68d06988497c3c6e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 00:13:54 +0200 Subject: [PATCH 25/42] parse_port() make use of cmd_words_len --- cmd_parser.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index c1a4e90..bc63b0a 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -601,11 +601,11 @@ void parse_mirror(void) void parse_port(void) { - if (cmd_words_b[3] <= 0) { - print_string("\nUsage:"); - print_string("\nport [show|on|off]"); - print_string("\nport [10m|100m|1g|2g5|duplex] [half|full]"); - print_string("\nport name [custom port name]\n"); + if (cmd_words_len < 3) { + print_string("\nUsage:" \ + "\nport [show|on|off]" \ + "\nport [10m|100m|1g|2g5|duplex] [half|full]" \ + "\nport name [custom port name]\n"); return; } From a24b63a81f222bec418bc739f802eb826680b42e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 00:15:14 +0200 Subject: [PATCH 26/42] parse_mtu() make use of cmd_words_len --- cmd_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd_parser.c b/cmd_parser.c index bc63b0a..35236dd 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -706,7 +706,7 @@ void parse_mtu(void) p = cmd_buffer[cmd_words_b[1]] - '1'; p = machine.phys_to_log_port[p]; print_byte(p); - if (cmd_words_b[2] <= 0) { + if (cmd_words_len != 3) { print_string("mtu [port] [size]\n"); return; } From f2ff7d7737eded094c1a39f4b7551e8fd3ac3965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 16:51:08 +0200 Subject: [PATCH 27/42] parse_ee() make use of cmd_words_len --- cmd_parser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index 35236dd..dbccf89 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -1059,7 +1059,7 @@ void parse_eee(void) __xdata uint8_t speed = EEE_2G5; __xdata uint8_t speed_word = 0; // Check if word 2 is a speed (contains 'g' or 'm') or a port number - if (cmd_words_b[3] > 0) { + if (cmd_words_len >= 3) { uint8_t idx = cmd_words_b[2]; // Skip digits to check if there's a letter after while (isnumber(cmd_buffer[idx])) @@ -1072,7 +1072,7 @@ void parse_eee(void) port = cmd_buffer[cmd_words_b[2]] - '1'; port = machine.phys_to_log_port[port]; // Check if word 3 is a speed - if (cmd_words_b[4] > 0) + if (cmd_words_len >= 4) speed_word = 3; } } From 8324edc5f7cd00f6abadebaf5ca58caca62e25a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 20:43:40 +0200 Subject: [PATCH 28/42] cmd_parser: Improve atoi_byte() and atoi_short(). Because no memory type is specified to the reference location, sdcc is using a helper function to access the location. But sdcc is using a register to tell the helper function which memory-type is used. This registers must also be preseved until all access to that location is done. --- cmd_parser.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index c56105e..08f9659 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -169,30 +169,33 @@ uint8_t atoi_hex(uint8_t idx) } -uint8_t atoi_byte(register uint8_t *out, register uint8_t idx) +uint8_t atoi_byte(uint8_t __xdata *out, uint8_t idx) { - __xdata uint8_t err = 1; - *out = 0; + uint8_t err = 1; + uint8_t num = 0; while (isnumber(cmd_buffer[idx])) { err = 0; - *out = (*out * 10) + cmd_buffer[idx] - '0'; + num = (num * 10) + cmd_buffer[idx] - '0'; idx++; } + + *out = num; return err; } -uint8_t atoi_short(register uint16_t *vlan, register uint8_t idx) +uint8_t atoi_short(uint16_t __xdata *vlan, uint8_t idx) { - __xdata uint8_t err = 1; - *vlan = 0; + uint8_t err = 1; while (isnumber(cmd_buffer[idx])) { err = 0; - *vlan = (*vlan * 10) + cmd_buffer[idx] - '0'; + uint8_t val = cmd_buffer[idx] - '0'; + *vlan = (*vlan * 10) + val; idx++; } + return err; } From 642030c7b2b59a52b80ccc83bc37840afea26809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 21:39:43 +0200 Subject: [PATCH 29/42] uip: de-__gptrget()-call in uip_add32() --- uip/uip.c | 2 +- uip/uip_arch.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/uip/uip.c b/uip/uip.c index 40c018c..6afd3be 100644 --- a/uip/uip.c +++ b/uip/uip.c @@ -241,7 +241,7 @@ __xdata struct uip_stats uip_stat; #if ! UIP_ARCH_ADD32 void -uip_add32(u8_t *op32, u16_t op16) +uip_add32(u8_t __xdata * op32, u16_t op16) { uip_acc32[3] = op32[3] + (op16 & 0xff); uip_acc32[2] = op32[2] + (op16 >> 8); diff --git a/uip/uip_arch.h b/uip/uip_arch.h index 71fd84b..5d408d9 100644 --- a/uip/uip_arch.h +++ b/uip/uip_arch.h @@ -81,7 +81,7 @@ * * \param op16 A 16-bit integer in host byte order. */ -void uip_add32(u8_t *op32, u16_t op16); +void uip_add32(u8_t __xdata * op32, u16_t op16); /** * Calculate the Internet checksum over a buffer. From 8134ca7ec74c409deb0bd1a506da86d44108f6ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 21:45:33 +0200 Subject: [PATCH 30/42] uip: de-__gptrget()-call in uip_ipaddr_copy() --- uip/uip.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uip/uip.h b/uip/uip.h index 2433512..ac644f9 100644 --- a/uip/uip.h +++ b/uip/uip.h @@ -880,8 +880,8 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked; */ #if !UIP_CONF_IPV6 #define uip_ipaddr_copy(dest, src) do { \ - ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \ - ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \ + ((u16_t __xdata *)dest)[0] = ((u16_t __xdata *)src)[0]; \ + ((u16_t __xdata *)dest)[1] = ((u16_t __xdata *)src)[1]; \ } while(0) #else /* !UIP_CONF_IPV6 */ #define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t)) From facc4afe400df439e397490ae437e5bd685e9966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 21:48:55 +0200 Subject: [PATCH 31/42] uip: de-__gptrget()-call in timer_{set,reset,restart,exprired}() --- uip/timer.c | 8 ++++---- uip/timer.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/uip/timer.c b/uip/timer.c index cb52151..fd1531c 100644 --- a/uip/timer.c +++ b/uip/timer.c @@ -64,7 +64,7 @@ * */ void -timer_set(struct timer *t, clock_time_t interval) +timer_set(__xdata struct timer *t, clock_time_t interval) { t->interval = interval; t->start = clock_time(); @@ -84,7 +84,7 @@ timer_set(struct timer *t, clock_time_t interval) * \sa timer_restart() */ void -timer_reset(struct timer *t) +timer_reset(__xdata struct timer *t) { t->start += t->interval; } @@ -104,7 +104,7 @@ timer_reset(struct timer *t) * \sa timer_reset() */ void -timer_restart(struct timer *t) +timer_restart(__xdata struct timer *t) { t->start = clock_time(); } @@ -121,7 +121,7 @@ timer_restart(struct timer *t) * */ int -timer_expired(struct timer *t) +timer_expired(__xdata struct timer *t) { return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval; } diff --git a/uip/timer.h b/uip/timer.h index 057bea4..ef13f78 100644 --- a/uip/timer.h +++ b/uip/timer.h @@ -76,10 +76,10 @@ struct timer { clock_time_t interval; }; -void timer_set(struct timer *t, clock_time_t interval); -void timer_reset(struct timer *t); -void timer_restart(struct timer *t); -int timer_expired(struct timer *t); +void timer_set(__xdata struct timer *t, clock_time_t interval); +void timer_reset(__xdata struct timer *t); +void timer_restart(__xdata struct timer *t); +int timer_expired(__xdata struct timer *t); #endif /* __TIMER_H__ */ From 791f68582de7bac79e9f488289a032019999fdad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 21:54:12 +0200 Subject: [PATCH 32/42] httpd: de-__gptrget()-call in string_to_html() --- httpd/page_impl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpd/page_impl.c b/httpd/page_impl.c index 270ddb3..09c60b0 100644 --- a/httpd/page_impl.c +++ b/httpd/page_impl.c @@ -97,7 +97,7 @@ void itoa_html(uint8_t v) char_to_html('0' + (v % 10)); } -void string_to_html(register char *s) +void string_to_html(__code char *s) { while (*s) char_to_html(*s++); } From 6c6d11ab33c36762767bc2be43e03718aac6c87b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 21:56:29 +0200 Subject: [PATCH 33/42] dhcp: de-__gptrget()-call in dhcp_print_ip() --- dhcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dhcp.c b/dhcp.c index 9febcca..67c0e50 100644 --- a/dhcp.c +++ b/dhcp.c @@ -82,7 +82,7 @@ struct dhcp_pkt { __xdata uint32_t long_value; -void dhcp_print_ip(uint8_t *a) +void dhcp_print_ip(__xdata uint8_t *a) { itoa(a[0]); write_char('.'); itoa(a[1]); write_char('.'); From 3e599f0e06184dc0f23c225987969bddcc424720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 22:27:55 +0200 Subject: [PATCH 34/42] dhcp: de-__gptrput()-call in ip_opt() --- dhcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dhcp.c b/dhcp.c index 67c0e50..1a04168 100644 --- a/dhcp.c +++ b/dhcp.c @@ -216,7 +216,7 @@ void dhcp_send_request(void) } -void ip_opt(uint8_t * __xdata ip) +void ip_opt(__xdata uint8_t * ip) { dhcp_state.opt_ptr++; uint8_t len = DHCP_OPT[dhcp_state.opt_ptr++]; From 94bf4425baaf5f797606b9ef0b3b41909a6b4643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 22:38:42 +0200 Subject: [PATCH 35/42] uip: de-__gptrput()-call access to struct uip_udp_conn --- dhcp.h | 2 +- uip/uip.c | 2 +- uip/uip.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dhcp.h b/dhcp.h index fdcc35d..991361b 100644 --- a/dhcp.h +++ b/dhcp.h @@ -35,7 +35,7 @@ struct dhcp_state { uint32_t rebind; uint32_t renewal; - struct uip_udp_conn *conn; + __xdata struct uip_udp_conn *conn; }; typedef struct dhcp_state uip_udp_appstate_t; diff --git a/uip/uip.c b/uip/uip.c index 6afd3be..653591a 100644 --- a/uip/uip.c +++ b/uip/uip.c @@ -465,7 +465,7 @@ uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banke #endif /* UIP_ACTIVE_OPEN */ /*---------------------------------------------------------------------------*/ #if UIP_UDP -struct uip_udp_conn * +__xdata struct uip_udp_conn * uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked { __xdata struct uip_udp_conn *conn; diff --git a/uip/uip.h b/uip/uip.h index ac644f9..58b3d6c 100644 --- a/uip/uip.h +++ b/uip/uip.h @@ -763,7 +763,7 @@ void uip_send(register __xdata const void *data, register uint16_t len) __banked * \return The uip_udp_conn structure for the new connection or NULL * if no connection could be allocated. */ -struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked; +__xdata struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked; /** * Removed a UDP connection. From da768171a5e81198d25cc8fcf10d9c01ea2e5bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 19 Apr 2026 22:00:31 +0200 Subject: [PATCH 36/42] change cmd_tokenize(). Remove the return argument because `err_status` is also reflecting the result. Fix the error message when too many arguments are found. refactor `execute_config()`, error out when err_status is not OK. --- cmd_parser.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index dbccf89..32bdc5f 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -1187,7 +1187,7 @@ err: // Parse command into words // cmd_words_len contains the number of words found. // cmd_words_b[] contains only start of a word offset. -uint8_t cmd_tokenize(void) __banked +void cmd_tokenize(void) __banked { #ifdef DEBUG print_string("Tokenizing command\n"); @@ -1211,7 +1211,7 @@ uint8_t cmd_tokenize(void) __banked if (line_ptr == CMD_BUF_SIZE - 1) { err_status = ERR_CMD_TOO_LONG; - return 1; + return; } if (is_white && c != ' ') { @@ -1220,9 +1220,9 @@ uint8_t cmd_tokenize(void) __banked cmd_words_b[word++] = line_ptr; if (word >= N_WORDS) { cmd_words_len = 0; - print_string("\ntoo many arguments, truncated"); + print_string("\nSyntax error: too many arguments."); err_status = ERR_TOO_MANY_ARGUMENTS; - return 1; + return; } } else if (c == ' ') { is_white = 1; @@ -1230,8 +1230,6 @@ uint8_t cmd_tokenize(void) __banked line_ptr++; } - - return 0; } // Print GPIO status @@ -1551,10 +1549,11 @@ void execute_config(void) __banked c = flash_buf[cfg_idx++]; if (c == 0 || c == '\n') { cmd_buffer[cmd_idx] = '\0'; - if (cmd_idx && !cmd_tokenize()) { - cmd_parser(); - if (err_status) + if (cmd_idx) { + cmd_tokenize(); + if (err_status != ERR_OK) goto config_done; + cmd_parser(); } if (c == 0) goto config_done; From e79e90dd35aeead0f475e0450f541c7112cf0482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 22:43:25 +0200 Subject: [PATCH 37/42] cmd_parser: de-__gptrput()-call in vlan_ingress_mode_parse() --- cmd_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd_parser.c b/cmd_parser.c index 08f9659..0bc8762 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -447,7 +447,7 @@ err: } -bool vlan_ingress_mode_parse(char c, vlan_ingress_mode_t *mode) +bool vlan_ingress_mode_parse(char c, __xdata vlan_ingress_mode_t *mode) { switch (c) { case 'u': From 52d943d5e4c011bee64effc0d4a7cc746ddac4dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 22:47:52 +0200 Subject: [PATCH 38/42] rtlplayground: de-__gptrput()-call in read_reg_timer() --- rtl837x_common.h | 2 +- rtlplayground.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl837x_common.h b/rtl837x_common.h index 7933687..2bb15b4 100644 --- a/rtl837x_common.h +++ b/rtl837x_common.h @@ -148,7 +148,7 @@ uint16_t strcpy(register __xdata uint8_t *dst, register const char *s); void tcpip_output(void); uint8_t read_flash(uint8_t bank, __code uint8_t *addr); void get_random_32(void); -void read_reg_timer(uint32_t * tmr); +void read_reg_timer(__xdata uint32_t * tmr); void sfp_print_info(uint8_t sfp); bool gpio_pin_test(uint8_t pin); void set_sys_led_state(uint8_t state); diff --git a/rtlplayground.c b/rtlplayground.c index 2da920e..2d90077 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -688,7 +688,7 @@ void cpy_4(__xdata uint8_t dest[], __xdata uint8_t source[]) } -void read_reg_timer(uint32_t * tmr) +void read_reg_timer(__xdata uint32_t * tmr) { uint8_t * val = (uint8_t *)tmr; SFR_REG_ADDR_U16 = RTL837X_REG_SEC_COUNTER; From d5709bcaf341c15675de85ac04945a3903c80484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 23:20:47 +0200 Subject: [PATCH 39/42] fix atoi --- cmd_parser.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index 0bc8762..9b2b9b1 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -169,7 +169,7 @@ uint8_t atoi_hex(uint8_t idx) } -uint8_t atoi_byte(uint8_t __xdata *out, uint8_t idx) +uint8_t atoi_byte(__xdata uint8_t *out, uint8_t idx) { uint8_t err = 1; uint8_t num = 0; @@ -185,7 +185,7 @@ uint8_t atoi_byte(uint8_t __xdata *out, uint8_t idx) } -uint8_t atoi_short(uint16_t __xdata *vlan, uint8_t idx) +uint8_t atoi_short(__xdata uint16_t *vlan, uint8_t idx) { uint8_t err = 1; @@ -200,7 +200,7 @@ uint8_t atoi_short(uint16_t __xdata *vlan, uint8_t idx) } -uint8_t parse_ip(register uint8_t idx) +uint8_t parse_ip(uint8_t idx) { __xdata uint8_t b; From 50d06c61bcfe8669d5f96d91c2c02d0a4fc02644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 23:28:09 +0200 Subject: [PATCH 40/42] change prototype uip_udp_new(), saves 1 sram. --- uip/uip.c | 2 +- uip/uip.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/uip/uip.c b/uip/uip.c index 653591a..98e18b5 100644 --- a/uip/uip.c +++ b/uip/uip.c @@ -466,7 +466,7 @@ uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banke /*---------------------------------------------------------------------------*/ #if UIP_UDP __xdata struct uip_udp_conn * -uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked +uip_udp_new(__xdata uip_ipaddr_t *ripaddr, u16_t rport) __banked { __xdata struct uip_udp_conn *conn; diff --git a/uip/uip.h b/uip/uip.h index 58b3d6c..718d607 100644 --- a/uip/uip.h +++ b/uip/uip.h @@ -763,7 +763,7 @@ void uip_send(register __xdata const void *data, register uint16_t len) __banked * \return The uip_udp_conn structure for the new connection or NULL * if no connection could be allocated. */ -__xdata struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked; +__xdata struct uip_udp_conn *uip_udp_new(__xdata uip_ipaddr_t *ripaddr, u16_t rport) __banked; /** * Removed a UDP connection. From 224471d676188c75442ca0139bc964c0b3f00624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 18 Apr 2026 23:50:47 +0200 Subject: [PATCH 41/42] uip: move second argument to __xdata free up 4 sram bytes. --- uip/uip.c | 4 ++-- uip/uip.h | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/uip/uip.c b/uip/uip.c index 98e18b5..a15787a 100644 --- a/uip/uip.c +++ b/uip/uip.c @@ -466,7 +466,7 @@ uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banke /*---------------------------------------------------------------------------*/ #if UIP_UDP __xdata struct uip_udp_conn * -uip_udp_new(__xdata uip_ipaddr_t *ripaddr, u16_t rport) __banked +uip_udp_new(__xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banked { __xdata struct uip_udp_conn *conn; @@ -1901,7 +1901,7 @@ htons(u16_t val) } /*---------------------------------------------------------------------------*/ void -uip_send(register __xdata const void *data, register uint16_t len) __banked +uip_send(__xdata const void *data, __xdata uint16_t len) __banked { if(len > 0) { uip_slen = len; diff --git a/uip/uip.h b/uip/uip.h index 718d607..d28f295 100644 --- a/uip/uip.h +++ b/uip/uip.h @@ -495,7 +495,7 @@ void uip_unlisten(u16_t port) __banked; * or NULL if no connection could be allocated. * */ -__xdata struct uip_conn *uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t port) __banked; +__xdata struct uip_conn *uip_connect(__xdata uip_ipaddr_t *ripaddr, __xdata u16_t port) __banked; @@ -535,7 +535,7 @@ __xdata struct uip_conn *uip_connect(register __xdata uip_ipaddr_t *ripaddr, __x * * \hideinitializer */ -void uip_send(register __xdata const void *data, register uint16_t len) __banked; +void uip_send(__xdata const void *data, __xdata uint16_t len) __banked; /** * The length of any incoming data that is currently avaliable (if avaliable) @@ -763,7 +763,7 @@ void uip_send(register __xdata const void *data, register uint16_t len) __banked * \return The uip_udp_conn structure for the new connection or NULL * if no connection could be allocated. */ -__xdata struct uip_udp_conn *uip_udp_new(__xdata uip_ipaddr_t *ripaddr, u16_t rport) __banked; +__xdata struct uip_udp_conn *uip_udp_new(__xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banked; /** * Removed a UDP connection. @@ -880,8 +880,8 @@ __xdata struct uip_udp_conn *uip_udp_new(__xdata uip_ipaddr_t *ripaddr, u16_t rp */ #if !UIP_CONF_IPV6 #define uip_ipaddr_copy(dest, src) do { \ - ((u16_t __xdata *)dest)[0] = ((u16_t __xdata *)src)[0]; \ - ((u16_t __xdata *)dest)[1] = ((u16_t __xdata *)src)[1]; \ + ((__xdata u16_t *)dest)[0] = ((__xdata u16_t *)src)[0]; \ + ((__xdata u16_t *)dest)[1] = ((__xdata u16_t *)src)[1]; \ } while(0) #else /* !UIP_CONF_IPV6 */ #define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t)) @@ -908,8 +908,8 @@ __xdata struct uip_udp_conn *uip_udp_new(__xdata uip_ipaddr_t *ripaddr, u16_t rp * \hideinitializer */ #if !UIP_CONF_IPV6 -#define uip_ipaddr_cmp(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \ - ((__xdata u16_t *)addr1)[1] == ((u16_t *)addr2)[1]) +#define uip_ipaddr_cmp(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__xdata u16_t *)addr2)[0] && \ + ((__xdata u16_t *)addr1)[1] == ((__xdata u16_t *)addr2)[1]) #define uip_ipaddr_cmpx(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__xdata u16_t *)addr2)[0] && \ ((__xdata u16_t *)addr1)[1] == ((__xdata u16_t *)addr2)[1]) #define uip_ipaddr_cmpc(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__code u16_t *)addr2)[0] && \ From 18225f5d2252823eecc8709505bd3298c05b3e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 19 Apr 2026 00:30:42 +0200 Subject: [PATCH 42/42] uip: more fix. --- uip/uip_arch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uip/uip_arch.h b/uip/uip_arch.h index 5d408d9..f4547d6 100644 --- a/uip/uip_arch.h +++ b/uip/uip_arch.h @@ -81,7 +81,7 @@ * * \param op16 A 16-bit integer in host byte order. */ -void uip_add32(u8_t __xdata * op32, u16_t op16); +void uip_add32(__xdata u8_t * op32, u16_t op16); /** * Calculate the Internet checksum over a buffer.
Name:" + portName + "
Name:" + portName + "