From bacfb97ae0a2a4cf9a41a11e1ab05e363baf8c4a Mon Sep 17 00:00:00 2001 From: Maix0 <39835848+Maix0@users.noreply.github.com> Date: Fri, 24 Apr 2026 14:05:10 +0200 Subject: [PATCH] feat(ex02): fixed all issues --- ex02/src/main.c | 190 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 132 insertions(+), 58 deletions(-) diff --git a/ex02/src/main.c b/ex02/src/main.c index b93ab7b..674d5a7 100644 --- a/ex02/src/main.c +++ b/ex02/src/main.c @@ -8,23 +8,32 @@ #include "uart.h" #include "utils.h" -#define COL_RED "\x1b[31m" -#define COL_GREEN "\x1b[32m" -#define COL_YELLOW "\x1b[33m" -#define COL_BLUE "\x1b[34m" -#define COL_PURPLE "\x1b[35m" -#define COL_CYAN "\x1b[36m" -#define COL_RESET "\x1b[0m" -#define COL_GRAY "\x1b[38;5;248m" +#define COL_RED "\x1b[31m" +#define COL_GREEN "\x1b[32m" +#define COL_YELLOW "\x1b[33m" +#define COL_BLUE "\x1b[34m" +#define COL_PURPLE "\x1b[35m" +#define COL_CYAN "\x1b[36m" +#define COL_RESET "\x1b[0m" +#define COL_GRAY "\x1b[38;5;248m" -#define COL_BOLD "\x1b[1m" +#define COL_BOLD "\x1b[1m" -#define COL_BGBLACK "\x1b[47m" +#define COL_BGBLACK "\x1b[47m" -#define ROW_SIZE (0x20) -#define BUFFER_SIZE (128) +#define ROW_SIZE (0x20) +#define BUFFER_SIZE (128) -#define tabsize(tab) (sizeof(tab) / sizeof(tab[0])) +#define tabsize(tab) (sizeof(tab) / sizeof(tab[0])) +#define member_size(type, member) (sizeof(((type*)0)->member)) + +typedef struct node { + char magic[3]; // RED + char tag[33]; // BLUE + uint32_t id; // GREEN + int16_t priority; // YELLOW + uint16_t crc; // PURPLE +} node; typedef struct command { enum command_type { @@ -38,21 +47,22 @@ typedef struct command { FACTORY_RESET, INT_FAILURE, SLOT_FAILURE, + SLOT, } ty; union cmd_type { uint32_t u32; uint16_t u16; int16_t i16; - char c32[32]; + char tag[member_size(node, tag)]; } args; } command; -uint8_t MAGIC[3] = {'N', 'O', 'K'}; -char DEFAULT_TAG[32] = "Unconfigured"; -uint32_t DEFAULT_ID = 0; -uint16_t DEFAULT_PRIO = 0; +uint8_t MAGIC[member_size(node, magic)] = {'N', 'O', 'K'}; +char DEFAULT_TAG[member_size(node, tag)] = "Unconfigured"; +uint32_t DEFAULT_ID = 0; +uint16_t DEFAULT_PRIO = 0; -uint16_t slot_address[6] = { +uint16_t slot_address[6] = { 0x000, 0x080, // 0x100, 0x180, // 0x200, 0x280, // @@ -60,15 +70,6 @@ uint16_t slot_address[6] = { volatile uint8_t SLOT_FAILURE_COUNT = 0; -typedef struct node { - char magic[3]; // RED - char tag[33]; // BLUE - uint32_t id; // GREEN - int16_t priority; // YELLOW - uint16_t crc; // PURPLE -} node; - -#define member_size(type, member) (sizeof(((type*)0)->member)) #define setup_isField(field) \ static inline bool is_##field(uint16_t addr) { \ for (uint8_t i = 0; i < tabsize(slot_address); i++) { \ @@ -245,9 +246,9 @@ bool parse_command(char* str, command* cmd) { return true; while (str[i] == ' ') i++; - char c[32] = {}; - uint16_t j = 0; - uint8_t seen = false; + char c[member_size(node, tag)] = {}; + uint16_t j = 0; + uint8_t seen = false; if (str[i] != '"') { uart_sendstring( "Invalid format: SET_TAG only take a single parameter in quotes (32 char max) (no " @@ -255,7 +256,7 @@ bool parse_command(char* str, command* cmd) { return true; } i++; - for (j = 0; j < 32 && (str[i]); j++, i++) { + for (j = 0; j + 1 < member_size(node, tag) && (str[i]); j++, i++) { seen |= BV(1); if (str[i] == '"') { seen |= BV(2); @@ -264,6 +265,10 @@ bool parse_command(char* str, command* cmd) { } c[j] = str[i]; } + if (!(seen & BV(2)) && str[i] == '"') { + seen |= BV(2); + i++; + } while (str[i] == ' ') i++; if (str[i] != '\0' || seen != (BV(1) | BV(2))) { @@ -271,9 +276,19 @@ bool parse_command(char* str, command* cmd) { "Invalid format: SET_TAG only take a single parameter in quotes (32 char max)\r\n"); return true; } + for (uint8_t k = 0; c[k]; k++) { + if (!(k >= 'a' && k <= 'z') && !(k >= 'A' && k <= 'Z') && !(k >= '0' && k <= '9') && + k != '_' && k != '-') { + uart_sendstring( + "Invalid format: SET_TAG parameter must be alphanumeric (- and _ are allowed " + "too)" + "\r\n"); + return true; + } + } cmd->ty = SET_TAG; - ft_memcpy(cmd->args.c32, c, sizeof(c)); + ft_memcpy(cmd->args.tag, c, sizeof(c)); return false; } CMD_CHECK(str, "FACTORY_RESET") { @@ -281,7 +296,27 @@ bool parse_command(char* str, command* cmd) { return false; } CMD_CHECK(str, "INT_FAILURE") { - cmd->ty = INT_FAILURE; + uint16_t count = ~0; + if (str[i] != ' ') { + if (str[i] == 0) { + cmd->ty = INT_FAILURE; + cmd->args.u16 = count; + return true; + } + return false; + } + while (str[i] == ' ') + i++; + if (str[i] >= '0' && str[i] <= '0' + (char)tabsize(slot_address) - 1) + count = str[i] - '0'; + else if (!str[i]) { + uart_sendstring( + "invalid format: INT_FAILURE only take a single optional parameter (number " + "between 0-5)"); + return true; + } + cmd->ty = INT_FAILURE; + cmd->args.u16 = count; return false; } CMD_CHECK(str, "SLOT_FAILURE") { @@ -302,6 +337,24 @@ bool parse_command(char* str, command* cmd) { cmd->args.u16 = count; return false; } + CMD_CHECK(str, "SLOT") { + uint8_t count = 0; + if (str[i] != ' ') + return false; + while (str[i] == ' ') + i++; + if (str[i] >= '0' && str[i] <= '0' + (char)tabsize(slot_address) - 1) + count = str[i] - '0'; + else if (!str[i]) { + uart_sendstring( + "invalid format: SLOT only take a single optional parameter (number " + "between 0-5)"); + return true; + } + cmd->ty = SLOT; + cmd->args.u16 = count; + return false; + } cmd->ty = UNKNOWN; return false; @@ -339,26 +392,25 @@ void read_command(command* cmd) { } } -bool node_crc(node* node) { - uint16_t count; +bool _get_crc(node* node) { + uint16_t sum1 = 0; + uint16_t sum2 = 0; + uint16_t index; - count = 0; - for (uint8_t i = 0; i < sizeof(*node) - sizeof(node->crc); i++) { - count += ((uint8_t*)node)[i]; + for (index = 0; index < sizeof(*node) - sizeof(node->crc); ++index) { + sum1 = (sum1 + ((uint8_t*)node)[index]) % 255; + sum2 = (sum2 + sum1) % 255; } - count += node->crc; - return count == 0; + return (sum2 << 8) | sum1; +} + +bool node_crc(node* node) { + return node->crc == _get_crc(node); } void node_set_crc(node* node) { - uint16_t count; - - count = 0; - for (uint8_t i = 0; i < sizeof(*node) - sizeof(node->crc); i++) { - count += ((uint8_t*)node)[i]; - } - node->crc = 0 - count; + node->crc = _get_crc(node); } bool check_magic(node* node) { @@ -425,13 +477,22 @@ bool write_node_reallocating(uint8_t* current_slot, node* node) { return true; } +uint8_t find_first_valid_slot(void) { + node node; + for (uint8_t i = 0; i < tabsize(slot_address); i++) { + if (read_node(i, &node)) + return i; + } + return 0; +} + int main(void) { uart_init(); command cmd; ft_bzero(&cmd, sizeof(cmd)); - uint8_t current_slot = 0; + uint8_t current_slot = find_first_valid_slot(); node node = {}; print_eeprom(-1); @@ -467,16 +528,19 @@ int main(void) { continue; } - char c[33] = {}; + char c[sizeof(node.tag)] = {}; ft_bzero(c, sizeof(c)); - ft_memcpy(c, node.tag, sizeof(node.tag)); + ft_memcpy(c, node.tag, sizeof(node.tag) - 1); uart_sendstring("Integrity check Good\r\n"); - uart_sendstring("ID: "), uart_send_u32(node.id), uart_sendstring("\r\n"); - uart_sendstring("Priority: "), uart_send_i16(node.priority), + uart_sendstring("ID: "), uart_send_u32(node.id), uart_sendstring("\r\n"); + uart_sendstring("Priority: "), uart_send_i16(node.priority), + uart_sendstring("\r\n"); + uart_sendstring("Tag: \""), uart_sendstring(c), uart_sendstring("\"\r\n"); + uart_sendstring("Slot: "), uart_send_u8(current_slot), uart_sendstring("\r\n"); + uart_sendstring("Stored_crc:"), uart_send_u16(node.crc), uart_sendstring("\r\n"); + uart_sendstring("Calc_crc: "), uart_send_u16(_get_crc(&node)), uart_sendstring("\r\n"); - uart_sendstring("TAG: \""), uart_sendstring(c), uart_sendstring("\"\r\n"); - uart_sendstring("SLOT: "), uart_send_u8(current_slot), uart_sendstring("\r\n"); break; } case SET_ID: { @@ -498,7 +562,7 @@ int main(void) { case SET_TAG: { if (!read_node(current_slot, &node)) init_default_node(&node); - ft_memcpy(node.tag, cmd.args.c32, sizeof(cmd.args.c32)); + ft_memcpy(node.tag, cmd.args.tag, sizeof(cmd.args.tag)); node_set_crc(&node); write_node_reallocating(¤t_slot, &node); break; @@ -511,8 +575,9 @@ int main(void) { break; } case INT_FAILURE: { - uint8_t data = eeprom_read_single(slot_address[current_slot] + 22); - data ^= BV(2); + uint16_t s = cmd.args.u16 == ~(uint16_t)0 ? current_slot : cmd.args.u16; + uint8_t data = eeprom_read_single(slot_address[s] + 22); + data ^= BV(2); eeprom_write_single(slot_address[current_slot] + 22, data); uart_sendstring("One bit as been changed !\r\n"); break; @@ -525,6 +590,15 @@ int main(void) { SLOT_FAILURE_COUNT = cmd.args.u16; break; } break; + + case SLOT: { + uart_sendstring("Changed slot to number "); + uart_send_u16(cmd.args.u16); + uart_sendstring("\r\n"); + current_slot = cmd.args.u16; + + break; + } } // uint16_t edata = eeprom_read_single(addr);