This commit is contained in:
Imbus 2025-08-24 12:47:13 +02:00
parent 6a58763ece
commit 38d078509e
4 changed files with 109 additions and 0 deletions

12
message/Makefile Normal file
View file

@ -0,0 +1,12 @@
CC ?= gcc
CFLAGS ?= -Wall -O2
TARGET = main.elf
SRC = message.c main_demo.c
$(TARGET): $(SRC)
@echo CC $@
@$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
clean:
rm -f $(TARGET)

14
message/main_demo.c Normal file
View file

@ -0,0 +1,14 @@
#include "message.h"
#include <stdio.h>
#include <assert.h>
int main(void) {
Message m;
message_create(&m, UI_BATTERY, (MessageData){75});
printf("%04X\n", m.crc);
int16_t crc = compute_crc16((const uint8_t *)&m, offsetof(Message, crc));
printf("%04X\n", crc);
assert(message_validate(&m));
return 0;
}

52
message/message.c Normal file
View file

@ -0,0 +1,52 @@
#include "message.h"
#include <assert.h>
uint16_t compute_crc16(const uint8_t *data, uint16_t len);
bool is_type_valid(MessageType t);
/**
* @brief Create a message
*
* Use as: create_message(&m1, UI_VOLTAGE, (MessageData){.voltage = 6.3});
*
* @param m A pointer to the message struct
* @param type The enum type of the message you want to send
* @param data The data corresponding to the message type
*/
void message_create(Message *m, MessageType type, MessageData data) {
m->type = type;
m->data = data;
m->crc = compute_crc16((const uint8_t *)m, offsetof(Message, crc));
}
bool message_validate(const Message *m) {
return is_type_valid(m->type) && m->crc == compute_crc16((const uint8_t *)m, offsetof(Message, crc));
}
// Standard CRC-16-CCITT (poly 0x1021, init 0xFFFF)
uint16_t compute_crc16(const uint8_t *data, uint16_t len) {
uint16_t crc = 0xFFFF;
for (uint16_t i = 0; i < len; i++) {
crc ^= (uint16_t)data[i] << 8;
for (int j = 0; j < 8; j++) {
if (crc & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
}
}
return crc;
}
bool is_type_valid(MessageType t) {
return t >= UI_SPEED_MS && t <= UI_VOLTAGE;
}
int message_tests(void) {
Message m;
message_create(&m, UI_BATTERY, (MessageData){75});
assert(message_validate(&m));
return 0;
}

31
message/message.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef MESSAGE_H
#define MESSAGE_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
typedef enum {
UI_SPEED_MS,
UI_BATTERY,
UI_VOLTAGE,
} MessageType;
typedef union {
int battery;
int speed_ms;
float voltage;
} MessageData;
typedef struct {
MessageType type;
MessageData data;
int16_t crc;
} Message;
void message_create(Message *m, MessageType type, MessageData data);
bool message_validate(const Message *m);
int message_tests(void);
uint16_t compute_crc16(const uint8_t *data, uint16_t len);
#endif