嵌入式中缓冲区队列的实现
发布日期:2021-05-14 10:08:36 浏览次数:28 分类:精选文章

本文共 2446 字,大约阅读时间需要 8 分钟。

在串口、IIC或SPI以及CAN等通信中,数据的完整性和时序性对于系统的正常运行至关重要。由于硬件传输速度的限制,有时会出现数据丢失或发送不完整的情况。为了解决这一问题,通常会使用缓冲区来存储数据,确保数据能够在适当的时候被发送和接收。

传统的队列实现通常包括入队、出队、查询队列大小、创建队列和销毁队列等基本操作,但在串口等硬件环境中,这样的实现可能会引入过多的函数调用,导致性能下降。针对这一问题,我们开发了一种优化后的缓冲队列,并通过测试验证了其在数据传输中的完整性和可靠性。

一、缓冲队列的结构体定义

缓冲队列的结构体主要由以下几个部分组成:

  • 缓冲区(TxBuff):用于存储需要发送的数据。
  • 队列头指针(font):指向队列当前接收的位置。
  • 队列尾指针(rear):指向队列当前发送的位置。
  • 发送完成标志位(finished):用于判断是否完成一次完整的数据发送。

结构体定义如下:

typedef struct {
u8 TxBuff[BUFFSIZE]; // 缓冲区
u16 font; // 队列头指针
u16 rear; // 队列尾指针
u8 finished; // 发送完成标志位,0表示未完成,1表示完成
} TxBuffer;

二、入队函数

入队函数负责将数据存入缓冲区,并准备好发送。主要包括两种函数:

  • 单字节发送函数(UsartSendData)
    void UsartSendData(ConnIFName tx, u8 data, USART_TypeDef* u) {
    TxBuffer* buff = GetTxBuffer(tx);
    if (buff->rear == BUFFSIZE) {
    buff->rear = 0;
    }
    buff->TxBuff[buff->rear++] = data;
    if (buff->finished == 1) {
    buff->finished = 0;
    if (buff->font == BUFFSIZE) {
    buff->font = 0;
    }
    USART_SendData(u, buff->TxBuff[buff->font]);
    buff->TxBuff[buff->font] = 0xFF;
    buff->font++;
    }
    }
  • 多字节发送函数(MultitySend)
    void MultitySend(ConnIFName tx, u8 data[], USART_TypeDef* u, u8 len) {
    u8 i = 0;
    TxBuffer* buff = GetTxBuffer(tx);
    if (len > buff->rear + buff->font) {
    for (i = 0; i < len; i++) {
    if (buff->rear == BUFFSIZE) {
    buff->rear = 0;
    }
    buff->TxBuff[buff->rear++] = data[i];
    }
    if (buff->finished != 0) {
    if (buff->font == BUFFSIZE) {
    buff->font = 0;
    }
    USART_SendData(u, buff->TxBuff[buff->font++]);
    buff->finished = 0;
    }
    }
    }
  • 三、出队函数

    出队函数负责从缓冲区读取数据并发送。通常由中断触发。

    void TxBuffIRQ(ConnIFName tx, USART_TypeDef* u) {
    TxBuffer* buff = GetTxBuffer(tx);
    if (buff->font == buff->rear) {
    buff->finished = 1;
    } else {
    if (buff->font == BUFFSIZE) {
    buff->font = 0;
    }
    USART_SendData(u, buff->TxBuff[buff->font]);
    buff->TxBuff[buff->font] = 0xFF;
    buff->font++;
    }
    }

    四、获取队列函数

    该函数用于获取对应通信接口的缓冲区指针,以便操作队列。

    TxBuffer* GetTxBuffer(ConnIFName tx) {
    switch (tx) {
    case DGUSIF:
    return &DgusTxBuff;
    case WKIF:
    return &WKTxBuff;
    case CK1IF:
    return &CKTxBuff;
    default:
    break;
    }
    return 0;
    }

    这种优化后的缓冲队列通过简化函数调用和减少硬件操作,显著提升了数据传输的效率和可靠性。

    上一篇:tensorflow不同版本安装与升级/降级
    下一篇:C语言定位并抓取文件中的特定字符串

    发表评论

    最新留言

    网站不错 人气很旺了 加油
    [***.192.178.218]2025年04月27日 11时44分31秒