【C语言】一个好用的循环队列与使用示例(以EC200/600为例的AT框架)
目录
- 1.前言
- 2.结论
- 3.循环队列
- 3.1写队列到队列头
- 3.2从尾部读读队列
- 3.3获取当前队列内数据数量
- 3.4清空队列
- 3.5两个重要结构体
- 4.效果与示例
- 4.1三个读队列线程
- 4.2 AT框架写队列与EC200初始化
- 4.3 AT框架读队列
- 4.4 EC200维持TCP长连接
- 5.下载
- 5.1 循环队列
- 5.2 AT框架+EC200的TCP长连接(与EC600通用)
1.前言
上一篇:https://blog.csdn.net/ylc0919/article/details/111050124
自从之前说要发二代框架,不知不觉竟然已经鸽了十个月了,难的有时间总结这段时间的收获。写完第一代AT队列之后,我又有许多设想,比如,能否用一个AT队列管理多个AT模块;比如,AT框架的循环队列加循环缓冲占用了很大空间,能够只将数据的相应序号写入队列,读队列的时候临时填充数据帧;又比如,代码中很多地方用到队列,能否写一个队列框架,每次用到的时候直接复制代码,或者用指针来实现多个队列公用一个队列框架……
经过这么长时间以来的实践验证,其中大部分猜想有了结果。
2.结论
依照惯例,先上结论:
1.一个AT队列控制多个AT模块并不实用,因为其中一个AT模块卡住会导致所有模块都动不了,就EC600来说,信号差的时候一条注网指令需要十几秒的反应时间是很正常的,这时候队列处理不了其他指令。
2.取消循环缓冲,队列只存命令序号,须分情况考虑。如果需要处理的数据和时间相关性不大,且格式固定,队列里只存放命令序号是非常好的办法。如果数据一直在变化,那么这种方法并不太好用,但是也不是不能用,可以在flash中开另一个队列,先将当前数据写入到flash,这样既做到了掉电保持,也做到了节省内存。
3.用指针来实现多个队列公用一个队列框架,理论上没有问题,但我没有找到一个简单好用的办法,写出来的代码都不如直接复制队列框架改个名…
4.整理出一个队列框架,用的时候直接复制修改,能够灵活使用,正是本文要写的。
3.循环队列
下面放上循环队列各部分代码,重要地方都做了注释。
3.1写队列到队列头
队列头在前面跑,如果追上了队列尾,就吃掉一个。
void write_to_queue(MY_INFO_t info)
{//队列写满了,就覆盖掉最先写入的数据(也可以直接返回,忽略掉新添加的数据)if(my_queue.rear==((my_queue.front+1)%MY_QUEUE_MAXNUM)) {my_queue.rear=(my_queue.rear+1)%MY_QUEUE_MAXNUM;}//写入队列my_queue.info_queue[my_queue.front]=info;//队列头进一格my_queue.front=(my_queue.front+1)%MY_QUEUE_MAXNUM;
}
3.2从尾部读读队列
队列尾在后面追,如果追上了队列头,说明队列无数据。
如果跑了系统,可以直接开一个线程放进去。
如果裸机跑,可以放到10ms事件中。
//每次调用读队列为一个tick,超时时间为n ticks
void read_from_queue(void)
{if(my_queue.flags.busy==0){ //队列空闲if(my_queue.rear!=my_queue.front){my_queue.flags.busy=1;my_queue.info =my_queue.info_queue[my_queue.rear];my_queue.otime =0;my_queue.retryNum =0;my_queue.rear =(my_queue.rear+1)%MY_QUEUE_MAXNUM; //队列尾追一格 //数据处理}}else{ //队列忙碌 my_queue.otime++; //ticks+1if(my_queue.otime>my_queue.info.oTime){ //计时时间到my_queue.otime=0;if(my_queue.retryNum<my_queue.info.retryNum){//如果没有达到重试次数上限my_queue.retryNum++;//重试}else{ //异常,重试达到上限,调用错误处理queue_error(); //错误处理my_queue.retryNum=0;my_queue.flags.busy=0;}}}
}
3.3获取当前队列内数据数量
主要用于调试
u16 get_queue_data_num(void)
{u16 ret=0;if(my_queue.front>my_queue.rear)ret=my_queue.front-my_queue.rear;else if(my_queue.front<my_queue.rear)ret=MY_QUEUE_MAXNUM-my_queue.rear+my_queue.front;else if(my_queue.front==my_queue.rear)ret=0;return ret;
}
3.4清空队列
直接清空队列结构即可
void clear_my_queue(void)
{memset((void*)&my_queue,0,sizeof(MY_QUEUE_t));
}
3.5两个重要结构体
这是要填入队列的每一条数据包含的内容,可以直接在这里新增变量
typedef struct
{u8 retryNum; //重试次数上限u16 cmd; //信息idu16 oTime; //超时时间 单位ticks
}MY_INFO_t;
这是队列控制结构体,
typedef struct
{struct{u8 busy:1; }flags; u8 retryNum; //当前重试次数u8 rstNum; //复位次数,多次失败特殊处理(暂未使用)MY_INFO_t info_queue[MY_QUEUE_MAXNUM]; //全部指令环形队列MY_INFO_t info; //当前取出的指令信息u16 otime; //当前命令等待时间u16 front; //队列头数组下标u16 rear; //队列尾数组下标
}MY_QUEUE_t;
4.效果与示例
代码太多,只选择部分截图展示。
4.1三个读队列线程
LiteOS下,我直接给每个读队列单独开了线程。
4.2 AT框架写队列与EC200初始化
为了简化初始化代码,我没有使用结构体作为写队列入参。
相比在写队列函数里面用strlen获得长度,我还是更喜欢把他当做参数传入进去。
4.3 AT框架读队列
读队列,没啥好说的
4.4 EC200维持TCP长连接
这些就照着AT指令手册写就行了
5.下载
5.1 循环队列
https://download.csdn.net/download/ylc0919/44922216
5.2 AT框架+EC200的TCP长连接(与EC600通用)
https://download.csdn.net/download/ylc0919/44922750
需要对照EC200At指令手册。
【C语言】一个好用的循环队列与使用示例(以EC200/600为例的AT框架)相关推荐
- c语言数组方式实现静态循环队列
1 循环队列原理图 2 结构体设计 3 运行结果图 4 完整源代码 #include<stdio.h> #include<malloc.h> /*这是一个c语言用数组方式实现循 ...
- python做一个考试系统_python考试系统 相关实例(示例源码)下载 - 好例子网
开发语言:Python | 大小:0.02M | 发布时间:2016-07-07 | 发布人:linq 相关标签: 立即下载 开发语言:Python | 大小:0.21M | 发布时间:2020-08 ...
- c语言循环队列入列算法,C语言——循环队列和链队列的基本运算
// 循环队列 #include #include "SeqQue.h" // 循环队列的基本运算 /* const int maxsize = 20; typedef struc ...
- 4循环队列的顺序表示中,为什么要空一个位置?
我们先讲一下循环队列的概念: 首先是队列的概念,这个大家都很清楚.队列就是一个线性表. 循环队列就是头尾相连的队列. 那么在普通的队列中我们怎么区别队列中有多少个元素的呢? 队列里有两个指针: 一个指 ...
- 队列之循环队列详解(C语言版)
文章目录 前言 一.循环队列的定义 二.循环队列的结构 三.循环队列的常用操作 结语 附录 前言 大家好,越努力,越幸运.本篇文章小猿将跟您分享数据结构队列中的循环队列,希望对您有所帮助. 一.循环队 ...
- 循环队列(Circular Queue)
循环队列作用 为充分利用向量空间,克服"假溢出"现象的方法. 循环队列的原理 在环状顺序表中,最后一个位置(a[6])和第一个位置(a[0])紧挨着,这样做的好处是: 随着元素做入 ...
- 【数据结构】队列-顺序队列、循环队列、链队、双端队列
定义 队列是只允许在一端进行插入,而在另一端进行删除的线性表. 队头(Front):允许删除的一端,又称为队首. 队尾(Rear): 允许插入的一端. 先进入队列的元素必然先离开队列,即先进先出(Fi ...
- 数据结构-队列之循环队列
将顺序队列臆造为一个环状的空间,即把存储队列元素的表从逻辑上看成一个环,称为循环队列. 当队首指针q.front=MaxSize-1后,再前进一个位置就自动归0,可以通过除法取余运算(%)来实现. 初 ...
- 8 线性表-循环队列-顺序存储
这几天犹豫了一下要不要上机实现数据结构的代码 一轮复习已经结束了 第二次看还是觉得光看书实在太无感了 于是决定来上机 顺便加深印象 即使考不上 记录一些基础的知识 以后找工作也有用-- 好 就这样决定 ...
最新文章
- 寒冬中的半个月前端面试
- Linux中的 inode以及 软硬链接分析
- 详解:UML类图符号、各种关系说明以及举例
- 生成excel表格并下载
- vue ajax加载动画,vue 请求加载数据的时候如何显示加载动画
- .NET Core 3.0 新 JSON API - JsonSerializer
- 原生JS字符串操作方法汇总
- Delphi TXLSReadWriteII导出Excel
- vs2015-OpenGL绘制三角形
- CodeForces - 556C Case of Matryoshkas
- OpenFileDialog获取文件名和文件路径问题
- openfire源码解读--用户登录
- excel模板 基金账本_有哪些好用的Excel个人账单模板?
- 最新Django经典面试问题与答案汇总
- 智能电子后视镜MFC01-LCD产品标定说明
- 人体一机竞技格斗机器人_在格斗机器人比赛中,如何判断输赢?
- android Wifi自动连接
- 蓝牙BQB证后还会被查的3种情况,蓝牙组织审查
- 逾20万人“云围观”,第八届全球云计算大会乘风破浪而来
- 阿里云服务器1Mbps带宽到底能够达到什么效果