环形缓冲区定义

为什么需要这个概念了,因为从机发送数据之后主机可能来不及处理,比如从机发送频率是每10ms发送一次,当主机接收到数据处理需要15ms,那么此时主机就会出现丢帧的概念,因此最好的解决办法是,定义一个缓冲区,当接受到数据后存储下来,然后一帧一帧的处理,这样就不会出现丢帧的情况。

下面以CAN通信举例


typedef struct
{
    uint32_t source_address         : 8;
    uint32_t destination_address    : 8;
    uint32_t cmd_type               : 8;
    uint32_t reserved0              : 2;
    uint32_t prior                  : 3;
    uint32_t reserved1              : 3;
}can_id_redefine_t;

typedef union
{
    uint32_t ext_id;
    can_id_redefine_t bits;
} can_id_redefine_u;

typedef struct
{
    can_id_redefine_u id;
    uint8_t buff[8];
}can_tx_data_t;

typedef struct {
    can_rx_data_t buffer[CIRCLE_BUFFER_SIZE];  // 缓冲区数组
    int head;                  // 缓冲区头部指针
    int tail;                  // 缓冲区尾部指针
    int count;                 // 缓冲区中元素的数量
} circleBuffer_t;

// 初始化环形缓冲区
void circle_buffer_init(circleBuffer_t *rb)
{
    rb->head = 0;
    rb->tail = 0;
    rb->count = 0;
    // memset(rb->buffer, 0, CIRCLE_BUFFER_SIZE);
}


// 向环形缓冲区添加数据
int circle_add_data(circleBuffer_t *rb, can_rx_data_t data)
{
    if (rb->count == CIRCLE_BUFFER_SIZE)
    {
        return -1; // 缓冲区已满
    }
    memcpy(&rb->buffer[rb->head], &data, sizeof(data));
    rb->head = (rb->head + 1) % CIRCLE_BUFFER_SIZE;
    rb->count++;
    return 0;
}

// 从环形缓冲区读取数据
int circle_get_data(circleBuffer_t *rb, can_rx_data_t *data)
{
    if (rb->count == 0)
    {
        return -1; // 缓冲区为空
    }
    memcpy(data, &rb->buffer[rb->tail], sizeof(rb->buffer[rb->tail]));
    rb->tail = (rb->tail + 1) % CIRCLE_BUFFER_SIZE;
    rb->count--;
    return 0;
}

// 检查环形缓冲区是否为空
int circle_empty(circleBuffer_t *rb)
{
    return rb->count == 0;
}

// 检查环形缓冲区是否已满
int circle_full(circleBuffer_t *rb)
{
    return rb->count == CIRCLE_BUFFER_SIZE;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值