一、简述
【资料图】
麒麟座开发板代码例程由OneNET-基础例程、OneNET-进阶例程、OneNET-RTOS例程组成,由浅入深地演示如何接入OneNET,从最基本的上传数据点,命令接收处理,到网络维持,平台连接维持,到最后的网络错误处理,一步一步演示如何处理这些事情。
下面先以OneNET-基础例程为例,讲解如何接入OneNET。
二、OneNET-基础例程模块分析
1. 代码框架说明
初始化开发板外围硬件;如LED、蜂鸣器、按键等。
初始化网络模组;开发板板载GSM模组-M6312,可插拔的WIFI-ESP8266-01模组。
登录OneNET。
执行相关上下行数据处理。
2. 代码功能简述
演示如何接入OneNET,如何处理OneNET推送的数据。
不具备网络维持能力,掉网后无法处理。
3. 初始化开发板外围硬件-Hardware_Init()函数
根据不同功能所需要用到的外围硬件不同,可根据自己使用的例程查看相应的硬件驱动代码,这里以为例说明
麒麟座使用的STM32F103RET6单片机,mini板使用STM32F103C8T6单片机,都是F1系列,编程方式完全一致。
先配置单片机的中断分组,采用2:2配置;
然后初始化systick用来做阻塞延时;
然后初始化串口1和串口2,串口1用来调试打印,串口2和网络模组通信;
然后就是初始化LED,蜂鸣器,按键,主要就是GPIO的配置;
最后打印一下,提示硬件初始化完成。
4. 初始化网络模组-ESP8266_Init()函数
WIFI模组的初始化比较简单:
先初始化相关控制的GPIO。
然后先发送AT,测试通信是否OK。
然后就是设置WIFI工作模式、登录路由、连接IP。
如果是GSM模组,前两步相同,初始化控制GPIO、发送AT测试通信。然后是注册、激活网络、连接IP。
5.登录OneNET -OneNet_DevLink()函数
主要流程就是获取登录数据,然后发送出去,等待返回。
获取登录数据:
EDP_PacketConnect1(DEVID, APIKEY,256, &edpPacket)
根据devid和apikey通过sdk生成登录数据,保存在edpPacket里边。
发送:
ESP8266_SendData(edpPacket._data,edpPacket._len);
指明要发送的数据和长度即可,调用此函数就会发送到OneNET接入机。
等待结果
ESP8266_GetIPD(250):从硬件层判断时间是否收到
EDP_UnPacketRecv(dataPtr) ==CONNRESP:
EDP_UnPacketConnectRsp(dataPtr):
从软件层解析是否接入成功。
6. 执行相关上下行数据处理
上行数据
执行OneNet_SendData()函数,会调用相关上传功能。
166行,是封装一个json,把要上传的内容写在里边
170行,根据devid、json格式和json封装协议包
175行,将协议包上传。
简单看看166行的内容
其中led_status.xxx,就是我们要上传的数据,按照json格式写好即可,如果新增数据点,复制高亮三行的任意一行加以扩展,然后把箭头的buf缓存开大一点即可。
下行数据
先判断驱动层是否收到数据,有则调用OneNet_Re**taPtr)函数解析相关功能。
判断是否是下发命令,是则回复这个命令,然后做相关命令的处理
三、OneNET-RTOS例程模块分析
1. 代码框架说明
初始化开发板外围硬件;如LED、蜂鸣器、按键等。
初始化网络模组;开发板板载GSM模组-M6312,可插拔的WIFI-ESP8266-01模组。
登录OneNET。
执行相关上下行数据处理。
网络维持,网络监测、错误处理。
2.代码功能简述
完整的开发板功能体验,所有传感器数据均上传,并包含一些监测类变量;完备的网络维持、监测、错误处理机制。
后文以与OneNET通讯、网络监测、错误处理为重点进行分析。
3.初始化开发板外围硬件-Hardware_Init()函数--main.c
基本流程和基础例程类似,初始化板载硬件,单片机片内外设等。
这里多了一个功能,将登陆的devid和apikey保存在eeprom里边,可以通过串口1按照资料中的格式进行更改而无需重新下载代码。
4.初始化网络模组- NET_DEVICE_Init ()函数--net_task.c
这个函数不连接具体的ip,仅仅只是让网络模组具备网络接入能力即可。
5. 登录OneNET- -net_task.c
OneNET_GetLinkIP:获取该协议当前资源最优的接入ip和port。
OneNET_ConnectIP:连接ip和port。
OneNET_DevLink:根据devid和apikey 或者 proid和auth_info登录OneNET设备。
6.执行相关上下行数据处理--net_task.c
上行数据
在net_task.c-- NET_**_Task任务里,红框处,是定时上传的内容,这个任务以50ms周期执行一次,当累计300次-约15s时,可自行更改,触发一次上传数据的标志,箭头所指处。
然后在net_task.c--DATA_P_Task任务里判断到标志置位,执行OneNET_SendData(…)函数根据当前的data_stream值去打包一个待上传的数据包,但此时并不上传,而是放入一个单向链表里,原因稍后分析,如果上传成功,则返回值会改变onenet_info.send_data的值,如果错误,则会间隔一段时间后继续回来打包数据。
最终将数据发送出去的的是net_task.c--DATA_S_Task任务判断表头是否为空,且网络连接正常,然后获取表里数据和对应长度,吧数据发往OneNET。
简单说一下,为什么上传一包数据,分了三个步骤(触发、打包、发送),因为这样可以在其他地方方便地上传数据,只需要改变一个变量值即可,而不用调用复杂的打包、发送函数,对函数堆栈要求降低很多;然后发送作为一个单独的任务是为了网络模组稳定性,wifi和gsm发送数据的时间间隔不同,wifi可以快一点,当短时间内有很多包大小不同的数据包待上传时,发送必须要稳定,所以OneNET_SendData(…)只是打包放入链表,发送函数以一个稳定的时间间隔来一包包的发出去。
下行数据
在net_task.c-- RECV_Task任务里边,只有一个函数OneNET_CmdHandle
先是调用NET_DEVICE_Read()函数判断驱动层是否收到数据。
然后调用NET_DEVICE_GetIPD(dataPtr)判断是否具有IPD头,这里说明一下,在绝大多数网络模组里,在指令模式下,如果收到一帧网络数据,则会以IPD标识(不同网络模组这个头可能不一样),如果带有IPD头,则说明收到OneNET推来的数据,进入OneNET_RevPro(ipdPtr)函数进行处理。
处理函数里边先通过EDP_UnPacketRecv(cmd)判断推送数据的类型,以EDP为例,有连接响应、命令下发、数据转发、心跳回复等,然后各自处理即可。
最后具体说说命令下发的处理机制。
先调用EDP_UnPacketCmd(…)函数解析出uuid、uudi长度、命令、命令长度。
然后是调用EDP_PacketCmdResp(…)函数打包命令回复的内容。
然后是调用CALLBACK_Execute(...)函数处理命令,在cmd_callback.c里边可以找到处理的过程
调用CALLBACK_Find_CallBack(…)找到红框处XXX的内容,这是是命令体,后边YYY是命令值,后边会用到
然后根据命令体对应的回调函数,执行响应的动作,比如redled,
调用CALLBACK_Find_Value(…)函数找到命令参数YYY
调用CALLBACK_Str2Dec(…)函数转为数值形式,方便执行开关处理。
大家在添加自己的命令和处理内容的时候添加两个地方
命令体和命令回调对应表
然后编写命令回调函数即可。
继续回到下行数据处理上来,处理完命令之后,就是释放相关内存,然后调用NET_DEVICE_AddDataSendList(…)函数吧命令回复的内容加入链表,最后置位一下onenet_info.send_data上传一次数据,以更新OneNET设备上的数据。
7. 网络维持—net_task.c
在NET_**_Task任务里边,和数据上传一样的流程,定时发送心跳,然后等待心跳返回正确的结果,以此判断网络是否通畅
同样的,在DATA_P_Task任务里边调用OneNET_SendData_Heart()函数打包心跳数据并清除心跳标志,在DATA_S_Task任务里真正发送出去,在OneNET_RevPro()函数里边解析心跳数据,收到则置位心跳标志,然后在OneNET_Check_Heart()来检测心跳标志。
如果在规定时间内检测不到心跳标志,则会检测当前模组状态,根据状态分配错误等级,然后会进入相关错误处理。
8. 网络监测、错误处理
7中说到,心跳标志检测不到,会进入错误处理,先看看错误等级处理都干了什么:
fault.c--NET_Fault_Process
将相关标志位清零,在任务里边检查到标志位变化,会执行对应功能,错误等级为1,只是负责重新连接一下ip。
错误等级2就是走初始化流程,去重新初始化一下网络模组了。
错误等级3是复位网络模组。
错误等级4是给网络模组断电后,等待一会,再打开。
那么错误等级如何确定,下面一一截图说明
NET_FAULT_LEVEL_1的场景:
net_task.c--OS_TimerCallBack
在网络定时检测回调里,发送数据未得到回应次数超过规定次数时。
onenet.c--OneNET_CmdHandle
当收到网络模组返回的连接关闭提示时。
onenet.c-- OneNET_Check_Heart
心跳标志接收超时,且网络模组具备网络能力时。
NET_FAULT_LEVEL_3的场景:
错误2和3通畅搭配使用,在重新初始化之前,先复位一下。
net_task.c--OS_TimerCallBack
当网络断开超过规定时间时。
onenet.c-- OneNET_Check_Heart
心跳标志接收超时,且网络模组不具备网络能力时。
fault.c
在错误等级1下,在规定次数内还未连接成功时。
可以看到,在例程里边有很多地方都在保障网络的通畅性,一旦发生网络错误,则会根据响应状态制定错误处理,争取用最高效的方式重新接入OneNET。