initial commit

This commit is contained in:
bmy
2024-05-17 01:57:18 +08:00
commit 478e698ae9
19 changed files with 3821 additions and 0 deletions

169
by_frame.c Normal file
View File

@@ -0,0 +1,169 @@
#include "by_frame.h"
#include "by_serial.h"
#include "crc16/crc16.h"
#include "logc/log.h"
by_serial_t serial_port;
by_frame_queue_t queue_recv;
uint8_t frame_buffer_recv[100];
uint8_t frame_buffer_send[4 + BY_FRAME_DATA_NUM * sizeof(uint32_t)];
int frame_parse_busy;
int by_frame_queue_pop(by_frame_queue_t *queue, uint8_t *element)
{
if (!queue->len) {
return -1;
}
*element = queue->buff[0];
queue->len -= 1;
memmove(queue->buff, queue->buff + 1, queue->len);
return 0;
}
int by_frame_queue_add(by_frame_queue_t *queue, uint8_t element)
{
if (queue->size == queue->len) {
return -1;
}
queue->buff[queue->len] = element;
queue->len += 1;
return 0;
}
int by_frame_queue_copy(by_frame_queue_t *queue, uint8_t *buff_out, int num)
{
int copy_num = (queue->len < num) ? queue->len : num;
memcpy(buff_out, queue->buff, copy_num);
return copy_num;
}
int by_frame_queue_drop(by_frame_queue_t *queue, int num)
{
int drop_num = 0;
uint8_t element_temp;
for (int i = 0; i < num; i++) {
drop_num += (!by_frame_queue_pop(queue, &element_temp));
}
return drop_num;
}
int by_frame_queue_find(by_frame_queue_t *queue, const uint8_t element)
{
int found_num = -1;
for (int i = 0; i < queue->len; i++) {
if (queue->buff[i] == element) {
found_num = i;
break;
}
}
return found_num;
}
int by_frame_queue_get_used(by_frame_queue_t *queue)
{
return queue->len;
}
void by_frame_queue_init(by_frame_queue_t *queue, uint8_t *buff, int buff_len)
{
memset(queue, 0, sizeof(by_frame_queue_t));
memset(buff, 0, buff_len);
queue->buff = buff;
queue->size = buff_len;
}
void by_frame_send(uint8_t cmd, uint8_t *data_array, uint8_t len)
{
uint16_t crc_cal = 0;
const uint8_t data_byte_num = BY_FRAME_DATA_NUM * sizeof(uint32_t);
memset(frame_buffer_send, 0, sizeof(frame_buffer_send));
frame_buffer_send[0] = BY_FRAME_HEAD;
frame_buffer_send[1] = cmd;
if (len > data_byte_num) {
len = data_byte_num;
}
memcpy(frame_buffer_send + 2, data_array, len);
crc_cal = crc16_check(frame_buffer_send, 2 + data_byte_num);
frame_buffer_send[2 + data_byte_num] = (uint8_t)(crc_cal >> 8);
frame_buffer_send[3 + data_byte_num] = (uint8_t)(crc_cal);
by_serial_write(&serial_port, frame_buffer_send, 4 + data_byte_num);
}
/**
* @brief
*
* @param data_num
* @param data_array
* @todo 将其中写死的数据长度按照宏定义给出
*/
int by_frame_parse(uint8_t *cmd, uint32_t *data_array)
{
uint8_t frame_buff[BY_FRANE_LEN] = {0};
// 先从缓冲区内复制数据到临时 buffer 里
for (int i = 0; i < by_serial_get_used_buffer_len(&serial_port); i++) {
uint8_t data = 0;
by_serial_read(&serial_port, &data, 1);
by_frame_queue_add(&queue_recv, data);
}
// 丢弃缓冲区头部无法解析的数据,如果剩下的数据过少则不解析
// log_debug("drop %d", by_frame_queue_find(&queue_recv, BY_FRAME_HEAD));
int used_num = by_frame_queue_find(&queue_recv, BY_FRAME_HEAD);
by_frame_queue_drop(&queue_recv, used_num);
// 不存在帧头时退出
if (-1 == used_num) {
return -1;
}
// 剩余数据过少时退出
if (BY_FRANE_LEN > by_frame_queue_get_used(&queue_recv)) {
return -1;
}
log_debug("start parsing");
by_frame_queue_copy(&queue_recv, frame_buff, BY_FRANE_LEN);
uint16_t crc_val = (uint16_t)frame_buff[BY_FRANE_LEN - 1];
crc_val |= (uint16_t)(frame_buff[BY_FRANE_LEN - 2] << 8);
uint16_t crc_cal = crc16_check(frame_buff, BY_FRANE_LEN - 2);
if (crc_val == crc_cal) {
log_info("received successful");
// 丢掉当前帧头,下次解析时就不从该帧头开始
by_frame_queue_drop(&queue_recv, 1);
// TODO 复制数据
*cmd = frame_buff[1];
memcpy(data_array, &frame_buff[2], BY_FRANE_DATA_LEN);
return 0;
} else {
log_warn("receive failed");
log_warn("cal crc 0x%04X, but got 0x%04X", crc_cal, crc_val);
// 丢掉当前帧头,下次解析时就不从该帧头开始
by_frame_queue_drop(&queue_recv, 1);
return -1;
}
}
int by_frame_init(void)
{
by_frame_queue_init(&queue_recv, frame_buffer_recv, sizeof(frame_buffer_recv));
return (by_serial_init(&serial_port, "/dev/ttyTHS0"));
}