从零开始搭建微信硬件开发环境全过程——1小时掌握微信硬件开发流程

最后更新于:2022-04-01 06:58:22

笔者决定在嵌入式企鹅圈2016年的首篇文章中,发表微信硬件物联领域极具实践价值的文章,它将能指引和帮助任何有兴趣于物联网开发的童鞋们快速掌握微信硬件开发流程,只需一个小时,而再不需要通过揣摩微信硬件浩瀚的文档资料来完成艰难构建。 笔者之前曾经撰写过一篇文章《[基于微信硬件公众平台的智能控制开发流程](http://blog.csdn.net/yueqian_scut/article/details/47380109)》介绍微信硬件开发的流程,但该篇文章是理论性的描述。而本篇文章是完全可操作实践的,请结合两篇文章理解。 本篇文章的目的是快速搭建微信硬件开发的环境,完成微信硬件物联Demo。直接上图,傻瓜式教程! **1.申请微信硬件测试公众号** 链接:[http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login](http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login),用自己的微信扫一扫即可以完成注册申请。微信测试公众账号重要信息包括:appID、appsecret和微信号。开发工程师代表厂商/运营商的角色,所以这里的微信号其实是代表厂商/运营商的微信ID. ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a50a263.jpg) **2.开通测试微信公众账号的设备功能接口** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a51952d.jpg) 开启后如下图: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a526abe.jpg) **3.添加设备产品,获得产品编号** 点击设置进行添加: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a534cbd.jpg) 添加后可以看到产品的编号,如下图。这里只是演示,选择设备品类为“血压计”,其编号是4735\. 表明要生成微信蓝牙血压计(其实是笔者的微信蓝牙开发板)。![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a5538a4.jpg)  **4.蓝牙设备授权** 微信硬件平台的核心功能之一就是对硬件设备进行身份管理。授权即是硬件设备的身份注册,其需要硬件设备的唯一地址码MAC(例如新生儿的指纹)以及人为给这个硬件设备起的名字id(例如新生儿的姓名)。 授权我们通过微信网页调试工具进行,链接是:[http://mp.weixin.qq.com/debug/](http://mp.weixin.qq.com/debug/)。 1)获取access_tocken ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a5653cd.jpg) 2) 设备授权 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a577752.jpg) 授权字段定义请参考:[http://iot.weixin.qq.com/document-2_6.html](http://iot.weixin.qq.com/document-2_6.html)。也可以按照以下修改: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a592f04.jpg) 这里要特别注意,微信硬件平台有时更新了策略又没说明白,坑很多。应该在2015年9月前注册的测试号可以在不写product_id时也能成功授权,但最近注册的测试号如果不写这个product_id会报以下错误: {"errcode":100020,"errmsg":"accountquota not enough"} 说是“账号设备授权配额已用完,需重新申请”。晕倒,我刚注册的账号,配额就用完了,天知道微信为什么要这么搞。最后增加产品编号product_id即可以完成注册。   **5.微信硬件测试公众号自定义菜单** 1)  获取access_tocken,同上。 2)  自定义菜单,定义两个按钮 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a5a144c.jpg) 自定义菜单的效果如下:如果用户关注了该公众号,则进入该公众号后会看到底部有开灯和关灯两个button: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a5b5f96.jpg) **6.部署后台开发环境** 1)   安装JDK,安装后设置系统高级环境变量JAVA_HOME,指向JDK的安装目录。 2)   安装tomcat,修改apache-tomcat-7.0.64\conf\server.xml,将web服务端口改为80 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a5c9e5d.jpg) 3)   启动tomcat, 点击apache-tomcat-7.0.64\bin\startup.bat 4)   安装MyEclipse 5)   MyEclipse配置Tomcat ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a5de0ca.jpg) 6)   下载微信蓝牙后台服务样例工程roseblue ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a6055e3.jpg) 7)   MyEclipse导入roseblue工程 8)   MyEclipse配置服务推送,即生成类文件并拷贝到tomcat的对应目录(apache-tomcat-7.0.64\webapps)。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a620810.jpg) 9)       后台工程配置,修改工程配置属性指向微信测试账号 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a63d186.jpg) **7.配置微信测试公众号的第三方服务地址,指向tomcat所在的web服务目录** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a654982.jpg) **8.MyEclipse生成设备二维码** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a666902.jpg) 这里的device_id和mac两个值和设备授权时的值务必保持一致。Device_id可以任意取值,而mac必须是蓝牙设备的真实MAC地址。 以Java application直接运行这个类可以生成设备二维码,生成路径可以修改: ![](image/5694bff4af8e6.jpg) **9.手机用户扫描关注这个设备二维码,完成设备绑定。** 例如昵称为O的微信用户绑定了这个设备,则在微信测试公众号的后台可以看到它的微信号。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a696380.jpg) **10.修改roseblue工程的通信设备配置** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a6b1429.jpg) 暂时不使用数据库,可以将所有的数据库操作注释掉,并直接硬编码。 deviceType即是第1步里面的微信号 deviceID即是设备授权时的deviceID openID是绑定这个设备的用户的手机微信ID,如昵称为O的微信ID。 11.实现Airsync协议的微信蓝牙开发板上电,开始广播。 12.微信昵称为O的用户打开订阅的微信测试公众号,开始自动扫描并连接微信蓝牙开发板。 13.公众号连上微信蓝牙开发板后,即可以发开灯和关灯指令,对微信蓝牙开发板进行控制。 **如果想要以上安装程序和代码敬请关注嵌入式企鹅圈,并发消息给嵌入式企鹅圈获取资讯。**   OK, 所有的微信硬件开发流程全部完成!可以看到,当你拥有一块实现Airsync协议的微信蓝牙开发板时,即可立刻开始微信硬件物联的Demo。笔者研发的基于Ti CC2541的微信蓝牙模组和微信蓝牙开发板已经量产,能够同时支持微信Airsync协议和一般APP串口透传,用户可以直接在此基础上进行应用控制开发。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a6cf396.jpg) 你希望立刻拥有这块开发板吗?还记得嵌入式企鹅圈2015年的总结吗?原创技术分享是互联网的核心理念,如果你能够关注嵌入式企鹅圈后向嵌入式企鹅圈投稿(yqwucheng@163.com)一篇有关嵌入式和物联网相关的原创技术总结,一经录用,嵌入式企鹅圈将会赠送你一块微信蓝牙开发板! 笔者前天受邀请到深圳参加CSDN优秀专家年底party,分享一下活动合影! ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a6ec7b0.jpg) **更多嵌入式Linux和物联网原创技术分享敬请关注微信公众号:嵌入式企鹅圈** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a143a64.jpg)
';

全球最低功耗蓝牙单芯片(DA14580)系统架构和应用开发框架分析

最后更新于:2022-04-01 06:58:20

DA14580是Dialog公司研制的蓝牙单芯片,号称全球功耗最低,是TI CC2541的四分之一,是运动手环等穿戴类电子产品的常用芯片。但是DA14580的开发门槛不低,适合有蓝牙开发经验的团队来开发,不适合学习爱好者,在网络上搜索DA14580相关的开发文章,基本上都是对官方仅有的几篇文档进行简单翻译,还不如直接阅读英文原文。笔者将对DA14580的系统架构和应用开发框架进行分析,之后再讲解如何进行应用开发。        对于蓝牙单芯片应用开发来说,我们要关注的问题是:蓝牙协议栈方面如何新增一个GATT profile(服务和特征值定义及操作)、SOC内核方面如何驱动外围设备、系统应用框架上如何使用定时器和任务间消息通信等等。DA14580单芯片发布时并不是一颗裸片,而是带有开发平台和SDK包,还有常用的应用例程(如防丢proximity),我们要做的就是通过SDK和相关的文档去理解它整个系统架构和应用框架,在这个基础上才能去完成以上三个方面的开发。 >一、DA14580系统架构 DA14580是基于Cortex M0架构,内置ROM、OTP和RAM。其中ROM固化了大部分协议栈和操作系统(单任务)的代码实现,而OTP一次性编程则是为了降低成本,实现用户的差异化应用需求。当用户通过SPI NORFLASH引导或者直接通过JLINK下载代码到RAM进行调试后,就可以通过SmartSnippets工具下载代码到OTP。量产产品即从OTP开始引导执行。 DA14580集成的是第三方公司RW的蓝牙协议栈IP,范围包括GAT和GAP层及以下。因此我们可以在代码框架目录上看到RW开头命名的目录和头文件,官方文档涉及到蓝牙协议栈方面大部分都是RW公司出品。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a460a68.jpg) >二、DA14580 开发例程目录和SDK目录结构 DA14580的SDK开发平台使用keil,我们先来看看开发例程的目录结构,再来看SDK目录结构。前者简单一些,后者因为涉及到第三方IP、ROM等原因,目录实在是太多太细了,初接手真的会歇菜。 防丢(proximity,英文是接近的意思)的开发目录结构如下: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a4734f0.jpg) 这里需要注意的是,ROM里面的固话代码,包括协议栈和单任务操作系统的相关管理代码也是整个工程应用的一部分,只不过没有列到开发目录里面。 SDK目录架构如下: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a48d947.jpg) >三、蓝牙profile和应用的角色和分工 从工程的代码目录结构来看,每个profile都有一个以profile(如proxr)命名的.c文件,也有一个以profile_task(如proxr_task)命名的.c文件;相应地,每个应用子任务也有一个app_profile(如app_proxr)的.C文件,和app_profile_task(如app_proxr_task)的.c文件。一般地: 在操作系统ke内核看来,Profile和profile_task共同完成一个task任务,其中app_proxr_task的task ID标识是TASK_PROXR。但app_profile和app_profile_task并不是一个具体的task任务,在代码目录的app目录,所有的task,包括app_proxr_task和app_batt_task(电池)、app_sec_task(安全)共同组成一个task,在app.c中完成任务创建,task的ID标识是TASK_APP。各个app_profile_task只不过完成应用的一个子场景功能,如防丢、电池告警等。 app是主动发送消息给profile,以执行相应的蓝牙GATT服务和操作,并接受回调。即app是profile的上层。 Profile任务执行GATT服务/属性的具体创建create、开启服务enable和属性特征的读写等操作,其调用ATT和GAP等底层接口来实现具体功能。Profile作为接口供给app层调用,app是通过消息通信来完成接口调用的。 app_profile的代码一般包括主动调用的接口实现,而app_profile_task则是接受消息回调的接口实现。两者的分工是非常清晰的。 >四、应用开发框架 DA14580的应用开发框架的核心是基于状态机和消息回调。以下分析以防丢proxr为例。 **1.状态机** 每个任务都必须明确自己的状态表,例如proxr的状态表是: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a4a315f.jpg) 状态的初始化和转换是由用户主动切换的。在某个确定的状态时,内核会在对应的状态响应接口集中遍历所有发给该任务的消息。 每个任务都会在初始化时被创建,例如proxr任务的创建是: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a4b1107.jpg) 这时,假设有个其他的任务发一个消息给TASK_PROXR,则会在proxr_disabled中查找相应的消息回调接口,并执行回调。 **2.消息回调** 接下来看看各个状态的响应接口集,例如PROXR_CONNECTED连接状态时的状态响应接口集如下。可见,其会对两个消息进行回调,一个是底层ATT收到对特征值的写操作时执行回调,另一个应用层主动改写另一个特征值。在笔者的防丢和计步应用中,前者是实现防丢告警功能,后者是上报计步数据。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a4c64c3.jpg) **3.任务间通信** 消息发出之后,系统即会执行proxr_jibu_update_req_handler回调。  ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a4d58a4.jpg) 另外,笔者会根据文章的阅读量考虑进一步对DA14580的SDK进行分析,如系统启动过程、服务建立过程以及上面说的,如何进行应用开发,即蓝牙协议栈方面如何新增一个GATT profile(服务和特征值定义及操作)、SOC内核方面如何驱动外围设备、系统应用框架上如何使用定时器和任务间消息通信等等。 更多原创请关注微信公众号:嵌入式企鹅圈 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a4e7662.jpg)
';

以蓝牙开发的视觉解读微信Airsync协议

最后更新于:2022-04-01 06:58:18

