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 |