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测试代码
C 语言通用模板队列的更多相关文章
- PHP中的位运算与位移运算(其它语言通用)
/* PHP中的位运算与位移运算 ======================= 二进制Binary:0,1 逢二进1,易于电子信号的传输 原码.反码.补码 二进制最高位是符号位:0为正数,1为负数( ...
- go语言的模板,text/template包
go语言的模板,text/template包 定义 模板就是将一组文本嵌入另一组文本里 传入string--最简单的替换 package main import ( "os" &q ...
- C语言实现,队列可伸缩
两个栈实现一个队列,C语言实现,队列可伸缩,容纳任意数目的元素. 一.思路:1.创建两个空栈A和B:2.A栈作为队列的入口,B栈作为队列的出口:3.入队列操作:即是入栈A:4.出队列操作:若栈B为空, ...
- Django模板之通用模板的使用
Django模板之通用模板的使用 转载:https://code.ziqiangxuetang.com/django/django-template.html 我们做网站有一些通用的部分,比如 导航, ...
- 「小程序JAVA实战」小程序通用模板的使用(17)
转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-17/ 小程序也为了页面增加了通用模板的功能,如何去理解一个通用的模板呢?模板的定义就是为了让我们的 ...
- Xamarin XAML语言教程模板视图TemplatedView(二)
Xamarin XAML语言教程模板视图TemplatedView(二) (2)打开MainPage.xaml文件,编写代码,将构建的控件模板应用于中TemplatedView.代码如下: <? ...
- Xamarin XAML语言教程模板视图TemplatedView(一)
Xamarin XAML语言教程模板视图TemplatedView(一) 模板视图TemplatedView 与模板页面相对的是TemplatedView,它被称为模板视图,它的功能和模板页面类似,也 ...
- Xamarin XAML语言教程模板页面TemplatedPage
Xamarin XAML语言教程模板页面TemplatedPage 模板页面TemplatedPage 在上文中我们提到了TemplatedPage,它被称为模板页面,用来显示控件模版.Templat ...
- Loadrunner:脚本编写通用模板(Http协议类型)
1. 背景 对于 Http协议,Loadrunner 脚本可以使用通用模板反复粘贴,只需要修改其中的 URL 和 传参,就可以完成一整个业务 2. Get 类型的接口 web_custom_reque ...
随机推荐
- ES系列(三):网络通信模块解析
ES是一个分布式搜索引擎,其除了用户提供必要的通信服务外,集群间也必须保持紧密的通信联系,才能在必要的时候给出正确的结果.其则必然涉及到各种繁多且要求高的通信场景,那么如何实现高性能的通信,则是其必须 ...
- 077 Kuchiguse
The Japanese language is notorious for its sentence ending particles. Personal preference of such pa ...
- 01- Sublime的工具安装以及使用
一 sublime安装与使用 sublime介绍: sublime是一个代码编辑器,可以编写HTML,PHP,js,css等文件. Sublime有哪些优点: 1.跨平台 2.扩展性强 3.提交小,运 ...
- video播放视频以及相关事件
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...
- Laravel 队列功能 简单应用
生成任务类 默认情况下,应用程序的所有可排队任务都存储在 app/Jobs 目录下.如果 app/Jobs 目录不存在,则会在运行 make:job Artisan 命令时将创建它.你可以使用 Art ...
- Windows下Nexus 5的Android 5.0以上版本官方ROM的刷机教程
博客链接:http://blog.csdn.net/qq1084283172/article/details/52334452 折腾Android逆向的时候,经常需要给Nexus 5刷机.最近给Nex ...
- ResNet学习笔记
ResNet学习笔记 前言 这篇文章实在看完很多博客之后写的,需要读者至少拥有一定的CNN知识,当然我也不知道需要读者有什么水平,所以可能对一些很入门的基本的术语进行部分的解释,也有可能很多复杂的术语 ...
- (CV学习笔记)看图说话(Image Captioning)-2
实现load_img_as_np_array def load_img_as_np_array(path, target_size): """从给定文件[加载]图像,[缩 ...
- 报错com.github.pagehelper.PageHelper cannot be cast to com.github.pagehelper.Dialect
报错com.github.pagehelper.PageHelper cannot be cast to com.github.pagehelper.Dialect spring以及mybatis版本 ...
- Java反射机制以及动态代理
Java反射机制以及动态代理 Java反射机制 含义与功能 Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类 ...