微信硬件平台使用蓝牙作为近场控制的连接件,并拟定了《微信蓝牙外设协议》。这份协议更像一个标准,用于规范微信和蓝牙外设之间的数据交互场景和接口。但从开发者来看,要完全读懂这份协议,恐怕需要熟读很多遍,并且要结合调试才能真正实现微信Airsync通信。笔者对IOT和微信硬件平台的整个框架和技术都比较熟悉了,并且已经在TI的CC254X和Dialog的DA14580上实现了微信Airsync协议通信。现在回过头来,从开发的角度,对微信Airsync协议进行重新解读,以帮助新进入物联网领域的开发者更快地掌握微信蓝牙设备通信开发,以让产品快速接入微信硬件平台。        有关微信硬件平台和物联网的架构分析请参考笔者之前的博文,特别是《[一张图读懂基于微信硬件平台的物联网架构](http://blog.csdn.net/yueqian_scut/article/details/49153405)》和《[基于微信硬件公众平台的智能控制开发流程](http://blog.csdn.net/yueqian_scut/article/details/47380109)》。 >一、微信蓝牙物联的技术需求 软件和协议都是需求驱动的。在物联网、移动互联网领域,理解场景是提炼需求的重要方法。那么,我们从场景分析的角度来理解微信硬件平台的蓝牙物联需求。 **1.微信蓝牙物联是一种近场控制场景** 微信硬件平台支持蓝牙和Wifi/3G/GPRS接入。Wifi/3G/GPRS是一种远场控制手段,只要网络可达,那么用户可以在远场(例如办公场所)控制离用户距离很远(例如家里)的物联设备。而蓝牙接入则是一种近场控制手段,用户只能利用微信通过手机的蓝牙来控制20米左右的蓝牙设备。也即是,当蓝牙设备离开手机蓝牙的连接范围,那么用户是控制不了该设备的。 对于蓝牙外设来说,手机就像一个蓝牙网关一样,手机通过蓝牙来跟蓝牙外设进行通信,将得到的数据通过手机的wifi或者3G/4G信号与云后端(微信公众平台、第三方云服务端)交互。前者是基于微信Airsync协议,后者则是微信制定的基于TCP/IP协议的《设备接入接口协议》。 **2.蓝牙外设身份注册** 微信硬件平台只提供两部分核心的物联功能,一是身份管理,二是消息推送。任何一个外设,不管是蓝牙还是wifi,它都将拥有一个唯一的设备ID。设备ID的相关描述请参考《[一张图读懂基于微信硬件平台的物联网架构](http://blog.csdn.net/yueqian_scut/article/details/49153405)》,其包括设备类型(设备厂商的公众号ID)和该设备厂商自行定义的设备ID。这种设计手段和蓝牙MAC地址、网卡MAC地址的设置是一样的。设备ID就是外设的身份。 在外设向微信硬件平台注册身份前,微信硬件平台是不认识这个外设的。所以,我们在使用蓝牙外设前,需要向微信硬件平台注册身份。 对于微信硬件平台而言,设备注册其实就是平台对这个设备进行授权(加入)的过程。接口如下图。其主要通过提交自身的唯一MAC、设备ID来向平台注册。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a3cb844.jpg) **3.蓝牙广播** 对于蓝牙设备来说,它主要的状态包括未连接和已连接两种状态。在未连接时,它需要进行广播。广播的目的是为了让手机微信能够通过蓝牙扫描得知这是一个支持蓝牙Airsync协议的设备。当手机微信识别到是一个支持该协议的外设时,手机微信会发起连接。 那么,广播数据需要包含什么格式的数据才能被手机微信所识别到呢?这就是蓝牙Airsync协议规定的内容。 **4.蓝牙通信** 蓝牙连接之后,自然是数据通信的需求。对蓝牙BLE来说,数据通信都是通过访问某个characteristics来实现的。而characteristics需要支持以下场景: 1)手机微信对外设进行写控制,要求characteristics的write属性。 2)手机微信读取外设的一些信息。当外设和厂商自己研制的APP连上之后,外设处于连接状态,其不会再发出广播信息,此时微信想去连接这个外设怎么办?其是通过读取外设的信息,如MAC,来判断该外设是否支持微信。这要求characteristics的read属性。 以上两种都是手机微信作为主动方,外设是被动。接下来,我们来看看外设是主动时的场景: 3)例如,运动手环需要主动上报用户某个时段的运动步数。在这种情况下,手机微信主动读取运动步数显然是不合适的,因为手机不应该时时刻刻地读这个步数来更新。而应该是手机微信订阅characteristics的信息更新服务,即作为被动方接受外设的信息更新。 对于蓝牙外设来说,characteristics的信息更新有两种,一种是notify,一种是indicate。他们有什么区别呢?对于notify,当蓝牙外设的characteristics的值有变化时,它会主动将新的值告知手机微信,而手机微信收到这个信息更新时不需要回复。而对于indicate属性,手机微信在收到这个信息时需要给蓝牙外设一个简单的回复。 蓝牙BLE通信的characteristics的长度是有限制的,或者说每一帧数据长度是有限的,是20字节。那么,如果蓝牙外设有一串很长的数据要主动传送,很明显,它需要indicate属性才能完成这个任务,即将这段数据按20字节长度进行分帧,每次更新发送之后,需要等手机微信回复之后才能发下一个20字节,直到发完为止。 >二、蓝牙微信Airsync协议开发 根据以上对蓝牙微信物联的技术需求分析,再根据蓝牙BLE的应用开发知识,我们来梳理蓝牙微信Airsync协议的开发要点。 **1.广播** 蓝牙外设广播的目的是让手机微信能够识别到。微信Airsync协议是这样规定蓝牙外设广播数据格式的: 1) 声明自己的ServiceUUID是0xFEE7。 2) 在自定义厂商数据manufature specific data中需以MAC地址(身份注册时的MAC地址,也是该设备真实的MAC地址)结尾,并且要求manufature specific data的长度大于等于8. 蓝牙的广播数据格式定义请参考《Blutoothspecification 4.0》的P1735页,对应以下两个类型: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a3dfbed.jpg) 另外,微信Airsync协议提到广播设备分为两种,一种是普通设备,没有按钮,需要无时无刻地广播数据;另一种是确认设备,即有按钮,即用户按下按钮后才开始广播数据。事实上,现实生活中为了省功耗,不可能时时刻刻都在广播的,都是在用户拿手机过来后,再按下外设按钮之后才开始广播并连接的。但是微信把这种方式称为确认设备会造成困惑啊,又没解释清楚,以为广播之后还要确认什么的。这里明确解释这一点。 对于确认按钮之后的广播数据需要注意的是,在自定义厂商数据manufature specific data中需以0xfe 0x01 0x01 +MAC地址结尾。 **2.蓝牙通信服务** 外设要实现以下特征,并根据具体芯片平台的接口实现各特征字的读写回调过程,以实现具体的应用需求。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a408bf4.jpg) 即写characteristics的UUID是0xfec7, indicate characteristics的UUID是0xfec8\. 这两个是必须的。而read characteristics UUID不支持也没有问题。 **3.蓝牙Airsync协议交互** 满足以上两个条件代表已经能够跟手机微信进行数据通信了。但是交互过程是一个协作的过程,就像我们访问业务系统一样也要先登陆,再初始化后,才能进行正常的业务通信啊。那么登陆和初始化我们可以理解为应用控制信令,而后续的数据通信也是应用数据通信。 蓝牙Airsync协议使用protobuf技术进行封包和解包,详见《[ Protocolbuffer序列化及其在微信蓝牙协议中的应用](http://blog.csdn.net/yueqian_scut/article/details/47606599)》。 1) 登陆 登陆时的数据参数格式是: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a41b9e5.jpg) 微信支持两种登陆身份认证,加密和不加密。这里只讨论简单的不加密认证好了。不加密时,我们一般用MAC地址方式登陆,即将AeSine付空值,AuthMethod赋值为EAM_macNoEncrypt. Author会收到手机微信的回复,在加密时收到的是一个用于之后通信的秘钥,但在不加密是可以忽略。 2) 初始化 初始化的目的是外设生成一个随机数,以后每次通信后,该数值都会自动加1;另外,在初始化的回复中,手机微信可以告诉外设手机微信当前的用的手机操作系统的版本、当前时间、微信用户ID等等。以便于外设记录用户的信息。 初始化的数据参数格式是: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a434fa5.jpg) 初始化成功之后就可以正常通信了。 微信提供一个叫做airsyncDebug的工具用于调试,如果能正常与它连接通信,那就代表着可以跟微信进行正常通信了。 >三、蓝牙Airsync协议学习开发步骤       1.     初步理解微信规范《蓝牙外设协议》。 2.     理解本文 3.     根据本文的分析理解微信官方实现的基于NRF81522平台的外设例程。 4.     在自己的蓝牙单芯片平台开发实现Airsync协议,并结合airsyncDebug进行调试。 你将会事半功倍!祝好运! 更多嵌入式Linux和物联网原创分享,请关注微信公众号:嵌入式企鹅圈 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a143a64.jpg)
';

蓝牙防丢器原理、实现与Android BLE接口编程

最后更新于:2022-04-01 06:58:15

本文是对已实现的蓝牙防丢器项目的总结,阐述蓝牙防丢器的原理、实现与android客户端的蓝牙BLE接口编程。在这里重点关注如何利用BLE接口来进行工程实现,对于BLE的协议、涉及到JNI的BLE接口内部源码实现,笔者以后再详细剖析。但要求读者对BLE协议有一定的认识,如GAP、GATTprofile在BLE中的角色和作用,如何使用Service、Characteristic等。 >一、蓝牙防丢器原理和产品需求 蓝牙防丢器的核心原理是根据接收到的蓝牙设备端的无线信号强度(RSSI)来估算距离。其计算公式是: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a3b7935.jpg) d是计算距离,RSSI是信号强度,A为发射端和接收端相隔1米时的信号强度,n是环境衰减因子。对于不同的蓝牙设备该值是不一样的,同样的设备在不同的发射功率的情况下其信号强度也是不一样的,而且对于同是1米的情况下,环境对于信号强度也是有影响的。n是环境衰减因子,自然跟环境有关。所以在确切发射功率的情况下,A和n对于同一款设备来说,也是一个经验值。 在实际的防丢器产品中,一般有以下功能: 1\. 当手机(接收端)检测到发射端设备的距离超过一定距离时,发出告警提示,设备根据告警级别进行相应的指示,如发出不同频率的音频或者闪灯。 2\. 当发射设备端发现和手机端建立的链路断开(意味着距离已经超过连接范围)时,其会自动发出某种形式的警告。 >二、蓝牙防丢profile 笔者以业界目前功耗最低的蓝牙单芯片(Dialog公司的DA14580)来说明。针对DA14580,Dialog公司有提供开发SDK(以后会对该SDK框架进行分析,以指导开发),其中就有实现防丢profile,命名是Proximity。     该profile针对以上防丢的功能提供的Characteristic如下: 1.TXP(txpower) Characteristic, 设备端需要通过主机控制接口HCI来获得发射功率参数,并以read属性提供给master。 2.IAS(**immediate alter service**), write属性,供master写告警级别。当master写入新的值时,设备端会收到write的回调,其根据告警级别进行相应告警。 3\. LLS(link loss service),write/read属性,供master设置链路断开情况下默认的告警级别。 RSSI通过接收端的接口来获得,并不需要设备端提供service。 以上Characteristic都通过GATT profile提供服务,在蓝牙通信协议上,每个Characteristic都会对应一个UUID。 >三、android蓝牙BLE接口编程 androidBLE接口在android4.3版本以上提供。 **1.判断当前系统是否支持BLE** getPackageManager().hasSystemFeature(PackageManager.*FEATURE_BLUETOOTH_LE*) 返回真表示支持。 **2.获得蓝牙适配器类** 用户通过统一的蓝牙适配器类BluetoothAdapter来使用BLE API。 先获得蓝牙管理器: BluetoothManagerbluetoothManager = getSystemService(Context.*BLUETOOTH_SERVICE*); 再获得蓝牙适配器实例(单体对象): BluetoothAdaptermBluetoothAdapter = bluetoothManager.getAdapter(); **3.启动手机蓝牙硬件功能(相当于在设置界面开启蓝牙功能)** mBluetoothAdapter.enable(); **4.开始扫描** BluetoothAdapter.startLeScan(android.bluetooth.BluetoothAdapter.LeScanCallbackcallback) callback是当扫描到蓝牙设备时的回调接口。实现callback中的onLeScan接口: @Override **public void** onLeScan(**final**BluetoothDevice device, **int** rssi, **byte**[] scanRecord) 其中,device代表扫描到的设备,可以获得其MAC地址、设备名等等;rssi即信号强度,这是未连接时获取RSSI的方法;scanRecord代表扫描设备得到的响应参数,ibeacon即通过该参数来获得广播内容。 假设String bluetoothAddress = device.getAddress(),获取蓝牙48位MAC地址 **5.连接GATT,获取设备端的UUID服务,并进行数据通信交互** 通过MAC地址获得代表设备端的蓝牙设备类 BluetoothDevicedevice = mBluetoothAdapter.getRemoteDevice(bluetoothAddress); 连接GATT BluetoothGatt mBluetoothGatt = device.connectGatt(android.content.Context context, booleanautoConnect, android.bluetooth.BluetoothGattCallback callback); Callback是连接GATT之后,所有数据交互的回调入口。分别包括: 1)设备服务发现 @Override **publicvoid**onServicesDiscovered(BluetoothGatt gatt, **int** status) mBluetoothGatt.getServices()代表设备服务集合, **for** (BluetoothGattService gattService : mBluetoothGatt.getServices()) 对于每个服务service,用getUuid()可以获得服务的UUID,getCharacteristics()代表该服务的Characteristic集合。 **for**(BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) 对于每个Characteristic,getUuid()获得UUID,getPermissions()获得属性权限,getValue()获得属性值。 在该回调中我们只提取感兴趣的三个Characteristic的UUID,对于其他的如电池、设备服务等UUID可以不管。 *gattCharacteristic_char5_TXP=*gattCharacteristic; 2)连接状态改变 @Override **public void**onConnectionStateChange(BluetoothGatt gatt, **int** status,**int**newState) 有两种状态,BluetoothProfile.*STATE_CONNECTED*代表连接,BluetoothProfile.*STATE_DISCONNECTED*代表断开连接。 3)读回调 @Override **public void**onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristiccharacteristic, **int**status) 其对应手机端发出读请求后,当收到设备端的数据时的回调。如 mBluetoothGatt.readCharacteristic(*gattCharacteristic_char5_TXP*) 4)设备端数据变化回调 这里对应设备的characteristic的属性是notify或者indication,即相当手机端订阅这个characteristic的值变更服务,当设备端的characteristic发生变化时,设备端会主动发出通知给手机端。 @Override **public void** onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristiccharacteristic) 在回调中获得新的值characteristic.getValue()。 5)获取到RSSI值的回调 RSSI在扫描时可以通过扫描回调接口获得,但是在连接之后要不断地使用 mBluetoothGatt.readRemoteRssi()向底层驱动发出读取RSSI请求,当底层获取到新的RSSI后会进行以下回调: @Override **public void**onReadRemoteRssi(BluetoothGatt gatt, **int** rssi, **int** status) rssi即是新的信号强度值。 连接后,由于手机和设备端的距离在发生变化,因此要不断地读取RSSI,实时计算两者之间的距离才能保证防丢功能的实现。 Android 4.3之后的SDK有提供BLE接口使用的样例,可以通过研读源码进行理解。对防丢器的蓝牙设备端和android客户端的开发感兴趣者可以关注 微信公众号:嵌入式企鹅圈 进行交流。谢谢!嵌入式企鹅圈分享嵌入式Linux和物联网原创技术经验,敬请关注: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a143a64.jpg)
';

