Message
This commit is contained in:
parent
6a58763ece
commit
38d078509e
4 changed files with 109 additions and 0 deletions
12
message/Makefile
Normal file
12
message/Makefile
Normal 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
14
message/main_demo.c
Normal 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
52
message/message.c
Normal 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
31
message/message.h
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue