最近在搞了一块乐鑫的ESP826-12F模块,实现手机无线控制单片机,模块烧写的固件是机智云32M的,具体烧录过程就不说了,可参考这里http://club.gizwits.com/thread-3551-1-1.html,我这里解释一下源码吧。首先来介绍一下Utils/ ringbuffer,就是环形缓冲区,字面上理解,环形缓冲区,但实际并不是环形,只是模拟出来环形而已,因为内存地址是往一个方向增长的。

图1-内存增长图

先来看看ringbuffer.h
主要是用宏实现了一个求最小值的函数。
还有就是定义了一个环形缓冲区的结构体。

#define min(a, b) (a)<(b)?(a):(b)                   ///< Calculate the minimum valuetypedef struct {size_t rbCapacity;uint8_t  *rbHead;uint8_t  *rbTail;uint8_t  *rbBuff;
}rb_t;

rb_t是环形缓冲区的结构体,rbCapacity为环形缓冲区的容量,指针rbHead指向头部,指针rbTail指向尾部,指针rbBuff指向缓冲区首地址,在创建缓冲区的时候,这些都会初始化。
缓冲区的创建

int8_t ICACHE_FLASH_ATTR rbCreate(rb_t* rb)
{if(NULL == rb){return -1;}rb->rbHead = rb->rbBuff;rb->rbTail = rb->rbBuff;return 0;
}

这个是缓冲区的创建函数,这些开源的代码写的就是比较严谨,一进来首先判断指针是否为空,空的话直接返回(后面的函数也有,后面就不做解释了),这点值得我们学习,严谨,提高程序的健壮性,然后初始化头尾指针,均指向缓冲区首地址。初始化后的指向情况见下图

图二-初始化后指针指向

返回缓冲区的容量

int32_t ICACHE_FLASH_ATTR rbCapacity(rb_t *rb)
{if(NULL == rb){return -1;}return rb->rbCapacity;
}

这个很容易理解,直接返回rbCapacity。

读取环形缓冲区可读数据大小

int32_t ICACHE_FLASH_ATTR rbCanRead(rb_t *rb)
{if(NULL == rb){return -1;}if (rb->rbHead == rb->rbTail){return 0;}if (rb->rbHead < rb->rbTail){return rb->rbTail - rb->rbHead;}return rbCapacity(rb) - (rb->rbHead - rb->rbTail);
}

进来头尾指针是否相等,相等直接返回0,说明无数据可读,接着判断头指针是否小于尾指针,如果是,则直接返回rb->rbTail - rb->rbHead,头尾指针直接相减即为可读数据大小

图三-尾指针大于头指针结构图

如果都不满足,即返回rbCapacity(rb) - (rb->rbHead - rb->rbTail); 缓冲区的容量-(头指针-尾指针)下图实例:21-(7-2)=16

图四-头指针大于尾指针结构图

获取缓冲区可写数据区大小

int32_t ICACHE_FLASH_ATTR rbCanWrite(rb_t *rb)
{if(NULL == rb){return -1;}return rbCapacity(rb) - rbCanRead(rb);  //总容量减去-可读数据区大小
}

读缓冲区数据
rb:准备读的缓冲区
data:读取数据的保存地址
count:要读取的个数

int32_t ICACHE_FLASH_ATTR rbRead(rb_t *rb, void *data, size_t count)
{int32_t copySz = 0;if(NULL == rb){return -1;}if(NULL == data){return -1;}if (rb->rbHead < rb->rbTail)            //结合图三{copySz = min(count, rbCanRead(rb)); //取出要读的数据长度,这里min避免过渡读取,memcpy(data, rb->rbHead, copySz); //读取数据到daterb->rbHead += copySz;            //移动头指针return copySz;                   //返回读取的个数}else    //结合图四{if (count < rbCapacity(rb)-(rb->rbHead - rb->rbBuff)) //判断count<21-(7-0){copySz = count;memcpy(data, rb->rbHead, copySz);      //读取数据到daterb->rbHead += copySz;               //移动头指针return copySz;                       //返回读取的个数}else                  // count>=20-(7-0){copySz = rbCapacity(rb) - (rb->rbHead - rb->rbBuff); // copySz = 21-(7-0)memcpy(data, rb->rbHead, copySz);            //读取数据到daterb->rbHead = rb->rbBuff;      //移动头指针,指向缓冲区首地址,copySz += rbRead(rb, (char*)data+copySz, count-copySz); //递归调用rbReadreturn copySz;}}
}

这里我们假设缓冲区大小为21,方便讲解。
写缓冲区数据
rb:准备写的缓冲区
data:数据的保存地址
count:要写的个数
既然理解了读取数据,那么写数据写数据就是相反的过程,这里,交给你们自己解决,结合上面的图,一步一步啃,很简单的。

int32_t ICACHE_FLASH_ATTR rbWrite(rb_t *rb, const void *data, size_t count)
{int32_t tailAvailSz = 0;if((NULL == rb)||(NULL == data)){return -1;}if (count >= rbCanWrite(rb)){return -2;}if (rb->rbHead <= rb->rbTail){tailAvailSz = rbCapacity(rb) - (rb->rbTail - rb->rbBuff);if (count <= tailAvailSz){memcpy(rb->rbTail, data, count);rb->rbTail += count;if (rb->rbTail == rb->rbBuff+rbCapacity(rb)){rb->rbTail = rb->rbBuff;}return count;}else{memcpy(rb->rbTail, data, tailAvailSz);rb->rbTail = rb->rbBuff;return tailAvailSz + rbWrite(rb, (char*)data+tailAvailSz, count-tailAvailSz);}}else{memcpy(rb->rbTail, data, count);rb->rbTail += count;return count;}
}