物联网核心协议—消息推送技术演进

最后更新于:2022-04-01 06:58:13

消息触达能力是物联网(internet ofthings, IOT)的重要支撑,而物联网很多技术都源于移动互联网。本文阐述移动互联网消息推送技术在物联网中的应用和演进。 >一、物联网架构和关键技术       从开发的角度,无线接入是物联网设备端的核心技术,身份设备管理和消息推送技术是物联网云端的核心技术。而从场景体验的角度,除了前者,还要包括手机的前端开发技术。       在上一篇《[一张图读懂基于微信硬件平台的物联网架构](http://blog.csdn.net/yueqian_scut/article/details/49153405)》博文中,笔者曾用一张大图详细描述了基于微信硬件平台的物联网架构的组成要素、关键场景、和通信协议(应用层和TCP/IP层)。本文则重点描述物联网各部分之间的通信技术实现。       IP互联架构已是物联网的事实标准(有关物联网TCP/IP层关键技术将另文阐述,敬请关注)。本文所讲的消息推送技术是基于TCP/IP协议的应用层协议技术。 我们先进一步抽象基于IP架构的物联网组成,如下图(忽略internet和路由等基础技术): ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a3a00ec.jpg) 可见,核心组成就是物联设备things、网关和云端。物联设备分为两类,一类是其自身天然支持TCP/IP而能直接接入物联网,如wifi、GPRS/3G/4G等设备;另一类是其未能支持IP协议而需要网关(协议转换)来接入物联网,如Zigbee、蓝牙等设备。对于蓝牙设备而言,手机其实是一个网关。手机通过自身的蓝牙跟外设蓝牙设备通信,并将消息通过手机的wifi或者3G/4G模块与云服务端通信。 从场景的角度来分析,物联网最终是给人类服务的,而手机是人类体验的最直接入口。因此在上图中可以单独添加手机组成部分,并将其与一般意义上的网关区分出来。这样物联网核心组成就是:设备端—网关—云端—手机。 从应用层开发技术的角度来看,物联网应用是基于TCP/IP架构建立,在屏蔽底层的网关协议转换的基础上,物联网应用的组成部分就是:设备端—云端—手机。 OK,有了以上的介绍,我们就从物联网应用的角度来分析设备、云端、手机直接的消息推送技术,它包括云端和设备端的双向通信技术、手机和云端的双向通信技术。 >二、移动互联网通信模式       互联网有B/S和C/S两种通信模式。在移动互联网领域,APP是以C/S的方式以client的角色跟服务器server进行通信;而微信是一个超级APP,其是通过内置浏览器让用户进行H5编程以获得操控硬件设备的能力,因此微信硬件平台的通信模块是B/S模式。       移动互联网B/S技术跟传统互联网没有区别,微信内置浏览器支持H5,因此可以获得很好的平台扩展性。我们近期重点关注基于微信硬件平台的物联网,因此就围绕B/S模式的消息推送技术讲述其演进。       HTTP协议是B/S的基础,HTTP有GET和POST两种方式。不知道的请百度,然后再往下看:-) >三、消息推送技术演进 **1.HTTP单向通信**       浏览器使用HTML文本标记语言,即浏览器通过HTTP协议向服务器发起请求(请求内容包括URL,即我们常说的网址),服务器将URL对应的HTML内容通过HTTP协议作为响应传送回给浏览器。     1)手机端。微信端因为有内置浏览器,其天然支持前端页面。     2) 云端对手机端推送。云端使用JSP/PHP等技术开发设计前端网页和简单的逻辑即可。       3)设备端。设备端上线时或者访问服务端参数等内容时需要模拟HTTP协议(C语言)向服务器发起请求,而请求的格式一般不使用HTML,而是使用较为简单的XML或者JSON协议格式。       4)云端对设备端推送。云端使用HttpServlet(即使用http协议的servlet)对设备的HTTP请求进行响应,回复XML或者JSON格式的消息。       5)缺点。这种方式通信方式的特点就是一请求一响应,总是要客户端向服务器发出请求,服务器才给予响应。服务器从来都不会主动给客户端发消息,而且在客户端发出请求后,服务器也只是回复一次。这种HTTP单向通信方式在互联网领域发挥巨大的作用,就是服务器端可以是无状态的,极大地简化了服务器的服务流程,提高效率。但在物联网领域,我们要求的是双向的通信能力。服务端要能主动给设备端或者手机发出消息。       在这种模式下,我们怎么做双向通信呢?唯一的做法就是客户端不断地发出请求(或者周期性),服务器不断地给予回复。这种模式下的缺点显而易见:一是网络负载重,服务器每次响应后都会关闭连接,所以每次通信都得重新握手。HTTP协议的头内容的长度可不小。二是实时性差。一般设备端都是周期性地轮询服务器是否有新的消息,轮询的方式是不能获得好的实时性的。三、浏览器端每次发出请求是以HTML全部内容来响应的,消息长度过大,在这种情况下,会发现浏览器页面不断地刷新。 **2.Ajax轮询**       Ajax技术是浏览器支持的一种JavaScript技术。其能够局部改善用户体验技术,让用户在不察觉浏览器页面刷新的情况向服务器发出请求,并获得响应。其原理是: 1)微信浏览器发出URL页面请求,服务器响应HTML页面内容。 2)HTML页面使用js调用XMLHttpRequest来向服务器发出异步通信请求。 3)服务器响应XML格式数据给浏览器页面。 4)HTML页面使用DOM模型来动态刷新页面元素。       Ajax技术是微信硬件平台框架中推荐的页面交互技术,但其本质还是遵守HTTP单向通信的规则,只是页面交互时不需要刷新整个页面。其双向通信实时性问题依然未能解决。 **3.Websocket**       Websocket是HTML5支持的一种新的协议,它能够真正支持浏览器和服务器之间进行双向通信。Tomcat7及以上版本也已经支持Websocket API。       1)为了能够兼容浏览器HTTP协议,Websocket规定在第一次发起请求时依然要发出符合HTTP协议规范的Header,但其Connection域的值是Upgrade,并增加Upgrade域,值是socket,即告知服务器,即将建立的通信是Websocket双向通信。服务器如果接受,会返回101给客户端进行协议切换。       2)接下来的通信将不再以HTTP作为传输协议,而是使用Websocket规定的数据格式进行通信,其分为控制帧和数据帧。控制帧是发出心跳帧(ping),而服务器响应pong,还有结束帧;数据帧就是真实数据格式,其格式头只有6个字节(2个字节头和4个字节的掩码),后面就是真实的数据(经过掩码转换)。比HTTP格式头的长度要小多了。       3)客户端和服务器之间是一直保持连接,直到close,当前期间要发发2个字节的3字节的ping帧。       可见Websocket比ajax有了极大的改进。其不仅省掉经常要连接握手,还简化的协议的格式,最重要的是实时性得到保证,因为双方是真正的全双工通信。       微信浏览器客户端支持Websocket,服务器使用Tomcat7以上的WebsocketServlet类,设备端要根据Websocket协议用C语言来模拟通信。       我们在用设备端模拟Websocket通信协议时一般会先看协议,再用HttpWatch等工具来抓包,抓到的头是GET ws://ip:port/path,如果在C语言也是这样模拟发包则会报400 bad request。因为C语言利用socket建立通信时已经利用了IP和port了,其发的第一个包的头是GET/path即可,不能在其前面加上ws://ip:port/。 **4.MQTT**       以上的分析都是将移动互联网的技术运用到物联网,其都有一个特定就是建立连接时会传送URL地址,由两个角色是客户端和服务器,这种架构我们一般称为是RESTful架构(另外,还有SOAP 面向应用的web services架构)。RESTful架构在互联网得到越来越广泛的运用,但物联网除了互联之外,还有其独有的特征,就是其终端设备的资源有限、低功耗运用场景、网络连接环境差(时不时断开连接)等。用C语言模拟的方式来使用RESTful架构(如Websocket)会使得终端的负荷较重,而且服务器发给终端设备的消息有可能因为断开连接而收不到。       MQTT是IBM针对物联网退出的一种轻量级协议,建立于TCP/IP层协议之上。其是物联网的重要组成部分,可能会成为物联网的事实标准。其具有QoS,能够缓冲消息,并通过重传机制保证终端设备收到消息;其消息格式极其简化,最短是两个字节;其提供订阅和发布模式,高效推送消息。       MQTT有三个角色,包括服务器代理、订阅者和发布者。 1)启动服务器代理。 2)订阅者向服务器代理订阅相关主题。 3)发布者向服务器代理发布主题信息。 4)服务器代理想所有订阅该主题的订阅者推送消息。 MQTT有C/C++语言和JAVA包实现。需要明确的是,MQTT更适用于设备终端和手机APP socket通信,而不能支持浏览器使用。如果要支持微信浏览器应用,还需要增加类似WebsocketServlet技术给浏览器提供支持,这时MQTT以JS接口进行封装,并被调用完成消息推送。 **5.CoAP**        CoAP是受限制的应用协议(ConstrainedApplication Protocol)的代名词。其基于UDP协议,也就是在设备终端上只需要底层实现UDP协议,而不需要实现较为复杂的TCP协议。这种协议用得比较小。笔者也没有用C语言模拟过,就不展开了。 更多原创嵌入式Linux和物联网开发技术分享请关注微信公众号:嵌入式企鹅圈 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a143a64.jpg)
';

揭开智能配置上网(微信Airkiss)的神秘面纱

最后更新于:2022-04-01 06:58:11

本文介绍微信利用Airkiss技术对wifi设备进行智能配置上网的场景,并分析其实现的原理。这里再次说明,Airkiss只是用于配置上网,其跟微信硬件平台的通信流程和接入协议规范完全没有关系。一个wifi设备并不一定要通过Airkiss技术来配置上网,它也可以利用传统的方法来配置,也可以利用其它厂商的智能配置技术来完成配置。所有的wifi智能配置上网技术的原理基本上都是一致的,其开山鼻祖应该是TIsmartConfig。 目前几乎所有的主流wifi厂商都提供了Airkiss的接口库,但并没有说明其原理和实现过程。网上也只见一份Airkiss技术实现方案文档,但需要对无线通信和socket编程有一定基础的人才能理解。本文尽可能深入浅出地分析这项技术,帮助大家理解。 >一、传统配置上网过程 例如我们买了一个路由器,路由器是没有按键和屏显示的。而我们都知道,路由器要配置好运营商的账号和密码才能接入互联网的。一般的做法都是路由器作为热点AP,其提供一个WebServer来设置路由的各项参数,默认IP是192.168.1.1(或者其他IP,路由器说明书上会说明);我们通过电脑有线接入路由器,通过DHCP自动分配到一个192.168.1段的地址。然后通过浏览器来访问[http://192.168.1.1](http://192.168.1.1/),即可以进入路由器设置界面进行设置,包括运营商的账号和密码、本机的SSID和密码。然后我们的手机就可以开启wifi扫描到SSID,输入密码即可以访问互联网了。 再比如,我们家里已经有了一个可以上网的路由器(SSIDx和pwdx)。我们购买了一个无线摄像头装在家里。它自然也要连到家里的路由,才能访问这个摄像头的厂商,这样我们才可以用手机的APP接收到厂商服务器传过来的数据进行显示。摄像头也没有显示屏和按键(reset键不算啦)。传统的配置方法是: 1)摄像头恢复出厂设置后默认进入AP(热点)+Station(工作站)状态。AP热点的SSID和密码由摄像头的说明书说明,是厂商默认的。手机通过wifi连接到该AP,然后通过浏览器访问[http://192.168.1.1](http://192.168.1.1/)(也是厂商默认的),在该界面设置家里的路由器的SSID和密码,便于其作为Station连入家里的路由器。 2)当摄像头连接路由器成功后,其即单独以Station的模式运行(不用再做AP可以省功耗),其会立即访问厂商的服务器(其内部程序代码会hardcode厂商服务的域名或者IP),告知其已经上线,并且要在一段周期内发送Beacon心跳包维持长连接。 3)手机断开摄像头的AP热点,连接家里的路由器。打开摄像头的APP,即可以通过厂商服务器查看家里的摄像头的效果。 所以传统的配置上网方法是wifi设备必须以AP的模式运行,配置好以后再转回Station模式运行。是不是比较费事? >二、智能配置上网流程 智能配置上网最新走进人们视野好像是庆科在大张旗鼓地宣传其智能插座的一键配置功能,其实最早是Ti推出的技术。它是怎样操作呢? 1)wifi设备以Station混杂模式运行。 2)手机智能配置APP通过某种协议包发送家里路由器的SSID和密码。 3)wifi设备通过抓包获取到SSID和密码,然后连接家里的路由器。 整个过程是不是很简单? >三、智能配置的基本原理 1.混杂模式 这里有没有注意到,wifi设备刚开始同样是以Station的模式运行,但是还有一个混杂模式。是什么意思?它是指正常的wifi设备都有一个MAC地址,其硬件电路会自动过滤目标MAC地址跟其MAC不同的数据包。开启混杂模式就是我们平常时说的抓包,就是空中符合802.11格式的数据包都接收进来,不管MAC是否一样。 很明显,手机智能配置APP并不知道该wifi设备的MAC地址,所以手机wifi发送出的数据包,通过家里的路由器转发出去时,wifi设备必须要在混杂模式下才能接收到这些数据包。 2.信道切换 802.11有多个信道,某个时刻wifi设备和路由器都是处于某个信道。路由器一般都是默认在第6个信道。所以如果想家里的wifi信号更好一点,可以尝试将路由器的信道改到一个其他值,这样就不会跟邻居家的wifi信道重叠了。无线信号混在同一个频道就会干扰的。 同理,我们也不能假定wifi设备是处于哪个信道,但我们可以在APP中确定手机wifi的发送信道,这样可以要求wifi设备在一定的时刻内切换信道,以便于接收数据包。当wifi设备检测到有效的数据包后,要锁定在该信道进行后续通信。 3.利用数据帧的长度来承载有效信息       我们先来看看802.2 SNAP(802.11物理层协议)的数据帧格式: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a36c50e.jpg)       我们不去深入研究各个字段的含义,只需要知道DAT是加密的,如路由器都会通过WAP2、WEP等方式加密数据等。而DA(目标MAC)、SA(源MAC)、LLC(逻辑控制)、SNA(厂商代码和协议标识)、FCS(校验码),这五个字段虽然是没有加密的,但是APP层的应用编程难以改变这些字段,需要操作系统才有权限修改,所以最终能够利用的字段就是Length,其没有被加密,而且能够被应用层编程所控制。       由于Length是两个字节,但是一帧最长是1492个有效数据,所以也不能完全利用16个比特。以最简单的方法来使用Length就是使用其中的一个字节,这样如果我们要发送数据0x12345678,那就连续发8个数据帧,第一次的长度是1,第二次的长度是2,以此类推。 >四、微信Airkiss       Airkiss顾名思义是飞吻的意思,即手机发送的SSID和密码经过路由转发出去,被目前wifi设备所检测并截获到。无线网络协议一般场景都规定station只能和AP通信,而不能station和station通信(这种场景叫做AD-Hoc点对点)。接下来我们分析SSID和pwd怎么利用Length进行编码的过程。 **1.物理层** 发送4个字节的前导码序列,{1,2,3,4}。即发送4个数据帧,帧长度分别是1,2,3,4.其要解决两个问题: 1)空中充满无线信号,通过前导码来识别出符合airkiss协议的数据包的开始。 2)数据包的数据是经过加密的,发送方的数据帧的有效数据的长度是1,经过编码后的长度会发送变化。假设加密后的长度为N,那接收方接收到的数据长度是N。以后所有的数据帧接收的长度是M时,那发送方真正的数据长度是M-N+1。 Airkiss规定数据的长度使用9个bit进行编码。 **2.数据链路层** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a382c38.jpg) 数据链路层的包括控制字段和数据字段。 1)Magic为4个数据帧,两个帧的两个9bit记录将要发送的数据(PWD+Ramdon+SSID)的长度;两个帧的两个9bit记录SSID的CRC校验值。路由器的SSID是会被路由器广播出来的,例如我们手机wifi扫描到路由器的名称就是SSID。因此wifi设备也能得到路由器的SSID,其只要计算目前所能获取到的SSID的CRC值跟MAGIC的SSID CRC值一样,那之后的SSID数据就不用接收了,这样能够提高配置上网速度。Magic很重要,因此发送5遍。 2)PrefixCode为4个数据帧,两个帧的两个9bit记录PWD的数据长度,另外两个帧的两个9bit记录PWD长度的CRC校验值。Magic中发送的长度是所有数据的长度,包括密码PWD、随机数(wifi配置成功后要回复该随机数作为回复)和SSID。而这里是PWD的长度,用于对接收到的数据进行分段。 3)一个序列包括一个序列索引和一个序列数据。协议规定将有效数据以4个字节进行划分,不够补0。如我家路由的PWD是8313huang,那其会分为3个序列,分别是“8313”、“huan”“g\0\0\0”进行发送。Sequence header包括索引值和CRC值,而Data field就是4个数据帧,包含要发送的数据,如“8313”等。 4)如何区分Magic、Prefix、Sequence和Data,是由9bit的最高几个bit来区分的。例如最高bit为1时表示是Data,其他是控制字段。 **3.应用层**       应用层即是手机配置上网APP要发送的数据,包括三部分的数据。分别是:       1)PWD。其先被发送是因为其是最重要的,而SSID已经在MAGIC字段中所确认。       2)1个字节的随机数。wifi配置成功后要发送以该随机数为内容的UDP广播包作为回复,APP收到后即认为wifi设备已经成功联网。       3)SSID。 >五、ESP8266 Airkiss       微信硬件开放文档有《airkiss_developer_manual.pdf》介绍在ESP8266平台上利用Airkiss接口库进行开发实现Airkiss协议的过程。而ESP8266的厂商提供的DEMO则更加直接地用一个接口就实现了Airkiss。 >六、微信Airkiss       微信Airkiss在正式产品中是需要通过硬件JSAPI进行调用来调出发送SSID和PWD的界面,而硬件JSAPI需要经过验证的服务号才能申请获得权限。没有权限时可以使用AirkissDebugger这个APP进行调试。 敬请关注微信公众号:嵌入式企鹅圈,获取更多嵌入式和物联网原创技术分享! ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a143a64.jpg)
';

一张图读懂基于微信硬件平台的物联网架构

最后更新于:2022-04-01 06:58:09

本文从物联网的核心要素、物联网的关键场景、微信硬件平台的通信协议分析三个维度去分析基于微信硬件平台的物联网架构。相关的背景知识请阅读微信公众号:嵌入式企鹅圈发布的有关物联网和微信硬件专题文章。 >一、 基于微信硬件平台的物联网架构图示 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a34e2da.jpg) 上图涵盖以下信息: 1.   基于微信硬件平台的物联网的架构组成,有微信公众平台/硬件平台、第三方厂商云后端、手机微信/公众号、微信硬件设备终端(Wifi和蓝牙BLE)。 2.   绿色代表腾讯向开发者和公众提供的基础平台和服务,并通过红色(airsync/airkiss)定义的硬件外设协议供硬件设备接入,红色(微信硬件平台接入协议,XML/JSON)供厂商云后端接入;蓝牙和紫色区域代表开发者所要完成的任务,其中蓝牙是嵌入式硬件设备终端的任务,紫色是第三方厂商云后端的任务。 3.   物联网各个组成部分之间的通信协议标识。除了红色标识的协议是微信公众平台和硬件平台制定的协议必须遵循外,其他组成部分的协议都是自定义的协议。 4.   Wifi模组的供应商提供的SDK一般都提供socket通信接口,而云后端一般会使用JSP/PHP等web编程技术,因此wifi设备需要模拟HTTP协议跟云终端通信。HTTP是一个标准的公共的通信协议,应用层需要在HTTP之上建立自定义的应用协议来完成设备的控制和交互,而应用协议可以是XML/JSON等等。当然,如果云后端使用底层的socket编程,则wifi设备终端可以不需要模拟http。 5.   蓝牙通过airsync协议接入微信,该协议规定了设备发现、绑定、登陆、初始化、接收用户指令、主动发送消息等过程。 6.   Airkiss是通过JSAPI的方式让用户可以在微信上输入路由器的用户名和密码,然后告知没有按键输入和屏幕显示的wifi设备,让该设备能够连上路由器进入网络在线状态。除此之外,Airkiss跟之后用户和厂商、设备的交互完成没有关系。本质上,Airkiss只是一个配置上网功能,跟物联网的控制和交互无关。 7.   Wifi设备接入微信硬件平台是远场控制,设备只要处于联网在线状态,那手机用户无论在哪里,只要能上网都可以对设备进行控制,典型的例子是在公司上班可以通过手机控制家里的智能插座上电;蓝牙设备接入微信硬件平台必须依赖于手机,是近场控制,典型的场景是手机控制家里的灯和空调等。 >二、物联网的核心要素 本文是从开发者的角度去分析整个微信硬件平台物联网,不去探讨物联网运营之类等领域。那么,从开发的角度,物联网的核心要素什么,微信平台又支持了什么?我的理解是: **1.设备的合法性和唯一性** 微信硬件平台在物联网领域做的事情其实不多,只要仔细想想架构图中的这么多的紫色和蓝色都是留给开发者,而且都是要赤裸裸的编程。对于一般的设备商,他们想接入也是勉为其难啊。在这个体系架构中,微信硬件平台做的最重要的一件事情就是身份认证。 就像一个人出生后要办一张身份证(出生证明的号码也是身份证号码)一样,设备生产出来要想进入微信硬件领域,它就必须到微信硬件平台注册自己的身份,那它拿什么去注册呢,这个依据自然应该是独一无二的,就像每个人的指纹,如果我国的小孩办身份证都以录指纹为依据,那就不会出现那么多拐卖儿童了。现在公安局的做法是什么,是硬生生地把一串身份证数字跟人名绑在一起,跟自然人的生物特征没有一丁点关系!!!设备的独一无二的依据就是48位的MAC地址(或者是MAC地址通过某种加密运算得到的结果)。 接着办身份证/出生证不是要给小孩起个名字吗,以后大家交流就叫名字了,公安局也是叫名字的嘛,不可能每次喊话都把指纹的二进制数字读出来的啊。嗯,那硬件设备注册时也要报备自己的名字,即设备ID。设备ID也应该在微信硬件平台唯一啊,不然会乱的。就像MAC地址一样,有一部分是代表一个设备提供商向世界IETF组织申请的企业识别字段,另一部分是设备商内部的分配。或者像身份证那样,前面6个字段是代表一个人出生时的县区行政区划码,后面的数字才代表自身,但同时要保证在这个行政区里面的唯一性。那微信硬件平台怎么规范设备身份?设备身份包括两个部分,deviceType是设备商/销售商的微信公众号的原始ID,deviceID由设备商/销售商自定义,由设备商保证deviceID在其deviceType中的唯一性。 这就是设备的注册场景。设备注册了以后在微信硬件平台就具有合法性和唯一性了。 **2.设备被访问的合理性和正当性** 设备最终是应该和人/手机用户交互的,否则就失去了物联的意义了。那么哪个用户能够访问这个设备呢? 微信用户要关注设备商的微信公众号和绑定设备才能对设备进行访问。如果不绑定就可以访问,那就是所有用户都能够访问这个设备,这显然是不合理的。你买的智能插座放家里,另一个人也能控制你的插座,多危险。 微信硬件平台确保设备的唯一性,微信公众平台确保微信用户的唯一性,两者通过关注和绑定这个流程建立起完全权利的访问关系。 微信硬件平台是微信公众平台的一个子集,微信硬件平台会利用微信公众平台已有的功能来完成基础服务。 **3.设备和用户交互的消息触达能力** 设备要成为物联网中的一员,必须能够联网,好比人体的神经元,具有能够和外界交流的能力。 微信硬件平台主要从云后端接入和硬件接入两方面作出努力。一是通过airsync协议让蓝牙设备和微信互通,airkiss协议让简单的没有按键和UI交互的wifi设备联网;二是通过制定云后端接入协议来接纳厂商云,通过消息接口和API接口使用户和设备的消息能够相互触达。即设备发出的消息经过微信平台发送到厂商云,厂商云的消息也能主动推送给设备,完成交互。 **4.效率** 扫一扫功能对微信的影响是巨大的,加关注,好友,移动支付等等都通过二维码来完成,设备绑定是二维码。微信硬件平台和公众平台产生的二维码关联了用户、设备ID等信息,通过扫一扫功能能方便地进行绑定,接入进入公众号的消息界面。 物联网涉及到终端、前端和后端等等,是一个大工程,无论从开发的角度,还是从用户使用的角度,都要始终强调便捷的效率,以让用户有足够好的体验,才能使得物联网得以壮大。 **5.消息处理能力—嵌入式系统** 这一点并没有在物联网架构的图示中出现。物联网决不仅仅是一种控制,例如开灯和关灯之类,也不仅仅是简单的通过各种传感器来进行数据采集,未来的物联网一定会让用户不断地提高用户体验,例如多媒体、虚拟与实现、数据决策等等,这部分是由高级的嵌入式系统来完成的。嵌入式系统才是设备的大脑,物联网应该更好地拥抱嵌入式系统。 >三、物联网场景分析和通信协议分析(近场蓝牙控制方案) **1.注册** 上面已有说明 **2.用户绑定** 上面已有说明 **3.连接** 用户在绑定过程中会自动完成对提供设备的厂商的微信公众号的关注。在以后每次进入公众号时,会自动通过手机蓝牙对蓝牙设备进行扫描连接。只有完成airsync协议的蓝牙设备才能连上微信。例如蓝牙设备广播的字段里面要声明自己的MAC地址,这样微信能识别到这个一个要接入微信的蓝牙设备,然后才会主动地连接它。 **4.控制(菜单控制)** 1)用户点击微信公众号提供的菜单,如开灯。 2)消息通过微信公众平台发送给厂商云后端。 3)云后端在自己的数据库内验证微信用户和设备的有效性后,将微信菜单的开灯消息转化为自定义协议的开灯消息(这个协议只有云后端和外设设备所认识),并根据airsync中的protobuf协议对消息体进行打包封装,最后通过调用微信硬件平台提供的API接口主动推送出去。 4)微信硬件平台收到信息后通过微信公众平台回传给微信用户所在的公众号。 5)微信将这个消息根据airsync协议通过手机蓝牙发送蓝牙外设。 6)蓝牙外设收到消息进行相应的处理。 从这个过程来看,直接的菜单控制走的流程太长了,影响效率。下面介绍的JSAPI控制就是直接控制,不需要再通过厂商云来发指令。 **5\. 控制(H5/JASPI控制)**       1)用户点击微信公众号提供的H5网页链接       2)微信浏览器通过H5地址向厂商云后端请求响应,返回H5页面。       3)用户点击H5页面的开灯button       4)button通过JSAPI接口直接向蓝牙设备发出自定义的控制消息,JSAPI蓝牙接口已经封装好airsync协议。       5)蓝牙设备收到消息进行相应的处理。 >四、物联网场景分析和通信协议分析(远场wifi控制方案) **1.注册** 上面已有说明 **2.用户绑定** 上面已有说明 **3.连接** 由于用户和wifi设备并不在一个区域,而是通过网络来连接,因此用户是不直接跟wifi设备打交道的,所有的交互都给通过wifi设备商的云后端进行间接交互。(之前已经说了airkiss只是微信提供的一个配置上网功能,wifi设备经过一次配置后,以后会记住这个路由器的ssid和pwd的,所以配置好一次后,airkiss跟物联网交互一点关系都没有,因此airkiss不应该算在物联网的消息触达协议内)。 用户进入wifi设备对应的公众号后,微信公众号会通过微信公众平台向厂商云订阅和咨询设备的在线状态。因此设备一上线时应该主动联系厂商云后端,告知自己上线了,并不时地发送心跳包维持连接。这样微信公众号一订阅请求,云就返回设备的状态给它。 假设设备在线,云后端返回在线状态,微信公众号就会显示设备连接上。 **4\. 控制(菜单控制)** 1)用户点击微信公众号提供的菜单,如开灯。 2)消息通过微信公众平台发送给厂商云后端。 3)云后端在自己的数据库内验证微信用户和设备的有效性后,将微信菜单的开灯消息转化为自定义协议的开灯消息(这个协议只有云后端和外设设备所认识),然后直接通过网络发给wifi设备。 4)wifi外设收到消息进行相应的处理。 **5\. 控制(H5控制)**       1)用户点击微信公众号提供的H5网页链接       2)微信浏览器通过H5地址向厂商云后端请求响应,返回H5页面。       3)用户点击H5页面的开灯button       4)button通过AJAX接口向厂商云后端发出自定义的控制消息。       5)厂商云接收到消息会转化硬件控制消息,直接通过网络发给wifi设备。       6)wifi设备收到消息进行相应的处理。 从这点来看,wifi设备接入微信硬件平台,微信硬件平台仅仅起到一个入口的作用,消息转发都不经过微信硬件平台了。 >五、微信硬件平台的优与劣 回过头来想想,国内这几年早已经有多家物联网平台,如机智云,yelink等等,它们除了充当公安局的角色确保设备的唯一性,还完成了后端的服务平台,甚至给用户提供物联设备模块,极大地简化了物联设备生产商的开发流程。在这样的基础上,微信硬件平台把那么多的任务丢给了开发者,但还是很多厂商拥抱它,只能说微信是一个超级APP,是一个极佳的入口,掌握了全社会大部分用户的入口。在移动互联网领域,用户数量就是王道。 诚然,用户量巨大和腾讯体量庞大是微信硬件平台物联网的优势,但要想做得更好,是不是考虑给用户多做一些像机智云一样的工作? 呵呵,腾讯又想到了,QQ物联就是。 不过腾讯什么都做了,那方案开发公司怎么活啊:-)         By the way,笔者已经全部完成基于微信硬件平台的物联网解决方案(即蓝色和紫色部分),即将推出demo产品。技术和业务咨询请联系QQ :183550631。更多技术分享请关注微信公众号:嵌入式企鹅圈。谢谢! ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a0d9e17.jpg)
';

