解析机智云MCU源码
最近在搞了一块乐鑫的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源码相关推荐
- PHP爱讯云商城源码v0.7.0-新增app功能
介绍: PHP爱讯云商城源码v0.7.0,新增app功能+一套app模板. 优化老模板,修复添加多个商品只显示一个的bug. 源码安装方法: 把源码上传到网站目录解压绑定域名,浏览器访问 http: ...
- 几款有意思的html游戏推荐(在线云玩+源码)
前言 作者小时候曾一度沉迷网页小游戏,一直都是7k7k,4399的老熟客了,常玩的像洛克王国.赛尔号.创世兵魂这呀,现在flash浏览器都基本不支持了,无聊时候想玩玩都得先找个合适的浏览器,少了很多乐 ...
- 采集网站服务器配置,搭建数据采集云服务器源码
搭建数据采集云服务器源码 内容精选 换一换 云速建站暂不支持自主搭建代码,您可以考虑通过添加高级代码插件实现相关功能.云速建站是一套基于SaaS模式的建站系统,使用的是云服务平台,不止是一台服务器,一 ...
- JAVA物联网云平台源码/Modbus/视频接入 物联网智能看板源码
JAVA物联网云平台使用 Java 语言.主流技术组合(MQTT.Spring Boot.Shiro.MyBatis.Druid.Ehcache.Thymeleaf.Bootstrap.Swagger ...
- java教程解析_【B0666】[java视频教程]全方位深入解析最新版SpringBoot源码新手都能学懂视频教程...
Java视频教程名称:全方位深入解析最新版SpringBoot源码新手都能学懂视频教程 java自学网[javazx.com] SpringBoot视频教程 it教程 Java自学网收集整 ...
- 最新天方夜谭云助手源码V1.0.1 完全开源版
介绍: 天方夜谭云助手V1.0.1 安装说明:请先安装终端再安装云助手. 安装前请看说明,爱看不看,不看就算. 该程序目前支持QQ秒赞,QQ秒评,群签到,手机扣扣加速,手游加速,后续更新会加入更多的功 ...
- 2020最新云赏源码,视频试看、红包打赏,附安装教程
源码名称:<2020最新云赏源码> 开发环境:PHP 空间支持:PHP5.6 + MySQL 安装环境:PHP5.4或者PHP5.6 + Apache + MySQL5.5以上 演示站: ...
- 智慧停车场管理系统php,智慧停车场管理系统云平台源码
智慧停车场管理系统云服务器源码 public class ComSysRenew extends BaseEntity { private static final long serialVersio ...
- 【微信小程序云工具箱源码】
工具箱源码,趣味工具微信小程序源码 皮皮趣味小工具小程序源码,支持功能去水印,精选壁纸,图片压缩,文字生成二维码,图片加水印 模拟来电,手持弹幕,掷骰子-等使用小工具,一个小程序有几十个功能. 微信小 ...
最新文章
- DataGridView发生异常
- 点到线段的距离计算方法
- python爬虫接单经历_一个Python小白5个小时爬虫经历
- python timer使用-关于定时器的两种使用方法
- 批量修改远程linux服务器密码
- 实用Python库,这几个你认识不?
- 不止代码:友好城市(动态规划)
- Intent各种flag解析。
- data access components 2.0未响应_Vue2.x 源码剖析之响应式原理
- 基于Android系统的IPv6网络接入分析
- 接口接收数据_基于原语的千兆以太网RGMII接口设计
- 京东天猫茅台抢购代码的一些总结
- linux区分三种用户角色,Linux用户角色划分
- 数据库时间慢了14个小时,Mybatis说,这个锅我不背~
- 加州大学戴维斯计算机博士生,关于加州大学戴维斯分校博士研究生CSC奖学金信息分享会的通知...
- 影响你选择职业的,跟个人相关的主要的因素
- springboot-01
- coursera android,Coursera
- Java精品项目源码第94期房屋租赁管理系统
- js实现,点击侧边导航栏,可以平缓的跳到界面指定位置,同时当界面某个元素在浏览器可视范围的时候,相应的导航栏也显示相应的样式
热门文章
- pgsql 一键修改PGSQL表名、字段名为小写
- 为你的梦想和目标去真正付出【时任树熊WIFI CTO时的一次内部分享】
- 博客(blog.m1kh.com)
- 车内看车头正不正技巧_路边侧方位实用停车技巧,学会这一招,再也不担心车头刮到前车...
- OpenGPU.org域名已经被劫持
- 计算机语言python怎么读,python编程怎么读音发音
- 华人工程师盗窃苹果商业机密,后果有多严重?
- HTML学生个人网站作业设计:公益专题扫黑除恶(HTML+CSS)
- EPICS记录参考--计算输出记录(calcout)
- 用一组方程表示一个平面