From b5c5fd4ede286b4b7a5a9f6e2ba3427ad63e166a Mon Sep 17 00:00:00 2001 From: binaryDiv Date: Sat, 17 Apr 2021 17:40:56 +0200 Subject: [PATCH] Rewrite buffer related stuff to avoid weird stack overflow(?) issues --- firmware/src/commands.c | 38 +++++++++++++------------------------- firmware/src/common.h | 11 +++++++---- firmware/src/eeprom.c | 2 +- firmware/src/parsing.c | 2 +- firmware/src/uart.c | 21 +++++++++++---------- firmware/src/uart.h | 3 --- 6 files changed, 33 insertions(+), 44 deletions(-) diff --git a/firmware/src/commands.c b/firmware/src/commands.c index 248c499..d549f65 100644 --- a/firmware/src/commands.c +++ b/firmware/src/commands.c @@ -103,14 +103,12 @@ void commandRead(char* arg) { uartPutLine("OK"); - uint8_t byteBuffer[DATA_BLOCK_SIZE]; - DataBuffer buffer = { - .data = byteBuffer, - .maxSize = DATA_BLOCK_SIZE, - .bytes = 0 - }; + // Create data buffer + DataBuffer buffer; do { + buffer.bytes = 0; + // Read a single block with up to DATA_BLOCK_SIZE bytes Address nextAddress = eepromReadBlock(range, &buffer); range.isValid = nextAddress.isValid; @@ -121,16 +119,16 @@ void commandRead(char* arg) { // First the size of the package (1 byte) followed by the data bytes uartPutChar(buffer.bytes); - for (int i = 0; i < buffer.bytes; i++) { + for (uint8_t i = 0; i < buffer.bytes; i++) { uartPutChar(buffer.data[i]); } } else { // Fancy ASCII output - uartPutChar('<'); - uartPutInteger(buffer.bytes); + uartPutString("<0x"); + uartPutHexByte(buffer.bytes); uartPutChar('>'); - for (int i = 0; i < buffer.bytes; i++) { + for (uint8_t i = 0; i < buffer.bytes; i++) { uartPutChar(' '); uartPutHexByte(buffer.data[i]); } @@ -159,17 +157,12 @@ void commandWrite(char* arg) { return; } - // Create data buffer - uint8_t byteBuffer[DATA_BLOCK_SIZE]; - DataBuffer buffer = { - .data = byteBuffer, - .maxSize = DATA_BLOCK_SIZE, - .bytes = 0 - }; - // "OK" indicates that data can be sent now. uartPutLine("OK START"); + // Create data buffer + DataBuffer buffer; + Address currentAddress = startAddress; uint8_t block_length = 0; @@ -180,10 +173,8 @@ void commandWrite(char* arg) { // Read and check block length block_length = uartGetChar(); - if (block_length > buffer.maxSize) { - uartPutString("ERROR maximal block size is: "); - uartPutInteger(buffer.maxSize); - uartPutLine(NULL); + if (block_length > DATA_BLOCK_SIZE) { + uartPutLine("ERROR maximal block size is: " STR(DATA_BLOCK_SIZE)); return; } @@ -196,9 +187,6 @@ void commandWrite(char* arg) { if (buffer.bytes > 0) { currentAddress = eepromWriteBlock(currentAddress, buffer); - // TODO wait necessary? - //_delay_ms(100); - if (!currentAddress.isValid) { uartPutLine("ERROR reached end of EEPROM while writing block"); return; diff --git a/firmware/src/common.h b/firmware/src/common.h index d6cb0e7..479a8af 100644 --- a/firmware/src/common.h +++ b/firmware/src/common.h @@ -8,6 +8,10 @@ // Define macro for NOP instruction #define _NOP() __asm__ __volatile__ ("nop"); +// Define macro to convert a preprocessor constant to a string literal +#define STR_(x) #x +#define STR(x) STR_(x) + // Define type for EEPROM addresses typedef uint16_t address_t; @@ -28,12 +32,11 @@ typedef struct { } AddressRange; // Define type for a block of data (bytes) +#define DATA_BLOCK_SIZE 64 + typedef struct { - uint8_t* data; - uint8_t maxSize; + uint8_t data[DATA_BLOCK_SIZE]; uint8_t bytes; } DataBuffer; -#define DATA_BLOCK_SIZE 64 - #endif /* COMMON_H_ */ diff --git a/firmware/src/eeprom.c b/firmware/src/eeprom.c index cdeaad9..9eb76ca 100644 --- a/firmware/src/eeprom.c +++ b/firmware/src/eeprom.c @@ -132,7 +132,7 @@ Address eepromReadBlock(AddressRange addressRange, DataBuffer* buffer) { highestAddress = HIGHEST_VALID_ADDRESS; } - while (currentAddress <= highestAddress && buffer->bytes < buffer->maxSize) { + while (currentAddress <= highestAddress && buffer->bytes < DATA_BLOCK_SIZE) { buffer->data[buffer->bytes++] = eepromReadByte(currentAddress++); // Handle integer overflow diff --git a/firmware/src/parsing.c b/firmware/src/parsing.c index 8316251..c3b6f79 100644 --- a/firmware/src/parsing.c +++ b/firmware/src/parsing.c @@ -13,7 +13,7 @@ // Read and parse command line and dispatch command void parseNextCommand() { - const int bufferLength = 80; + const int bufferLength = 40; char buffer[bufferLength]; // Read next command diff --git a/firmware/src/uart.c b/firmware/src/uart.c index e2dc588..5e84c97 100644 --- a/firmware/src/uart.c +++ b/firmware/src/uart.c @@ -4,8 +4,15 @@ #include #include #include +#include +#include #include +// Hexadecimal digit lookup table +static const char hexDigitLookupTable[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' +}; + // Initialize UART void uartInit() { // Set Baud register @@ -56,18 +63,12 @@ void uartPutLine(char* data) { uartPutChar('\n'); } -// Convert an integer to decimal ASCII and transmit -void uartPutInteger(int value) { - char outBuffer[32]; - snprintf(outBuffer, 32, "%d", value); - uartPutString(outBuffer); -} - // Convert a byte to hexadecimal ASCII and transmit void uartPutHexByte(uint8_t byte) { - char outBuffer[8]; - snprintf(outBuffer, 8, "%02hhX", byte); - uartPutString(outBuffer); + // First hex digit: most significant 4 bits + uartPutChar(hexDigitLookupTable[(byte >> 4) & 0x0f]); + // Second hex digit: least significant 4 bits + uartPutChar(hexDigitLookupTable[byte & 0x0f]); } // Receive a single character (blocking) diff --git a/firmware/src/uart.h b/firmware/src/uart.h index 9065993..d5be266 100644 --- a/firmware/src/uart.h +++ b/firmware/src/uart.h @@ -16,9 +16,6 @@ void uartPutString(char* data); // Transmit a string followed by a line break void uartPutLine(char* data); -// Convert an integer to decimal ASCII and transmit -void uartPutInteger(int value); - // Convert a byte to hexadecimal ASCII and transmit void uartPutHexByte(uint8_t byte);