如何快速理解一个全新的嵌入式操作系统(续)

最后更新于:2022-04-01 06:58:06

-基于TI CC254X OSAL的分析 当工具链配置完成后,SourceInsight向你展示一份源码工程,不借助百度和开发文档,能否在一两个小时内理解源码的组成框架和接口,进行快速开发? 上一篇《[如何快速理解一个全新的嵌入式操作系统](http://blog.csdn.net/yueqian_scut/article/details/48781937)》我们已经分析了如何快速理解OSAL的任务调度和任务间通信(其实OSAL只是酷似多任务操作系统的单任务系统),再理解好OASL的消息产生和处理过程,我们就能够进行快速开发了。 >一、消息的来源 嵌入式系统的消息包括两种,一是系统消息,包括低电、热插拔等,由系统进程去处理;二是用户消息,包括Timer、按键、串口、绘图等消息,由各应用进程进行处理。对于TI CC254x的OSAL,我们理解好Timer、key、UART就已足够。 >二、HAL OSAL向用户提供HAL硬件抽象层,对CC254x的所支持的硬件模块进行了封装抽象,如timer、key、UART、LED、LCD、flash、ADC等等,并向用户提供硬件模块的操作接口。 CC254x是低功耗蓝牙集成芯片,用户的产品和电路设计一般都会参考官方的典型电路,而OSAL为官方针对典型电路所设计的系统库和接口,用户的代码编程就只需要按照其提供的HAL接口进行调用就可以实现功能,而不需要通过GPIO级别的驱动编程来实现模块的功能。 针对CC254x的编程是应用编程,关注的是HAL接口,可以认为是基于硬件功能的API接口,而且电路的外设的功能也相对固定,如LED、LCD、UART所使用的pin脚都是相对固定的,因此调用简单的HAL层接口即可实现功能;而驱动编程则是针对SOC片上资源来进行开发,需要根据SOC的datasheet明确的物理地址资源进行访问和控制,并向用户提供API接口。从两者的区别可以理解HAL硬件抽象层的含义。当然,透传理解SOC datasheet也有助于HAL接口编程。 >三、Timer 对于Timer定时器接口,一般是设置定时器、编写定时器时间到达时的回调函数。而定时器模块的初始化函数一般由系统初始化完成。 OSAL对于Timer的HAL层代码对用户并不透明,我们可以理解Timer的HAL层是设置Timer模块的硬件相关操作,并且实现了Timer中断时的服务处理过程。OSAL的Timer的封装接口实际上是在HAL层的基础进行再次封装。其主要提供的接口如下: uint8osal_start_timerEx( uint8 taskID, uint16 event_id, uint32 timeout_value ) taskID标识哪个目标任务来处理这个定时到达消息,即当定时完成时,定时器中断服务器函数会往这个目标任务的taskEvents[taskID]写入event_id这个消息;event_id可以由用户自定义;timeout_value是定时时间,1毫秒为单位。 可见这个定时接口并没有设置定时完成时的回调函数,而是在定时完成时向这个目标任务发送一个事件。而在目标任务的执行过程中要检测这个事件并执行相应的处理。 >四、UART        UARTHAL层代码对用户是透明的,对于用户编程来说,最重要的就是串口的初始化(波特率)、串口输入、串口输出。 **1.串口初始化** voidNPI_InitTransport( npiCBack_t npiCBack ) 串口的初始化并没有带taskId这个参数,可见其是一个全局的系统级的接口。串口的使用一般是使用中断串口输入,非中断直接串口输出。该函数里面设置波特率是115200. npiCBack是串口HAL提供给用户的一个回调函数,即在串口中断时会调用该回调函数。而串口中断有以下几种事件: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a2aefa5.jpg) 一般我们都会在该回调函数中实现串口接收,如实现串口透传模式。回调接口声明如下: typedefvoid (*npiCBack_t) ( uint8 port, uint8 event )        port是UART0或者UART1,而event即是串口中断事件。 **2.串口输入** uint16NPI_ReadTransport( uint8 *buf, uint16 len ) **3.串口输出** uint16NPI_WriteTransport( uint8 *buf, uint16 len ) 从这些接口来看其前缀是NPI,真实的意义是Network Processor Interface (NPI),表示所谓的网络传输层。其实只是更高一层的数据输入输出罢了。NPI的底层可以是UART、SPI或者USB等等。我们这里默认是使用UART。 >五、按键消息来源和处理 **1. 代码理解前的思考** 1)按键消息按理是跟应用相关的,因此其必然是跟某个taskId绑定。在这种简单的嵌入式系统中,一般是由一个称为UI的任务来统一处理按键的消息。 2)按照上一篇文章和上一节Timer的分析,OSAL的设计是将事件event_id发往目标task,即设置taskEvents[tasked]。我们可以想象在按键中断(或者按键轮询)时检测到按键会往目标task发一个按键事件。但是,我们再细想,发一个KEY事件够了吗?很明显taskEvents的元素才是16bit,每个bit表示一个事件,最多只能代表16种事件,就算这16事件都用来表示不同的按键,也显得不够。因为系统可能有更多的按键啊,如果这样设计扩展性就太差了。事实上,它只是发了一个KEY_CHANGE事件,而键值是以MSG消息的形式发到系统的消息队列,而该消息也会带上目标taskId的标识。 3)以上两点是OSAL的KEY处理机制。对于用户快速开发,则需要知晓如何增加一个按键,或者改变一个按键对应的GPIO;处理按键的过程在哪里实现? 带着以上问题,我们从头到尾跟踪一次KEY处理的过程。OSAL对KEY的处理机制有点绕,但封装得挺有意思的。 对Key处理机制真正的理解过程应该是倒序的,即从按键的处理一步一步往前推,在现场教学时,对着代码反跟踪能够更加体现本文的方法论。为了表述更加有条理性,这里就从头到尾正序阐述。 **2. 初始化**        1)main->HalDriverInit->HalKeyInit ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a2bdf87.jpg) 2)main->InitBoard( OB_READY ) OnboardKeyIntEnable= HAL_KEY_INTERRUPT_ENABLE; HalKeyConfig(OnboardKeyIntEnable, OnBoard_KeyCallback); ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a2d36e1.jpg) 相关的代码在hal_keys.c和hal_keys.h,若要增加按键或者修改按键设置即修改这里。 OnBoard_KeyCallback是按键中断的回调函数。我们在下一步再展开其实现过程,现在跟踪在哪里会调用这个回调。我们从中断的源头开始跟踪。 **3. 中断的执行过程** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a2e440b.jpg) **4.HAL层任务的处理过程** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a302f16.jpg) pHalKeyProcessFunction即是之前在HalKeyConfig接口中设置的OnBoard_KeyCallback,继续跟踪这个函数的实现: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a31aba4.jpg) 这个 registeredKeysTaskID是什么,就是处理按键消息的任务Id。在哪里被初始化呢? **5.按键处理任务的初始化** main-> osal_init_system-> osalInitTasks-> SimpleBLEPeripheral_Init -> RegisterForKeys( simpleBLEPeripheral_TaskID ) 即在这个函数里面将simpleBLEPeripheral_TaskID赋值给registeredKeysTaskID,即SimpleBLEPeripheral对应的任务来处理这个消息。 **6.按键的处理** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a3313be.jpg) 用户添加的按键处理即在simpleBLEPeripheral_HandleKeys函数中。 请一步步地印证第一点,代码理解前的思考。 节日快乐! 更多原创嵌入式Linux,IOT、蓝牙wifi开发技术分享请关注微信公众号:嵌入式企鹅圈 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a143a64.jpg)
';

如何快速理解一个全新的嵌入式操作系统

最后更新于:2022-04-01 06:58:04

--基于TI CC254X OSAL的分析 当工具链配置完成后,Source Insight向你展示一份源码工程,不借助百度和开发文档,能否在一两个小时内理解源码的组成框架和接口,进行快速开发? 在笔者过往撰写的博文中,一直在倡导两个嵌入式学习和开发理念:提高嵌入式系统架构和软件层次形成大局观;掌握从需求的角度去理解新系统和技术这个方法论。在软件大局观作为学习新系统的背景知识的基础上,从软件需求的角度入手就能快速理解和掌握一个全新的系统。本文以TI蓝牙BLE CC254x的源码库和工程为例进行分析研究。 >一、操作系统相关概念 **1. 操作系统** 最常见的通用操作系统是Windows和Linux。操作系统给应用层提供进程调度、进程间通信、内存管理、驱动管理、文件管理、中断管理、时间管理等相关接口。在嵌入式领域,除了通用的嵌入式Linux操作系统,更多的是定制型的操作系统。定制型操作系统一般都是闭源且高度裁剪移植的系统,根据应用的需求提供必要的功能和管理模块。资源丰富型系统的应用层和内核层会使用不同的CPU运行模式,只有内核层能够访问硬件资源,而资源紧缺型系统的应用层和内核都是运行同一模式,都能够访问硬件资源。 嵌入式系统中有单任务操作系统和多任务操作系统。单任务操作系统一般用于简单的电子控制和处理产品中,如玩具、工业控制、家电等等。而多任务操作系统则用于较为复杂且功能丰富的电子产品中,如手机、视频监控等等。 在一般的简单的电子产品中,操作系统只是一种层次概念,其管理的功能显得比较弱,有时甚至为了效果和内存而进一步削减它的存在,但是软件层次能够让软件工程显得更加有序和易于维护和管理。只要中断管理、GPIO和驱动、时间管理单独成模块,我们都可以认为它形成操作系统。 **2. 内核** 内核是多任务操作系统的核心,最基本的功能就是任务调度和任务间通信。既然是多任务并发运行,而CPU只有一个(假设是单核CPU),就必须做好任务的调度和任务间的同步和通信。Linux是一个操作系统(OS),其内核(kernel)除了任务调度、任务间通信,还有内存管理、网络接口等;UCOS是常见的多任务内核,多用于资源有限型嵌入式系统,它提供了优先级抢占的任务调度和信号量、邮箱、消息队列等任务间通信,尽管UCOS也提供了内存管理,但完全可以裁剪掉这个功能。 **3. 并发** 一个系统可能有多个独立的任务,但是否是多任务操作系统,是以这些任务是否并发为标准。所谓并发,是指各个独立的任务是否能够得到公平的运行机会。如果一个任务必须要等待另一个任务完成才能执行,那两者是串行运行;如果一个任务能够在另一个任务执行过程中抢占CPU,才算是并发执行。并发执行跟任务上下文密切相关,单任务操作系统只有一个用户上下文,而多任务操作系统的每个任务都有一个上下文,任务切换就是对上下文的切换。 **4. TI CC254x需求分析** TI CC254x是在8051核上集成蓝牙BLE4.0低功耗的单芯片,可以预想它是一个资源紧缺型的嵌入式系统;同时CC254x是为了完成蓝牙连接和简单的控制功能(即GAP profile和GATT profile),因此TI提供的库也重点围绕蓝牙连接和控制传输设计,而没有通用操作系统所支持的文件、驱动管理等功能;另外蓝牙协议是分层协议栈,各层都有独立的的业务和处理流程,它会是多任务应用吗? TI向用户提供了一个叫做OSAL(操作系统抽象层)的编程框架,除了蓝牙相关的底层协议不透明,OS相关的任务调度和通信、蓝牙高层协议都是用户透明的。诚如以上对单任务操作系统的分析,OASL也是一个较弱的操作系统,只包含了调度和通信的内核,和一个硬件抽象层。但不妨碍我们把它当成一个操作系统去理解。 **5. 如何快速开发** 理解工程的架构、任务调度、任务通信、用户消息的输入和输出之后,就能进入快速开发阶段了。基于以上分析,要在OASL上进行快速开发,我们需要重点关注OSAL的任务编调度、任务间通信、用户消息输入和处理。对于蓝牙协议栈相关的内容(GAP、GATT等应用profile),不是本文的重点,以后再另外撰文阐述。 >二、OSAL的任务调度 **1. 背景知识** 嵌入式系统中每个任务都是while(1)的大循环。在单任务中可能还会有不同的场景,例如每个功能菜单都可以认为是一个场景,每个场景都有自己的消息大循环,但本质上还是一个while(1)的循环。而在多任务操作系统中,每个任务都有自己的消息循环。任务间的协同运行依赖任务的主动释放控制权(主动休眠)和被动的挂起(如等待另一个任务的信号量)。每个任务都必须要在就绪状态才可能得到运行的机会。 **2. OAL应用需求** OSAL支持蓝牙协议栈,包括链路层、适配层、GAP连接管理、ATT属性管理、GAP profile应用、GATT profile应用,此外还要支持用户的按键消息输入处理等。各层均有独立的分工和职责。到底是以多任务来支持这种模型,还是单任务的多场景呢。拭目以待! **3. OSAL代码分析(以SimplePeripheral为例)** 1)从main开始,main->osal_init_system-> osalInitTasks,如下图: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a2325f9.jpg) tasksCnt是系统的任务个数,如下图: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a2442cb.jpg) 数组中每个成员都是一个任务处理过程。先给tasksEvents申请空间,tasksEvents是做什么的,先不管它。 osalInitTasks接着就是进行各个任务的初始化,这时还没有进入消息循环。我们注意到taskID在每个任务初始化后,taskID都会加1,而在每个任务初始化的开始都会记录传入的taskID并保存,作为任务的标记。 2)main-> osal_start_system,如下图: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a2563a6.jpg)  我们看到大循环了。继续看: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a266863.jpg)  可见,taskID除了任务标识,还有优先级的含义。tasksEvents数组的每个元素即对应每个任务的就绪状态,0为没有事件需要处理,非0代表有事件需要处理。 跟踪一个任务处理流程,我们发现里面并没有while(1)循环,都是等到某个任务执行完才返回,返回之后回到osal_start_system大循环。因此该系统本质上是一个单任务操作,只有一个上下文。但是OASL的编程模型看起来确实蛮想多任务系统的,或者其借鉴了很多多任务编程的思维,如在OASL看到了很多UCOS的影子。 为什么要将返回值设置到tasksEvents中,就是因为其本质是一个单任务循环,如果某个子任务时间执行过长,会影响更高优先级的任务的响应变慢,影响整体性能。因此如果一个任务执行比较长,宜进行分割,在返回值那里设置继续处理事件,然后返回大循环,看看有没有更高优先级的任务需要执行。 >三、OASL的任务间通信 **1. 背景知识** Linux的任务间通信包括消息队列、共享变量,有信号量来同步;UCOS也有消息队列、邮箱和条件变量、信号量等手段来进行通信和同步。OSAL是单任务操作系统,需要由用户层的各个任务处理过程自己约束保证同步。 消息一般包括按键消息、时间消息、绘图消息等等,信号量用于任务间的同步,并不属于消息传递。 **2\. OSAL的代码分析** tasksEvents的元素除了作为就绪状态,还有另外一个作用就是作为参数传入该应用处理过程。我们跟踪一个处理过程: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a27b8d0.jpg) 可以看到,event可能是用户自定义的事件,如这个任务要做的周期性的事情和启动连接的事件。另外,event还可能是系统消息事件(SYS_EVENT_MSG),它是什么?消息和事件在OSAL中是怎么理解的。 其实把事件作为消息的类型更容易理解,事件用一个16位的整型来表示,从代码来看,是每个比特表示一种事件,其最多只能表示16种事件。对于按键消息,由于其可能有多个不同的键值,因此不宜通过多个事件来表示,而是用一个按键事件来表示,然后按键的键值通过消息队列来传递。 通过跟踪消息发送osal_msg_send( uint8 destination_task, uint8 *msg_ptr )和消息接收osal_msg_receive( uint8 task_id )接口,可以发现,所有的任务共用一个链表型的消息队列,每个结点记录消息的事件类型/值和接收任务的taskID。 那么事件的发送接口呢?如下图 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a295b74.jpg) 即往tasksEvents的taskID下标成员写入对应的事件值。这样在之后的大循环中目标task就会得到执行的机会。消息发送osal_msg_send不仅将消息插入到全局消息队列链表,而且最后也会调用osal_set_event接口填入SYS_EVENT_MSG事件。 此外,还有一个定时发送事件的接口osal_start_timerEx,其在规定的时间到达后才会发送该事件,以让目标taskID得到执行事件的机会。 >四、OSAL消息处理 OSAL提供了一个HAL硬件抽象层,咱们主要分析按键输入和串口输出就好了。 利用TI CC2540进行蓝牙方案开发还是几个前,当时一个小时就理解了OSAL,但现在把当时的理解思路还原整理出来花了差不多四个小时,主要是因为在撰写过程中不断地考虑如何让读者更好地理解本文的学习思路,即总结软件架构方面的知识,和如何从需求的角度去理解新的系统。呜呜,还是把OSAL的消息处理流程留到下一篇好了。 接下来将会陆续推出物联网-微信蓝牙和wifi接入相关的技术分享。敬请关注! 更多原创分享请关注微信公众号:嵌入式企鹅圈! ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a0d9e17.jpg)
';

