diff options
author | lonkaars <loek@pipeframe.xyz> | 2022-05-17 22:37:09 +0200 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2022-05-17 22:37:09 +0200 |
commit | 154df68cb2a74a3b22456e8ec5af3af54352a41f (patch) | |
tree | f9d2c83b30322d81691ae1a013813add6ec6b99e | |
parent | 2b75425070662b869c15673623df44e30ce43ebe (diff) |
fix buffer overflow in error handling module
- fixed ring buffer overflow in errcatch module
- fixed naming of commands in sercomm module
- added comments to macro's in consts.h
- properly handle `W2_E_WARN_UNCAUGHT_ERROR` and
`W2_E_WARN_ERR_BUFFER_FULL` (these used to cause infinite loops)
- added buffer full warning code
- added options to hide some simulation messages
- more boilerplate sercomm module code
-rw-r--r-- | robot/consts.h | 7 | ||||
-rw-r--r-- | robot/errcatch.c | 25 | ||||
-rw-r--r-- | robot/errcatch.h | 3 | ||||
-rw-r--r-- | robot/hypervisor.c | 15 | ||||
-rw-r--r-- | robot/makefile | 2 | ||||
-rw-r--r-- | robot/sercomm.h | 40 | ||||
-rw-r--r-- | robot/sim.h | 13 |
7 files changed, 68 insertions, 37 deletions
diff --git a/robot/consts.h b/robot/consts.h index d74d034..94a161d 100644 --- a/robot/consts.h +++ b/robot/consts.h @@ -5,6 +5,11 @@ #define W2_BUILD_STR ("????????") #endif +/** max logic module execution time in milliseconds */ #define W2_MAX_MODULE_CYCLE_MS (20) +/** serial baud rate (bit/s) */ #define W2_SERIAL_BAUD (9600) -#define W2_E_BUFFER_SIZE (16) +/** size of the error handling buffer (in errors, not bytes) */ +#define W2_ERROR_BUFFER_SIZE (16) +/** size of the serial communication buffer (in messages, not bytes) */ +#define W2_SERCOMM_BUFFER_SIZE (16) diff --git a/robot/errcatch.c b/robot/errcatch.c index 1262a38..f66b2a1 100644 --- a/robot/errcatch.c +++ b/robot/errcatch.c @@ -8,15 +8,25 @@ #include "modes.h" #include "orangutan_shim.h" -w2_s_error *g_w2_error_buffer[W2_E_BUFFER_SIZE] = {}; -uint8_t g_w2_error_index = 0; -uint8_t g_w2_error_offset = 0; +w2_s_error *g_w2_error_buffer[W2_ERROR_BUFFER_SIZE] = {}; +uint8_t g_w2_error_index = 0; +uint8_t g_w2_error_offset = 0; +uint8_t g_w2_error_buffer_full = 0; +uint8_t g_w2_error_uncaught = 0; void w2_errcatch_main() { while (g_w2_error_index != g_w2_error_offset) { w2_s_error *error = g_w2_error_buffer[g_w2_error_offset]; w2_errcatch_handle_error(error); - g_w2_error_offset = (g_w2_error_offset + 1) % W2_E_BUFFER_SIZE; + g_w2_error_offset = (g_w2_error_offset + 1) % W2_ERROR_BUFFER_SIZE; + } + if (g_w2_error_buffer_full) { + w2_errcatch_throw(W2_E_WARN_ERR_BUFFER_FULL); + g_w2_error_buffer_full = 0; + } + if (g_w2_error_uncaught) { + w2_errcatch_throw(W2_E_WARN_UNCAUGHT_ERROR); + g_w2_error_uncaught = 0; } } @@ -30,10 +40,13 @@ w2_s_error *w2_alloc_error(enum w2_e_errorcodes code, uint16_t length, const cha void w2_errcatch_throw(enum w2_e_errorcodes code) { w2_errcatch_throw_msg(code, 0, ""); } void w2_errcatch_throw_msg(enum w2_e_errorcodes code, uint16_t length, const char *message) { + uint8_t next_index = (g_w2_error_index + 1) % W2_ERROR_BUFFER_SIZE; + g_w2_error_buffer_full = next_index == g_w2_error_offset; free(g_w2_error_buffer[g_w2_error_index]); w2_s_error *error = w2_alloc_error(code, length, message); g_w2_error_buffer[g_w2_error_index] = error; - g_w2_error_index = (g_w2_error_index + 1) % W2_E_BUFFER_SIZE; + if (g_w2_error_buffer_full) return; + g_w2_error_index = next_index; } void w2_errcatch_handle_error(w2_s_error *error) { @@ -48,7 +61,7 @@ void w2_errcatch_handle_error(w2_s_error *error) { break; } default: { - w2_errcatch_throw(W2_E_WARN_UNCAUGHT_ERROR); + g_w2_error_uncaught = 1; #ifdef W2_SIM simwarn("Uncaught/unhandled error found with code 0x%02x\n", error->code); #endif diff --git a/robot/errcatch.h b/robot/errcatch.h index ec4b90f..9f737d8 100644 --- a/robot/errcatch.h +++ b/robot/errcatch.h @@ -29,6 +29,7 @@ enum w2_e_errorcodes { W2_E_WARN_OBSTACLE_DETECTED = 0x01 | W2_E_TYPE_WARN, W2_E_WARN_CYCLE_EXPIRED = 0x02 | W2_E_TYPE_WARN, W2_E_WARN_UNCAUGHT_ERROR = 0x03 | W2_E_TYPE_WARN, + W2_E_WARN_ERR_BUFFER_FULL = 0x04 | W2_E_TYPE_WARN, }; /** @@ -44,7 +45,7 @@ typedef struct { } w2_s_error; /** error ring buffer */ -extern w2_s_error *g_w2_error_buffer[W2_E_BUFFER_SIZE]; +extern w2_s_error *g_w2_error_buffer[W2_ERROR_BUFFER_SIZE]; /** stores head of ring buffer */ extern uint8_t g_w2_error_index; /** stores start of ring buffer */ diff --git a/robot/hypervisor.c b/robot/hypervisor.c index dbdc62a..c558de8 100644 --- a/robot/hypervisor.c +++ b/robot/hypervisor.c @@ -1,5 +1,4 @@ #include "hypervisor.h" -#include "consts.h" #include "errcatch.h" #include "io.h" #include "modes.h" @@ -7,6 +6,10 @@ #include "sercomm.h" void w2_hypervisor_main() { +#ifdef W2_SIM + siminfo("cycle start\n"); +#endif + time_reset(); w2_sercomm_main(); @@ -18,14 +21,10 @@ void w2_hypervisor_main() { w2_modes_main(); unsigned long mode_time = get_ms() - io_time; -#ifdef W2_SIM - siminfo("sercomm: %lums\n", sercomm_time); - siminfo("errcatch: %lums\n", errcatch_time); - siminfo("io: %lums\n", io_time); - siminfo("mode: %lums\n", mode_time); + if (mode_time > W2_MAX_MODULE_CYCLE_MS) w2_errcatch_throw(W2_E_WARN_CYCLE_EXPIRED); +#ifdef W2_SIM + siminfo("cycle end\n"); usleep(100e3); #endif - - if (mode_time > W2_MAX_MODULE_CYCLE_MS) w2_errcatch_throw(W2_E_WARN_CYCLE_EXPIRED); } diff --git a/robot/makefile b/robot/makefile index 6f50519..ce57090 100644 --- a/robot/makefile +++ b/robot/makefile @@ -34,7 +34,7 @@ CFLAGS += -DW2_BUILD_STR="$(BUILD_STR)" all: $(if $(SIM), a.out, out.hex) clean: - rm -f *.o out.hex a.out compile_commands.json + rm -f *.o out.hex a.out a.out: $(OBJECTS) $(CC) $(OBJECTS) $(CFLAGS) $(LDFLAGS) diff --git a/robot/sercomm.h b/robot/sercomm.h index 1533a4c..d960d0d 100644 --- a/robot/sercomm.h +++ b/robot/sercomm.h @@ -1,27 +1,35 @@ #pragma once #include "bin.h" +#include "consts.h" -#define W2_CMD_RX (0) -#define W2_CMD_TX (1) +#define W2_CMDDIR_RX (0) +#define W2_CMDDIR_TX (1) enum w2_e_serial_commands { - W2_E_CMD_PING = 0x00, - W2_E_CMD_EXPT = 0x02, - W2_E_CMD_MODE = 0x04, - W2_E_CMD_SPED = 0x06, - W2_E_CMD_DIRC = 0x08, - W2_E_CMD_CORD = 0x0a, - W2_E_CMD_BOMD = 0x0c, - W2_E_CMD_SRES = 0x0e, - W2_E_CMD_MCFG = 0x10, - W2_E_CMD_SENS = 0x12, - W2_E_CMD_INFO = 0x14, - W2_E_CMD_DISP = 0x16, - W2_E_CMD_PLAY = 0x18, - W2_E_CMD_CLED = 0x1a, + W2_CMD_PING = 0x00, + W2_CMD_EXPT = 0x02, + W2_CMD_MODE = 0x04, + W2_CMD_SPED = 0x06, + W2_CMD_DIRC = 0x08, + W2_CMD_CORD = 0x0a, + W2_CMD_BOMD = 0x0c, + W2_CMD_SRES = 0x0e, + W2_CMD_MCFG = 0x10, + W2_CMD_SENS = 0x12, + W2_CMD_INFO = 0x14, + W2_CMD_DISP = 0x16, + W2_CMD_PLAY = 0x18, + W2_CMD_CLED = 0x1a, }; +/** sercomm ring buffer */ +extern w2_s_bin *g_w2_sercomm_buffer[W2_SERCOMM_BUFFER_SIZE]; +/** stores head of ring buffer */ +extern uint8_t g_w2_error_index; +/** stores start of ring buffer */ +extern uint8_t g_w2_error_offset; + /** * serial pc-robot communication module * diff --git a/robot/sim.h b/robot/sim.h index 15a1b4b..9c80ecf 100644 --- a/robot/sim.h +++ b/robot/sim.h @@ -4,6 +4,11 @@ #include <stdlib.h> #include <unistd.h> +// debug fine-tuning +#define DBG_ENABLE_PRINTFUNC (0) +#define DBG_ENABLE_SIMWARN (1) +#define DBG_ENABLE_SIMINFO (1) + // debug print options #define DBG_BYTES_PER_LINE 16 @@ -21,10 +26,10 @@ // debug stdout print macros #define simprintf(message, ...) printf(COL_RED "[SIM] " COL_RST message, ##__VA_ARGS__) #define simprint(message) simprintf(message "\n") -#define simprintfunc(name, fmt, ...) simprintf(COL_BLU "[FUNC] " \ - COL_CYN name COL_RST "(" COL_YEL fmt COL_RST ")\n", ##__VA_ARGS__) -#define simwarn(message, ...) simprintf(COL_YEL "[WARN] " COL_RST message, ##__VA_ARGS__) -#define siminfo(message, ...) simprintf(COL_MAG "[INFO] " COL_RST message, ##__VA_ARGS__) +#define simprintfunc(name, fmt, ...) if (DBG_ENABLE_PRINTFUNC) { simprintf(COL_BLU "[FUNC] " \ + COL_CYN name COL_RST "(" COL_YEL fmt COL_RST ")\n", ##__VA_ARGS__); } +#define simwarn(message, ...) if (DBG_ENABLE_SIMWARN) { simprintf(COL_YEL "[WARN] " COL_RST message, ##__VA_ARGS__); } +#define siminfo(message, ...) if (DBG_ENABLE_SIMINFO) { simprintf(COL_MAG "[INFO] " COL_RST message, ##__VA_ARGS__); } /** * simulates pololu library functions for local testing |