最近在GD32中遇到CAN数据接受的问题,为了防止数据丢失采用了环形缓冲区的结构来做数据缓冲

环形缓冲区最重要的两点
1 判断队满,队空
2 对缓冲区进行内存分配
对缓冲区进行的内存分配首先涉及代码如下:
typedef struct CircularQueue
{
can_receive_message_struct* arry;
int front;
int tail;
int size;//可存放元素的大小,实际分配要多分配一个空间
}CQueue,* CQueueP;
int CQueueInit(CQueue** cq, int k)
{
*cq = (CQueue*)malloc(sizeof(CQueue));
if (*cq == 0) return 0;;
(*cq)->arry = (can_receive_message_struct*)malloc(sizeof(can_receive_message_struct) * (k + 1));
if ((*cq)->arry == 0) return 0;
(*cq)->front = (*cq)->tail = 0;
(*cq)->size = k;
return 1;
}
//如何使用如下:
CQueueP M_CanQueue;
CQueueInit(&M_CanQueue, 5);//初始化can接受环形队列
这里其实是定义一个M_CanQueue,它是一个CQueue类型的指针,开始并不会分配内存
只有在执行到CQueueInit()中的cq = (CQueue)malloc(sizeof(CQueue));时才会被分配内存。
然后是对实际存储空间arry分配内存,arry可根据实际选用的数据结构定义。注意的是int CQueueInit(CQueue** cq, int k)第一个参数必须是一个二维指针,不然对arry分配的内存传递不出来,或者还有其它两种方式在我另一篇博客
然后贴上完整代码。可直接使用
#include <stdio.h>
#include <malloc.h>
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
/* CAN receive message structure */
typedef struct {
uint32_t rx_sfid; /*!< standard format frame identifier */
uint32_t rx_efid; /*!< extended format frame identifier */
uint8_t rx_ff; /*!< format of frame, standard or extended format */
uint8_t rx_ft; /*!< type of frame, data or remote */
uint8_t rx_dlen; /*!< data length */
uint8_t rx_data[8]; /*!< receive data */
uint8_t rx_fi; /*!< filtering index */
} can_receive_message_struct;
typedef struct CircularQueue
{
can_receive_message_struct* arry;
int front;
int tail;
int size;//可存放元素的大小,实际分配要多分配一个空间
}CQueue,* CQueueP;
int CQueueInit(CQueue** cq, int k)
{
*cq = (CQueue*)malloc(sizeof(CQueue));
if (*cq == 0) return 0;;
(*cq)->arry = (can_receive_message_struct*)malloc(sizeof(can_receive_message_struct) * (k + 1));
if ((*cq)->arry == 0) return 0;
(*cq)->front = (*cq)->tail = 0;
(*cq)->size = k;
return 1;
}
//判断环形队列是否为空
int CQueueIsEmpty(CQueue* cq)
{
if (cq == 0) return 0;
return cq->front == cq->tail;
}
//判断环形队列是否为满
int CQueueIsFull(CQueue* cq)
{
if (cq == 0) return 0;
return (cq->tail + 1) % (cq->size + 1) == cq->front;
}
//入队
int CQueuePush(CQueue* cq, can_receive_message_struct x)
{
</

本文介绍了在GD32开发中如何使用环形缓冲区解决CAN数据接收问题,包括CQueue数据结构的定义、内存分配、队列操作(空、满判断及入队出队)以及动态内存管理的优化。
最低0.47元/天 解锁文章
2万+

被折叠的 条评论
为什么被折叠?



