剖析中移物联网麒麟座开发板代码模块

电子说

1.2w人已加入

描述

 

 

一、简述

麒麟座开发板代码例程由OneNET-基础例程、OneNET-进阶例程、OneNET-RTOS例程组成,由浅入深地演示如何接入OneNET,从最基本的上传数据点,命令接收处理,到网络维持,平台连接维持,到最后的网络错误处理,一步一步演示如何处理这些事情。

 

下面先以OneNET-基础例程为例,讲解如何接入OneNET。

二、OneNET-基础例程模块分析

OneNET

1. 代码框架说明

  • 初始化开发板外围硬件;如LED、蜂鸣器、按键等。

  • 初始化网络模组;开发板板载GSM模组-M6312,可插拔的WIFI-ESP8266-01模组。

  • 登录OneNET。

  • 执行相关上下行数据处理。

 

2. 代码功能简述

演示如何接入OneNET,如何处理OneNET推送的数据。

不具备网络维持能力,掉网后无法处理。

 

3. 初始化开发板外围硬件-Hardware_Init()函数

根据不同功能所需要用到的外围硬件不同,可根据自己使用的例程查看相应的硬件驱动代码,这里以 OneNET 为例说明

OneNET

麒麟座使用的STM32F103RET6单片机,mini板使用STM32F103C8T6单片机,都是F1系列,编程方式完全一致。

  • 先配置单片机的中断分组,采用2:2配置;

  • 然后初始化systick用来做阻塞延时;

  • 然后初始化串口1和串口2,串口1用来调试打印,串口2和网络模组通信;

  • 然后就是初始化LED,蜂鸣器,按键,主要就是GPIO的配置;

  • 最后打印一下,提示硬件初始化完成。

 

4. 初始化网络模组-ESP8266_Init()函数

OneNET

WIFI模组的初始化比较简单:

  • 先初始化相关控制的GPIO。

  • 然后先发送AT,测试通信是否OK。

  • 然后就是设置WIFI工作模式、登录路由、连接IP。

  • 如果是GSM模组,前两步相同,初始化控制GPIO、发送AT测试通信。然后是注册、激活网络、连接IP。

 

5. 登录OneNET -OneNet_DevLink()函数

OneNET

主要流程就是获取登录数据,然后发送出去,等待返回。

获取登录数据:

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

执行OneNet_SendData()函数,会调用相关上传功能。

OneNET

166行,是封装一个json,把要上传的内容写在里边

170行,根据devid、json格式和json封装协议包

175行,将协议包上传。

简单看看166行的内容

OneNET

其中led_status.xxx,就是我们要上传的数据,按照json格式写好即可,如果新增数据点,复制高亮三行的任意一行加以扩展,然后把箭头的buf缓存开大一点即可。

下行数据

先判断驱动层是否收到数据,有则调用OneNet_Re**taPtr)函数解析相关功能。

OneNET

判断是否是下发命令,是则回复这个命令,然后做相关命令的处理

OneNET

 

三、OneNET-RTOS例程模块分析

OneNET

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

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时,可自行更改,触发一次上传数据的标志,箭头所指处。

OneNET

然后在net_task.c--DATA_P_Task任务里判断到标志置位,执行OneNET_SendData(…)函数根据当前的data_stream值去打包一个待上传的数据包,但此时并不上传,而是放入一个单向链表里,原因稍后分析,如果上传成功,则返回值会改变onenet_info.send_data的值,如果错误,则会间隔一段时间后继续回来打包数据。

OneNET

最终将数据发送出去的的是net_task.c--DATA_S_Task任务判断表头是否为空,且网络连接正常,然后获取表里数据和对应长度,吧数据发往OneNET。

OneNET

简单说一下,为什么上传一包数据,分了三个步骤(触发、打包、发送),因为这样可以在其他地方方便地上传数据,只需要改变一个变量值即可,而不用调用复杂的打包、发送函数,对函数堆栈要求降低很多;然后发送作为一个单独的任务是为了网络模组稳定性,wifi和gsm发送数据的时间间隔不同,wifi可以快一点,当短时间内有很多包大小不同的数据包待上传时,发送必须要稳定,所以OneNET_SendData(…)只是打包放入链表,发送函数以一个稳定的时间间隔来一包包的发出去。