今天就先介绍环形缓冲区,有什么问题可以留言,或者发邮件1029292871@qq.com

解析机智云MCU源码相关推荐

  1. PHP爱讯云商城源码v0.7.0-新增app功能

    介绍: PHP爱讯云商城源码v0.7.0,新增app功能+一套app模板. 优化老模板,修复添加多个商品只显示一个的bug. 源码安装方法: 把源码上传到网站目录解压绑定域名,浏览器访问  http: ...

  2. 几款有意思的html游戏推荐(在线云玩+源码)

    前言 作者小时候曾一度沉迷网页小游戏,一直都是7k7k,4399的老熟客了,常玩的像洛克王国.赛尔号.创世兵魂这呀,现在flash浏览器都基本不支持了,无聊时候想玩玩都得先找个合适的浏览器,少了很多乐 ...

  3. 采集网站服务器配置,搭建数据采集云服务器源码

    搭建数据采集云服务器源码 内容精选 换一换 云速建站暂不支持自主搭建代码,您可以考虑通过添加高级代码插件实现相关功能.云速建站是一套基于SaaS模式的建站系统,使用的是云服务平台,不止是一台服务器,一 ...

  4. JAVA物联网云平台源码/Modbus/视频接入 物联网智能看板源码

    JAVA物联网云平台使用 Java 语言.主流技术组合(MQTT.Spring Boot.Shiro.MyBatis.Druid.Ehcache.Thymeleaf.Bootstrap.Swagger ...

  5. java教程解析_【B0666】[java视频教程]全方位深入解析最新版SpringBoot源码新手都能学懂视频教程...

    Java视频教程名称:全方位深入解析最新版SpringBoot源码新手都能学懂视频教程    java自学网[javazx.com]  SpringBoot视频教程   it教程 Java自学网收集整 ...

  6. 最新天方夜谭云助手源码V1.0.1 完全开源版

    介绍: 天方夜谭云助手V1.0.1 安装说明:请先安装终端再安装云助手. 安装前请看说明,爱看不看,不看就算. 该程序目前支持QQ秒赞,QQ秒评,群签到,手机扣扣加速,手游加速,后续更新会加入更多的功 ...

  7. 2020最新云赏源码,视频试看、红包打赏,附安装教程

    源码名称:<2020最新云赏源码> 开发环境:PHP 空间支持:PHP5.6  + MySQL 安装环境:PHP5.4或者PHP5.6 + Apache + MySQL5.5以上 演示站: ...

  8. 智慧停车场管理系统php,智慧停车场管理系统云平台源码

    智慧停车场管理系统云服务器源码 public class ComSysRenew extends BaseEntity { private static final long serialVersio ...

  9. 【微信小程序云工具箱源码】

    工具箱源码,趣味工具微信小程序源码 皮皮趣味小工具小程序源码,支持功能去水印,精选壁纸,图片压缩,文字生成二维码,图片加水印 模拟来电,手持弹幕,掷骰子-等使用小工具,一个小程序有几十个功能. 微信小 ...

最新文章

  1. DataGridView发生异常
  2. 点到线段的距离计算方法
  3. python爬虫接单经历_一个Python小白5个小时爬虫经历
  4. python timer使用-关于定时器的两种使用方法
  5. 批量修改远程linux服务器密码
  6. 实用Python库,这几个你认识不?
  7. 不止代码:友好城市(动态规划)
  8. Intent各种flag解析。
  9. data access components 2.0未响应_Vue2.x 源码剖析之响应式原理
  10. 基于Android系统的IPv6网络接入分析
  11. 接口接收数据_基于原语的千兆以太网RGMII接口设计
  12. 京东天猫茅台抢购代码的一些总结
  13. linux区分三种用户角色,Linux用户角色划分
  14. 数据库时间慢了14个小时,Mybatis说,这个锅我不背~
  15. 加州大学戴维斯计算机博士生,关于加州大学戴维斯分校博士研究生CSC奖学金信息分享会的通知...
  16. 影响你选择职业的,跟个人相关的主要的因素
  17. springboot-01
  18. coursera android,Coursera
  19. Java精品项目源码第94期房屋租赁管理系统
  20. js实现,点击侧边导航栏,可以平缓的跳到界面指定位置,同时当界面某个元素在浏览器可视范围的时候,相应的导航栏也显示相应的样式

热门文章

  1. pgsql 一键修改PGSQL表名、字段名为小写
  2. 为你的梦想和目标去真正付出【时任树熊WIFI CTO时的一次内部分享】
  3. 博客(blog.m1kh.com)
  4. 车内看车头正不正技巧_路边侧方位实用停车技巧,学会这一招,再也不担心车头刮到前车...
  5. OpenGPU.org域名已经被劫持
  6. 计算机语言python怎么读,python编程怎么读音发音
  7. 华人工程师盗窃苹果商业机密,后果有多严重?
  8. HTML学生个人网站作业设计:公益专题扫黑除恶(HTML+CSS)
  9. EPICS记录参考--计算输出记录(calcout)
  10. 用一组方程表示一个平面