feat(ex02): fixed all issues

This commit is contained in:
Maix0 2026-04-24 14:05:10 +02:00
parent 153f2b82d2
commit bacfb97ae0

View file

@ -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(&current_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);