网络架构、云平台和微信公众平台开发接入

最后更新于:2022-04-01 06:58:02

云与后端相关的技术似乎并不属于嵌入式和物联智能硬件开发工程师的范畴,但是嵌入式开发工程师有必要认识成熟的网络架构和相关的云技术,以拓展自己在系统架构方面的视野。大数据分析是物联网背后的核心价值,物联智能硬件是物联大系统的终端,开发工程师不仅要深入精通物联技术,也应该去理解大系统,甚至整个生态领域的相关技术。 作为嵌入式开发工程师,也许并不需要熟悉云和后端的技术开发,但至少要对其中用到的技术和接口有一定的认识。 >一、网络架构 常见的网络架构分为C/S和B/S两种模式。 1\. C/S是客户端/服务器模式,典型应用如QQ客户端、百度云管家等;B/S则是浏览器/服务器模式,典型的应用就是门户网站、银行业务系统等。两种模式的优点和缺点都显而易见。 2\. C/S交互性强、网络通信量低、响应速度快,很多处理都集中在本地客户端完成,是胖客户端/瘦服务器。但是其是针对性开发,不利于变更和扩展。C/S通信编程基于TCP/IP层的socket编程,或者基于对socket的封装类。 3\. B/S方式分布性强、升级维护方便、开发简单、总体成本低,本地只需要安装一个通用的浏览器即可,是瘦客户端/胖服务器。但其有数据安全性问题、对服务器要求过高、数据传输速度慢。B/S的通信是基于HTTP协议。随着网页脚本技术的提高,B/S也逐渐增强本地浏览器端的处理能力,以减轻服务器的负荷。 4.以上分析都是基于对PC端网络架构的思考,但是在移动互联网上却有截然不同的体验。以门户新闻网站而言,在PC领域是以B/S方式来呈现的,但是如果将其直接移植到手机和平板端,会因为屏幕尺寸的差异使得用户体验变差,尽管在服务器端可以通过获取终端的个性化参数来进行适配,但总体体验是远不上APP客户端来展现的,所以我们在手机看到的是新浪新闻、网易新闻等等客户端。在移动互联网领域,应该考虑的是更多的垂直服务,而不是大而全的产品。 >二、服务器架构 接下来以B/S架构为例来分析服务器端的架构。示意图如下: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a1c770c.jpg)  1.用户浏览器来访问业务系统,如银行业务,浏览器是直接跟WEB页面服务器交互的。WEB服务器一般会部署apache(或者tomcat),而业务系统的网页(如html,php)则通过apache服务转为HTTP协议通信给用户。 2.业务系统不同的业务页面由业务引擎来进行控制和处理,业务引擎还会访问数据库,另外还需要将处理结果的页面视图通过WEB向用户展示。 3.如果数据访问量不大,我们一般可以认为WEB是一台服务器,业务引擎是一台服务器,数据库和服务是一台服务器。如果数据量大,那WEB前面可能还有负载均衡服务器,业务引擎和数据库可能是服务器集群。如果是超大型数据,如大数据,那传统的oracle根本就不管用,要用到分布式文件系统,如Hadoop里面的HDFS。当然,如果数据量很小,一台服务器装下三者也可以。 >三、后端软件架构 以上分析是基于部署视图对整个系统的理解。在一般的软件业务系统中,web服务使用apache(开源),数据库服务用Mysql(开源)等,都是成熟的软件产品,或者我们可以认为它们是一种软件工具。在实现业务系统中,我们能做的是去高效利用apache和mysql,而业务实现的核心是业务引擎的实现。 业务引擎是应用系统的核心,应用系统上成熟的模型是MVC模型。M是模型,是对数据库应用接口的封装,业务引擎即通过M模型的接口来访问数据库的业务数据;V是视图,是应用根据数据处理的结果而整合的页面,最终会通过WEB推向用户的浏览器;而C则是控制,即业务引擎的核心,其根据用户的交互来进行有针对的数据处理。 用户的交互最终都会通过HTTP协议来传送,而HTTP有两种方式,类似编程中的函数的参数传递,一种是GET的方式,即在网页的访问地址后面加上参数来传递;另一种是POST方式,不出现在访问地址后面,而是出现在消息体中。MVC的控制器会根据参数的不同来区分不同的子业务请求,并将它们交给对应的数据处理引擎来处理。 业务引擎的开发一般都是用解释性语言来开发,如php,JSP,asp等等。中小型系统常用apache+php+Mysql这种组合,另外就是tomcat+jsp+mysql. >四、云平台 云平台并不是什么神秘的技术,对于应用者而言,云技术能给我们带来极大的便利和成本优势。我们来想象一下,一个公司如果只在广州办公,它开发的产品系统是服务全国,如果它只是在自己的公司架设服务器,但全国各地用户访问的IP包都要在网络上跋山涉水来到广州,北方的用户的体验肯定很差。假设淘宝的服务器都在杭州,那11.11的抢购,我们在广州怎么抢得过杭州的。因为租赁云平台来假设分布式的服务平台是大型系统的不二选择,有人可能会想,这些公司可以在全国各地租机房买服务器放着啊,成本呢?而且用户的访问也有峰值和周期性,360的抢票虽然牛掰,但如果不是过年,也没多少人用吧。平时买那么多服务器就为了过年抢一抢多浪费,肯定比不上过年有针对性地租用云资源来得便宜。 简单地说,对于一般用户来说,云平台就是提供在看不见的地方提供虚拟服务器主机(CPU、内存、硬盘)和数据库、WEB服务(apache)等资源。对于云平台的提供商,那才是虚拟集群技术人才的聚居地,咱们不去讨论了。 目前,国内有阿里云、新浪云和百度云等知名云平台。新浪云对于体验用户是免费的(php免费,java是收费的)。对于初学者,可以考虑申请新浪云来进行技术开发。 各种云的申请和创建云应用的过程都比较简单。以新浪云为例简单说明一下,详细的例程可以百度得到。 1.注册新浪微博账号,两者是绑定的。 2.以新浪账号登陆新浪云计算中心。 3.在新浪SAE上创建新应用,如图: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a1e7b63.jpg)  这个时候可以通过二级域名来访问了,即意味着你拥有了云平台的主机资源和apache服务和php脚本解释引擎。 4.编辑或者上传代码(php语言开发) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a211eaa.jpg) >五、微信公众平台开发接入 微信公众平台的后台管理有两种模式,一种是常规的模式,即由微信官方提供的后台菜单功能来进行管理,如用户管理、群发、交互回复等等;另一种是开发者模式,即由公众号的运营商自行开发后端,来对关注该公众号的用户提供服务,如自动回复、地理信息服务、移动支付等等。微信硬件服务也属于开发者模式,由微信硬件的厂商提供后端进行支持,详细的架构可以参考《物联网架构场景技术分析》一文。开发者模式给微信公众号注入了强大的生命力,有第三方创造力的加入,使得微信公众服务大放异彩,也可以预见基于微信的物联网会推到物联网大幅前进。 第三方后端服务假设在云前述的云平台基础上,只要按照微信提供的接口即可以接入微信公众平台。 1.先使用token来验证第三方主机方的存在。 2.第三方服务按照微信的接口来提供服务。目录微信公众号提供消息服务、对话服务、移动支付、硬件服务、地理信息、图像音频等方面的接口。详细请参考微信官方资料。   本文从大的宏观网络架构一步一步深入到所谓微观的微信后台接入,希望对你有所启发。 1、讲述C/S和B/S网络架构 2、从部署视图理解(S)服务器架构,包含web、业务引擎、数据库 3、从开发视图理解业务引擎的软件架构 4、云平台提供服务器资源(web服务、数据库服务、主机资源),申请免费云 5、云平台实现微信公众平台开发接入 作为嵌入式开发工程师,不用对未知领域有所畏惧,只要付出足够的努力,一切都能在掌握之中! 敬请关注微信公众号:嵌入式企鹅圈,获取更多嵌入式和物联网开发相关技术原创分享。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a0d9e17.jpg)
';

