C 语言通用模板队列

嵌入式开发过程中,各个模块之间,各个设备之间进行交互时,都会存在数据的输入输出,由于处理的方式不同,数据不会立即同步处理,因此通常在设计时都会设计缓冲区进行数据的处理,方式数据丢失等问题;一个项目中存在不同模块都需要缓冲区的设计,设计策略基本都一样,不同的是数据结构,在 C 语言中可以编写缓冲区功能函数,入参类型通常为无类型指针,适配所有需要储存的不同数据结构,但是这种方式必须先知道不同数据结构体的大小,在写入和读取时按一个个字节操作。

下面介绍的是使用宏定义函数实现该方式,按照数据结构的形式赋值速度快,效率高,但是需要一定内存(宏定义),以空间换时间。

实现方式

宏定义函数实现数据队列的功能,适用不同数据结构,类似于 C++ 的模板方式,相同的实现逻辑,不同的数据结构。

点击查看代码 /** * @brief 缓存区操作信息结构体定义 */ typedef struct{ uint8_t state; /*!< 控制状态 */ uint8_t end; /*!< 循环队列尾哨兵 */ uint8_t head; /*!< 循环队列首哨兵 */ uint8_t num; /*!< 循环队列中能存储的最多组数 */ } QueueCtrl_t; #define QUEUE_ENABLE_COVER (0X80) #define QUEUE_EXIT_DATA (0X01) #define QUEUE_DATA_FULL (0X02) #define QUEUE_DATA_LOCK (0X04) /** * @brief 队列控制初始化 * * @param[in,out] ctrl - 队列控制句柄 * @param[in] num - 队列数目大小 * @param[in] cover - 0,不覆盖; 1,队列满了覆盖顶端数据 */ #define QUEUE_INIT(ctrl, maxNum, cover) ({\ ctrl.end = 0;\ ctrl.head = 0;\ ctrl.num = (maxNum);\ ctrl.state = 0x00;\ ctrl.state |= ((cover) ? QUEUE_ENABLE_COVER : 0);\ }) /** * @brief 在队列末尾加入新的数据 * * @param[in,out] dstLists - 队列缓存区 * @param[in] src - 新的数据 * @param[in,out] ctrl - 队列控制句柄 * @retval 返回的值含义如下 * @arg 0: 写入成功 * @arg -1: 写入失败 */ #define QUEUE_PUSH_DATA(dstLists, src, ctrl) ({ \ int ret = 0;\ \ if (QUEUE_DATA_LOCK != ((ctrl.state) & QUEUE_DATA_LOCK)) \ {\ dstLists[(ctrl.end)++] = src;\ (ctrl.state) |= QUEUE_EXIT_DATA; \ \ if ((ctrl.end) >= (ctrl.num))\ {\ (ctrl.end) = 0;\ }\ \ if (((ctrl.state) & QUEUE_DATA_FULL) == QUEUE_DATA_FULL)\ {\ (ctrl.head) = (ctrl.end);\ }\ else if ((ctrl.end) == (ctrl.head))\ {\ (ctrl.state) |= QUEUE_DATA_FULL;\ \ if ((ctrl.state & QUEUE_ENABLE_COVER) != QUEUE_ENABLE_COVER) \ {\ (ctrl.state) |= QUEUE_DATA_LOCK;\ }\ }\ \ ret = 0;\ }\ else\ {\ ret = -1;\ }\ \ ret;\ }) /** * @brief 在队列顶端读取数据 * * @param[in,out] dstLists - 队列缓存区 * @param[out] dst - 读取的数据 * @param[in,out] ctrl - 队列控制句柄 * @retval 返回的值含义如下 * @arg 0: 读取成功 * @arg -1: 读取失败 */ #define QUEUE_POP_DATA(dstLists, dst, ctrl) ({\ \ int ret = -1;\ \ if (((ctrl.state) & QUEUE_EXIT_DATA) == QUEUE_EXIT_DATA)\ {\ dst = dstLists[ctrl.head++];\ \ if ((ctrl.head) >= (ctrl.num))\ {\ ctrl.head = 0;\ }\ \ if ((ctrl.head) == (ctrl.end))\ {\ if (((ctrl.state) & QUEUE_DATA_FULL) != QUEUE_DATA_FULL)\ {\ (ctrl.state) &= ~QUEUE_EXIT_DATA;\ }\ }\ \ ret = 0;\ }\ \ (ctrl.state) &= ~QUEUE_DATA_LOCK;\ (ctrl.state) &= ~QUEUE_DATA_FULL;\ \ ret;\ }) Demo测试代码

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwjdsj.html