summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2022-05-17 22:37:09 +0200
committerlonkaars <loek@pipeframe.xyz>2022-05-17 22:37:09 +0200
commit154df68cb2a74a3b22456e8ec5af3af54352a41f (patch)
treef9d2c83b30322d81691ae1a013813add6ec6b99e
parent2b75425070662b869c15673623df44e30ce43ebe (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.h7
-rw-r--r--robot/errcatch.c25
-rw-r--r--robot/errcatch.h3
-rw-r--r--robot/hypervisor.c15
-rw-r--r--robot/makefile2
-rw-r--r--robot/sercomm.h40
-rw-r--r--robot/sim.h13
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