下行数据

在net_task.c-- RECV_Task任务里边,只有一个函数OneNET_CmdHandle

OneNET

先是调用NET_DEVICE_Read()函数判断驱动层是否收到数据。

然后调用NET_DEVICE_GetIPD(dataPtr)判断是否具有IPD头,这里说明一下,在绝大多数网络模组里,在指令模式下,如果收到一帧网络数据,则会以IPD标识(不同网络模组这个头可能不一样),如果带有IPD头,则说明收到OneNET推来的数据,进入OneNET_RevPro(ipdPtr)函数进行处理。

处理函数里边先通过EDP_UnPacketRecv(cmd)判断推送数据的类型,以EDP为例,有连接响应、命令下发、数据转发、心跳回复等,然后各自处理即可。

最后具体说说命令下发的处理机制。

OneNET

先调用EDP_UnPacketCmd(…)函数解析出uuid、uudi长度、命令、命令长度。

然后是调用EDP_PacketCmdResp(…)函数打包命令回复的内容。

然后是调用CALLBACK_Execute(...)函数处理命令,在cmd_callback.c里边可以找到处理的过程

OneNET

调用CALLBACK_Find_CallBack(…)找到红框处XXX的内容,这是是命令体,后边YYY是命令值,后边会用到

OneNET

然后根据命令体对应的回调函数,执行响应的动作,比如redled,

OneNET

调用CALLBACK_Find_Value(…)函数找到命令参数YYY

调用CALLBACK_Str2Dec(…)函数转为数值形式,方便执行开关处理。

大家在添加自己的命令和处理内容的时候添加两个地方

OneNET

命令体和命令回调对应表

然后编写命令回调函数即可。

继续回到下行数据处理上来,处理完命令之后,就是释放相关内存,然后调用NET_DEVICE_AddDataSendList(…)函数吧命令回复的内容加入链表,最后置位一下onenet_info.send_data上传一次数据,以更新OneNET设备上的数据。

 

7.  网络维持—net_task.c

在NET_**_Task任务里边,和数据上传一样的流程,定时发送心跳,然后等待心跳返回正确的结果,以此判断网络是否通畅

OneNET

同样的,在DATA_P_Task任务里边调用OneNET_SendData_Heart()函数打包心跳数据并清除心跳标志,在DATA_S_Task任务里真正发送出去,在OneNET_RevPro()函数里边解析心跳数据,收到则置位心跳标志,然后在OneNET_Check_Heart()来检测心跳标志。

如果在规定时间内检测不到心跳标志,则会检测当前模组状态,根据状态分配错误等级,然后会进入相关错误处理。

OneNET

 

8.  网络监测、错误处理

7中说到,心跳标志检测不到,会进入错误处理,先看看错误等级处理都干了什么:

fault.c--NET_Fault_Process

OneNET

将相关标志位清零,在任务里边检查到标志位变化,会执行对应功能,错误等级为1,只是负责重新连接一下ip。

OneNET

错误等级2就是走初始化流程,去重新初始化一下网络模组了。

OneNET

错误等级3是复位网络模组。

OneNET

错误等级4是给网络模组断电后,等待一会,再打开。

那么错误等级如何确定,下面一一截图说明

NET_FAULT_LEVEL_1的场景:

net_task.c--OS_TimerCallBack

在网络定时检测回调里,发送数据未得到回应次数超过规定次数时。

OneNET

onenet.c--OneNET_CmdHandle

当收到网络模组返回的连接关闭提示时。

OneNET

onenet.c-- OneNET_Check_Heart

心跳标志接收超时,且网络模组具备网络能力时。

OneNET

NET_FAULT_LEVEL_3的场景:

错误2和3通畅搭配使用,在重新初始化之前,先复位一下。

net_task.c--OS_TimerCallBack

当网络断开超过规定时间时。

OneNET

onenet.c-- OneNET_Check_Heart

心跳标志接收超时,且网络模组不具备网络能力时。

OneNET

fault.c

在错误等级1下,在规定次数内还未连接成功时。

OneNET
可以看到,在例程里边有很多地方都在保障网络的通畅性,一旦发生网络错误,则会根据响应状态制定错误处理,争取用最高效的方式重新接入OneNET。

 

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分