Protocol buffer序列化及其在微信蓝牙协议中的应用

最后更新于:2022-04-01 06:57:59

 Protocol buffer是Google出品的一种轻便高效的结构化数据存储格式,可对结构化数据进行序列化,并具有语言无关、平台无关等特点,在通信协议和数据存储等领域已经得到广泛的应用。目前其已经提供 C/C++、Java、Python 等语言的 API。 >一、Protocol buffer和XML 在数据通信传输时,一般需要将结构化的数据序列化成流进行传送,接收方再反序列化为原始格式数据进行处理。在Web通信领域,XML应用算是最通用的了。在时间性能上,虽然XML的序列化开销还可以,但是反序列化的效率是比较差,而Protocol buffer的反序列化效率是比较高的;在空间性能上,Protobuffer采用了可变长的数据编码格式,比XML的字符格式要高效得多。Google集群要处理PB级数据,Protocolbuffer能够在时间和空间性能上有所改进,在整体效益而言就是相当可观的。 正是基于以上原因,微信和蓝牙外设的通信协议采用了Protocol buffer对消息包体进行打包。本文的目标是讲述Protobuffer在蓝牙微信协议中的应用,有助于理解微信蓝牙协议,对微信发给蓝牙外设的消息数据流进行反序列化,得到原始的结构化格式数据。因此语法也是围绕微信蓝牙协议包展开。更加详细的语法请百度相关内容或者找笔者探讨。 >二、微信蓝牙外设协议通用格式 微信蓝牙使用流进行传输,在流上传输的是一个接着一个的业务逻辑的数据包。把设备发往厂商服务器或者微信服务器的请求包称为Req,回复包称为Resp,一个请求对应一个回包。把厂商服务器或者微信服务器主动发往设备的请求包称为PushReq。 包结构由定长包头和变长包体组成,其中包体即由Protocol buffer进行打包。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a158246.jpg) 其中,定长包头为8个字节,bMagicNumber为0xFE;bVer为版本01;nLength为包长,包括包头和包体的长度;nCmdId为命令编码,如登陆授权,初始化,发送数据,push推送等等;nSeq为序列号,PushReq包的序列号固定为0,其他请求和回复包的序列号务必保持一致,每次请求后序列号加1. 以厂商服务器主动发数据给设备的PushReq包为例来说明变长包体,其对应定长包头的nCmdId为ECI_push_recvData = 30001。包体包括以下三个部分: 1) Push包标识 2) 自定义数据,指的是业务层自己定义的数据格式形成的数据。 3)  数据类型,如厂商自定义的数据,还是微信客户端Html5的数据等 >三、Protobuffer的语法表述 Protobuffer对push_recvData包的表述如下: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a1700db.jpg) Message类似C语言的struct数据结构,是Protobuffer消息定义的关键字。RecvDataPush是消息的名称。 Required前缀表示该字段必须在序列化之前赋值,optional前缀表示可以不赋值。 BasePush BasePush是message的第一个字段field,前者代表数据类型,后者是名称,其中BashPush在协议中是这样定义的: Message BashPush{} 其意味着里面没有数据项,BashPush在打包过程中只会出现数据类型,其实也是代表着一种push标识。 Bytes Data是第二个字段field,为字符串,名称是Data。 EmDeviceDataType type是第三个字段field,为设备数据类型,其中EmDeviceDataType是一个enum类型,如下: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a18437b.jpg) 1,2,3代表字段在序列化后布局中的位置index,第一个位置是BashPush,接着是Data、type。 >四、Protobuffer打包 Protobuffer打包有以下要素和规则: 1.使用Varints算法表示数字。Varints是一种紧凑表示数字的方法。Varints中每一个字节的最高位是有特殊含义的,如果是1,则表示后续的字节也是该数字的一部分;如果是0,则结束。所以如果表示小于128的数值可以用一个字节,如果大于等于128的数字则要用更多的字节进行表示。 2\. Protobuffer有以下数据类型 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a1944ef.jpg) Type表示对应数据类型序号,其中Varint对应的数据类型包括int32,int64,enum等等,type序号为0,其都使用Varints进行表示。String,bytes,message类型对应的type序号为2. 3\. Protobuffer打包即是将message通过一系列的key-value对来表示。而key就是每个message中各字段的index(并做一定运算),value根据类型的不同会有不同的表现形式。 其中key = field 而value,在数据类型为Varint时,直接为字段的赋值,按照Varints算法进行编码;在其他类型时就是“长度+原始内容编码”。 >五、PushReq包分析 我们通过微信提供的AirSyncDebugger2.1.0.apk来分析Protobuffer对数据包的序列化。该APP用于微信和蓝牙外设的通信调试,其封装了微信蓝牙的协议,一般先用该APP调通蓝牙协议,再和后台服务器联调。假设我们自定义的消息内容为fe cf 00 01 00 0c 20 01 00 00 00 00,即对应第二个字段bytesData,该消息内容是上一篇文章中服务器控制亮灯所发的消息,后台服务器和蓝牙外设的消息协议是自定义的。AirSyncDebugger对PushReq包的序列化如下: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a1a46da.jpg) 序列化过程分析如下: 固定包头(不受Protobuffer控制): Magic : fe Version: 01 Length : 00 1A,即包体和包体的总长度为26字节。 Cmdid : 75 31,十进制就是30001,即ECI_push_recvData包 Seq : 00 00 push包的序列号都是00 00 变长包体(Protobuffer控制打包,十六进表示): 0A: BasePush的field是1, 值类型message的序号type为2,所以是0x1 00 : 即值长度为0,BasePush值为空,其实就是一种标识。 12:data的field是2,值类型bytes的序号为2,所以是0x2 0C:  data的长度是12 Fe cf 00 01 00 0c20 03 00 00 00 00 : data的内容,即我们自定义的消息。 18: Type的field是3,值类型enum的序号为0,所以是0x3 00:Type的值,因为enum属于Varint的一种,所以不需要长度,直接用值表示,0代表厂商自定义数据。 >六、基于微信硬件公众平台的智能控制方案开发专栏介绍        接下来嵌入式企鹅圈会将陆续公开基于微信硬件公众平台的智能控制开发技术细节,大致内容包括: 1\. 物联网架构和场景分析(已发) 2\. 基于微信硬件公众平台的智能控制开发流程(已发) 3\. 云服务器搭建和公众号配置 4\. 公众号菜单设置 5\. 微信消息传递过程和微信设备接入接口协议 6\. 微信硬件平台后台服务开发 7\. 微信蓝牙协议和授权、绑定过程 8.Protocol buffer序列化及其在微信蓝牙协议中的应用(已发) 9\. 蓝牙外设控制开发 …   谢谢支持嵌入式企鹅圈: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a0d9e17.jpg)
