目录

  • 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框架)相关推荐

  1. c语言数组方式实现静态循环队列

    1 循环队列原理图 2 结构体设计 3 运行结果图 4 完整源代码 #include<stdio.h> #include<malloc.h> /*这是一个c语言用数组方式实现循 ...

  2. python做一个考试系统_python考试系统 相关实例(示例源码)下载 - 好例子网

    开发语言:Python | 大小:0.02M | 发布时间:2016-07-07 | 发布人:linq 相关标签: 立即下载 开发语言:Python | 大小:0.21M | 发布时间:2020-08 ...

  3. c语言循环队列入列算法,C语言——循环队列和链队列的基本运算

    // 循环队列 #include #include "SeqQue.h" // 循环队列的基本运算 /* const int maxsize = 20; typedef struc ...

  4. 4循环队列的顺序表示中,为什么要空一个位置?

    我们先讲一下循环队列的概念: 首先是队列的概念,这个大家都很清楚.队列就是一个线性表. 循环队列就是头尾相连的队列. 那么在普通的队列中我们怎么区别队列中有多少个元素的呢? 队列里有两个指针: 一个指 ...

  5. 队列之循环队列详解(C语言版)

    文章目录 前言 一.循环队列的定义 二.循环队列的结构 三.循环队列的常用操作 结语 附录 前言 大家好,越努力,越幸运.本篇文章小猿将跟您分享数据结构队列中的循环队列,希望对您有所帮助. 一.循环队 ...

  6. 循环队列(Circular Queue)

    循环队列作用 为充分利用向量空间,克服"假溢出"现象的方法. 循环队列的原理 在环状顺序表中,最后一个位置(a[6])和第一个位置(a[0])紧挨着,这样做的好处是: 随着元素做入 ...

  7. 【数据结构】队列-顺序队列、循环队列、链队、双端队列

    定义 队列是只允许在一端进行插入,而在另一端进行删除的线性表. 队头(Front):允许删除的一端,又称为队首. 队尾(Rear): 允许插入的一端. 先进入队列的元素必然先离开队列,即先进先出(Fi ...

  8. 数据结构-队列之循环队列

    将顺序队列臆造为一个环状的空间,即把存储队列元素的表从逻辑上看成一个环,称为循环队列. 当队首指针q.front=MaxSize-1后,再前进一个位置就自动归0,可以通过除法取余运算(%)来实现. 初 ...

  9. 8 线性表-循环队列-顺序存储

    这几天犹豫了一下要不要上机实现数据结构的代码 一轮复习已经结束了 第二次看还是觉得光看书实在太无感了 于是决定来上机 顺便加深印象 即使考不上 记录一些基础的知识 以后找工作也有用-- 好 就这样决定 ...

最新文章

  1. 寒冬中的半个月前端面试
  2. Linux中的 inode以及 软硬链接分析
  3. 详解:UML类图符号、各种关系说明以及举例
  4. 生成excel表格并下载
  5. vue ajax加载动画,vue 请求加载数据的时候如何显示加载动画
  6. .NET Core 3.0 新 JSON API - JsonSerializer
  7. 原生JS字符串操作方法汇总
  8. Delphi TXLSReadWriteII导出Excel
  9. vs2015-OpenGL绘制三角形
  10. CodeForces - 556C Case of Matryoshkas
  11. OpenFileDialog获取文件名和文件路径问题
  12. openfire源码解读--用户登录
  13. excel模板 基金账本_有哪些好用的Excel个人账单模板?
  14. 最新Django经典面试问题与答案汇总
  15. 智能电子后视镜MFC01-LCD产品标定说明
  16. 人体一机竞技格斗机器人_在格斗机器人比赛中,如何判断输赢?
  17. android Wifi自动连接
  18. 蓝牙BQB证后还会被查的3种情况,蓝牙组织审查
  19. 逾20万人“云围观”,第八届全球云计算大会乘风破浪而来
  20. 阿里云服务器1Mbps带宽到底能够达到什么效果

热门文章

  1. 设计模式之王者原则 开闭原则
  2. 使用idea导出war包
  3. 探访高铁“火花侠”驾驶火龙专列 脚下钢花飞溅
  4. 怎压缩html文件夹,如何利用koala压缩合并js文件?
  5. 请教如何实现SQL查询24小时内,当前时间之前20分钟的信息
  6. 小众原创技术类公众号真实体验: 微信公众号付费阅读能赚多少钱?
  7. 常用JS——string字符串方法
  8. 纯干货版阿里巴巴国际站入门攻略
  9. java模拟摇摆小球程序代码_用java实现跳动的小球示例代码
  10. java子类要调用父类的无参构造函数