';

基于微信硬件公众平台的智能控制开发流程

最后更新于:2022-04-01 06:57:57

通过持续的研发投入,嵌入式企鹅圈主人已经完全掌握微信硬件公众平台的蓝牙设备接入和后台服务接入技术,能够快速给用户提供基于微信硬件公众平台的智能控制完整解决方案,包括云平台构建、云服务开发、微信公众平台接入配置、蓝牙外设主板硬件设计和软件开发,甚至生产也可以提供,您只管市场销售和运维即可。项目洽谈请QQ联系:183550631,希望能够完整学习整套技术者持续关注嵌入式企鹅圈即可。接下来嵌入式企鹅圈会陆续分享各个部分的关键技术细节。 > 一、微信硬件公众平台整体架构 上一篇《物联网架构场景技术分析》已经探讨和分析了物联网架构的演进,基于微信硬件公众平台的智能控制方案即属于文中的第三种架构--基于统一后台服务的物联架构。其中的架构如下: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a0f0452.jpg) 各部分的角色和分工如下: 1.微信硬件公众号平台服务器,是物联网的基础和核心部分,其负责外设设备ID的认证,类似公安部给每个公民一个身份证一样,保证每个外设都有一个合法并且唯一的ID。目前微信平台的设备ID由两部分组成,一部分是厂商运维的公众号(即手机微信关注的公众号)的原始ID,称为设备类型,即代表生产商;另一部分就是设备的ID,设备由厂商负责生产,要保证厂商生产的所有设备的ID是唯一的。 另外,其负责将微信发过来的消息转发给厂商服务器,或者转发厂商的服务器给微信,这些操作的前提都是要通过验证。 验证的内容包括:设备是否已经通过授权(设备接入前需要授权)、用户是否已经绑定了该设备。 2.手机微信,其实指的是用户微信关注的公众号页面(例如嵌入式企鹅圈。需要注意的是,只有服务号或者通过验证的订阅号才能开通设备功能,而嵌入式企鹅圈只是个人订阅号,暂时无法进行验证。微信给开发者提供一种微信测试账号,可以支持硬件设备功能,但只有一年期限)。其调用微信封装的蓝牙接口和蓝牙外设进行通信。蓝牙接口实现的协议是微信定义的“蓝牙外设协议Airsync”。 3.厂商服务器,对微信硬件公众平台转发的消息进行验证(在厂商数据库中检测该用户是否已经绑定了自家的设备),然后按照和蓝牙外设拟定的自定义消息协议生成自定义消息。发给微信硬件公众平台,再通过微信发给蓝牙外设。 厂商服务器是和微信硬件公众平台直接交互的,厂商服务器需要遵循微信定义的“设备接入接口协议”。 4.蓝牙外设,由厂商负责生产和销售,购买该外设的终端用户只需要关注该设备的二维码即可用手机的公众号菜单来进行控制。 > 二、微信智能控制使用场景 1.购买蓝牙外设产品,厂商会在包装外面打上该设备的二维码。 2.用户手机扫描该二维码关注厂商的公众号。 3.进入公众号,对菜单进行控制,即可以控制蓝牙外设。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a10d200.jpg) 整个过程非常简单,如果有块蓝牙外设板子就可以很好体验一把了。如果希望学习微信硬件开发技术者或者购买蓝牙体验板的童鞋们可以跟我联系。 在没有蓝牙外设体验板前还是老老实实地扫描关注“嵌入式企鹅圈”的二维码跟着博主深入地学习整套技术吧,哈哈。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a143a64.jpg) > 三、基于微信硬件公众平台的智能控制开发流程 1.搭建云服务器,如百度云、新浪云。微信公众号的后台服务一般选择PHP+MySQL+Apache架构(如嵌入式企鹅圈),而微信提供的微信硬件公众平台后台服务demo是JSP,所以后台架构一般选择tomcat+java+MySQL(如“**的接口测试号”)。 2.创建微信公众号,并进行认证,开通硬件设备功能。公众号进入开发者模式,配置厂商服务器的域名服务地址和token。 3.微信公众号创建菜单,如点灯和关灯命令。微信提供接口进行创建。 4.设备分配ID,并到微信硬件公众平台进行授权,需要提供厂商ID、设备ID和蓝牙的mac地址。 5.厂商服务程序开发,需要遵循微信拟定的“设备接入接口协议”,并制定自定义消息协议,用于和蓝牙外设通信。 6.蓝牙外设程序开发,需要遵循微信拟定的“蓝牙外设协议Airsync”,并根据自定义消息协议对外围设备进行控制 以上过程可以通过“微信公众平台接口调试工具” http://mp.weixin.qq.com/debug进行调试(消息接口),蓝牙外设调试可以通过Airsysdebug.apk进行调试. 以上协议资料可以发消息向嵌入式企鹅圈索取。 >四、基于微信硬件公众平台的智能控制方案开发专栏介绍 接下来嵌入式企鹅圈会将陆续公开基于微信硬件公众平台的智能控制开发技术细节,大致内容包括: 1.物联网架构和场景分析(已发) 2.基于微信硬件公众平台的智能控制开发流程(已发) 3.云服务器搭建和公众号配置 4.公众号菜单设置 5.微信消息传递过程和微信设备接入接口协议 6.微信硬件平台后台服务开发 7.微信蓝牙协议和授权、绑定过程 8.微信蓝牙Protobuf协议分析、Airsyncdebug.apk使用 9.蓝牙外设控制开发 …
';

物联网架构演进和微信智能设备平台开发

最后更新于:2022-04-01 06:57:55

微信公众号(嵌入式企鹅圈)将新开辟专栏撰写物联网完整解决方案的相关技术,包括物联网架构、云服务、微信接口开发、智能设备开发等。鉴于本人研发的进展和需要时间进行原创总结,物联网专栏更新会比较慢,近期嵌入式企鹅圈仍以嵌入式Linux技术开发经验分享为主。 本文从场景和技术的角度去理解物联网技术和方案的演进,纯粹是个人观点,可能与主流定义稍有偏差。 > 一、物联网与物联设备 本人对物联网的理解是物联设备组成的网络,因此物联网需要两个要素,一是设备能够互联,另一个是能够组网。物联网往往又跟智能硬件概念相结合,当今物联网产品形态往往又带有无线连接的特点(有线最主要的弊端就是布线麻烦)。因此能够支持互联、组网、无线三个特点的物联设备技术就是常见的蓝牙和wifi了。蓝牙是近距离通信,穿墙能力差;而wifi距离远,可穿墙,但是功耗比较高。ZigBee其实通信距离比蓝牙远,功耗也比wifi低,看起来是比较理想的物联技术,但是ZigBee的组网能力比较差,带宽低,传输慢。ZigBee更多用在工业控制领域。 手机是现代社会每个人不可或缺的产品,蓝牙和wifi是手机的必备模块,所以手机是最大的物联智能设备。另外,由于人是物联网的直接使用者,因此几乎所有的物联解决方案都是围绕手机用户展开。 > 二、物联场景演进 **1.手机直接控制物联设备架构** 下图是wifi物联架构示意图: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a097581.jpg) 手机连接并控制物联设备是物联技术的基础,第一种方式是手机和硬件控制设备都以client的方式连接路由器,这样手机和硬件控制设备都能获得一个动态的IP,这样手机可以通过socket通信方式来控制硬件控制设备。第二种方式是硬件控制设备带有wifi AP热点功能,手机以wifi client连接上AP,AP的IP是固定的,因此手机也能够对硬件控制设备进行控制。 这种物联方式一般只是演示的模型,实际应用很少。因为它的缺点显而易见,我们都知道socket通信需要知道通信对方的IP,因此手机上的APP控制硬件设备时需要填入设备的IP。第一种方式的IP是动态的,需要通过路由器的web控制页面(一般电脑连接后浏览器输入192.168.1.1)获得,这在商用应用中不可能存在。第二种方式也需要手机APP输入固定的IP,控制不同的设备就得输入不同的IP,用户体验不好。而且这种物联跟遥控没有本质的区别,不利于获取用户的信息。而获取用户的信息并提供优质服务才是物联网的核心要素。 **2.基于独立后台服务的物联架构** 下图是wifi物联架构示意图: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a0aa675.jpg) 这种物联架构中的独立服务器是以域名的方式存在,这样可以直接解决动态IP不固定的问题。另外,这种物联架构中手机和硬件控制都需要以用户名注册和登陆的方式来访问独立服务器,并由服务器通过心跳技术来确认手机和硬件控制设备的在线状态。手机和硬件控制在服务器看来都是普通的物联设备,它们在服务器看来都具有唯一的用户ID,物联设备登陆服务器时服务器会获取到用户ID所在设备的IP地址。而手机APP控制硬件设备是以用户ID为依据进行控制,其先将用户ID送往服务器即可获取到对应的IP地址。后续控制可以通过服务器,也可以绕过服务器直接进行。 类似web互联架构在互联网应用广泛存在,如QQ。每台手机都以QQ账号和密码进行登录,登录后,QQ后台服务器会获知每个用户所在手机的IP地址。两个QQ用户通信时会先通过账号来获取对方的IP,并进行下一步通信。这些访问细节都已经封装在QQ客户端程序中,QQ使用者并不需要理会。用户间的通信可能会经过QQ服务器,也可能绕过服务器进行。如文字信息一般会送往QQ服务器进行信息过滤再送到对方,而QQ视频应该是双方直接通过IP进行通信 这种架构在物联领域曾经是主流的架构,但是其固有的缺点也约束了它的发展壮大。这种架构中,独立服务器一般是由硬件控制设备的销售厂商开发维护的,另外其还需要向购买硬件设备的用户提供手机APP,以让用户能够进行远端的硬件控制。如小孩监护摄像头,厂商需要开发手机监护APP给用户安装使用。可以想到,用户每购买一种物联设备,都需要安装一个不同的APP。这直接影响了用户体验。用户一般是不情愿安装很多的手机APP的,不仅安全无法保障,手机布满控制APP时,要找到哪款设备对应的APP还要花时间。另外,独立服务器的厂商受限于自己的技术储备和运维能力,难以兼容支持第三方厂商的物联设备。 **3.基于统一后台服务的物联架构** 由第2点,我们自然可以想到,如果有一家实力超雄的厂商能够提供统一的后台服务,并被广大手机用户使用者认可愿意使用,而物联设备厂商按照统一后台服务拟定的协议进行设备生产并接入到统一的后台服务,那大一统的物联网大平台将成为可能。 微信公众号和微信硬件平台得益于腾讯QQ的超大用户量,很自然就承载了这种平台的实现。完全可以预见,微信将是未来物联网的重要支撑平台之一,而小米在手机、智能家居和相关行业的布局也是物联网重要支撑平台的竞争者。微信拟定统一开发的协议,让社会上不同的第三方硬件设备公司接入并获得唯一的用户ID,而小米不仅是统一后台的开发维护者,也是小米不同硬件设备的生产者,两者走的路并不一致。但两者的共同点是后台服务是统一的,两者的隶属公司都是超大体量型企业。 在移动互联网领域,用户基础是非常核心的要素,涉及平台相关的服务,没有超大型体量的企业很难快速构建,顶多只能在垂直领域有所作为。事实上,在微信智能硬件平台出现之前,也有一些企业构建了统一的后台服务,让第三方设备厂商接入。但受限于用户的支持,这些平台都未能为人熟知(也许是我涉猎这方面知识较少,之前有了解过一个平台,后来忘记了)。 这种架构的示意图如下,以微信和蓝牙设备控制为例: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a0c01e7.jpg) 微信公众平台的最核心作用就是给各种不同的外设提供接入并分配唯一的设备ID。微信智能硬件平台的设备ID分配策略包括外设厂商编码和设备编码两个部分。设备编码在统一厂商里面是唯一的。 手机需要关注外设厂商运维的微信公众号,才能通过该公众号的页面发出设备控制指令消息。控制消息会通过微信公众号服务器发往外设厂商独立运维的后台服务器,并由后台服务器作出处理后向外设发出控制消息,该消息会通过微信公众号服务器到手机的微信客户端,而微信控制端调用蓝牙JSAPI来控制蓝牙外设。手机微信要控制外设需要先开启蓝牙并连接上蓝牙外设。连接协议由微信硬件平台制定,称为airsys协议。 微信公众平台是开放平台,支持第三方服务接入,同时提供微信支付、客户接口、用户管理等九大接口供第三方服务调用。微信公众号支持开发者模式,开启后即可以接入第三方的服务。所谓微信开发即是在调用微信提供的接口的基础上完成业务逻辑开发,支持的语言是php,asp等等。如何构建第三方服务器和如何进行微信接口开发另文再述。蓝牙和wifi由于功耗的差异,其互联微信的架构也有差异,在日后的技术实现分享中会详细进行比较。 >三、native APP & light APP 在第2种架构,手机要控制外设需要安装外设厂商开发的APP,是原生APP(native APP);而在第3种架构,手机控制外设只需要关注外设厂商运维的微信公众号,微信是手机的原生APP,而每个外设厂商通过微信公众号提供的服务称为轻应用(light APP)。微信是智能手机的首选APP,用户量超大,因此基于微信统一后台服务的物联平台是未来物联网的重要支撑。 欢迎关注微信公众号:嵌入式企鹅圈,获得更多原创嵌入式linux和物联网解决方案的技术分享。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-12_5694d4a0d9e17.jpg)
';

前言

最后更新于:2022-04-01 06:57:53

> 原文出处:[移动开发专栏文章](http://blog.csdn.net/column/details/iot-wechat.html) > 作者:[吴跃前](http://blog.csdn.net/yueqian_scut) **本系列文章经作者授权在看云整理发布,未经作者允许,请勿转载!** #微信硬件平台解决方案 > 阐述物联网的架构、微信公众平台和微信硬件平台的架构、第三方接入协议、蓝牙外设airsync协议、wifi外设airkiss协议、蓝牙开发、wifi开发、云平台搭建、后端开发等相关领域内容。博主精通微信硬件平台研发,能够提供微信硬件平台完整解决方案。
';