文档中心
机智云 文档中心
English
热搜词
APP
SDK
Android
ios
WIFI
GoKit3(V)二次开发-程序详解(旧)
文档编辑

2017年9月25日起已使用新版MCU代码生成,查看新版自动生成代码程序详解

通信协议详解

1 协议命令格式

我们首先了解具体通讯协议的约定,可以看到协议格式为:

Alt text

说明:

1) 包头(header)固定为0xFFFF;

2) 长度(len)是指从cmd 开始到整个数据包结束所占用的字节数;

3) 命令字(cmd)表示具体的命令含义,详见协议举例;

4) 消息序号(sn)由发送方给出,接收方响应命令时需把消息序号返回给发送方;

5) 标志位(flag),本产品填写默认0;

6) payload(p0数据区),详细参见p0 数据区约定;

7) 检验和(checksum)的计算方式为从len~DATA,按字节求和;

8) 所有发送的命令都带有确认,如在200 毫秒内没有收到接收方的响应,发送方;应重发,最多重发3 次;

9) 多于一个字节的整型数字以大端字节序编码(网络字节序);

10) 数字均用16 进制表示;

2 “p0 数据区约定”解析

“p0 数据区约定”有如下功能:

1) 模块向MCU发送控制命令时携带p0 命令和命令标志位以及可写数据区

2) MCU主动发送状态时或者回复模块的状态查询时携带p0命令和完整数据区

3) 数据区会自动合并布尔和枚举变量,且有严格的顺序,不可任意改变

怎么来理解这三个功能呢?将前序中准备的《XX-机智云接入串口通讯协议文档》如打开,我们会看到如下命令:

1)WiFi模组请求设备信息;

2)WiFi模组与设备MCU的心跳;

3)设备MCU通知WiFi模组进入配置模式;

4)设备MCU重置WiFi模组;

5)WiFi模组向设备MCU通知WiFi模组工作状态的变化;

6)WiFi模组请求重启MCU;

7)非法消息通知;

8)WiFi模组读取设备的当前状态;

9)设备MCU向WiFi模组主动上报当前状态;

10)WiFi模组控制设备;
(之后非重点省略)

“p0 数据区约定”主要作用是完成有效数据的上传(协议4.8、4.9)与下达(协议4.10),其中上传协议的组成形式为:action(1B) + dev_status(11B) ; 下达协议的组成形式为:action(1B) + attr_flags(1B) + attr_vals(6B) ; 其中:

p0 数据区内容 含义
action 表示”p0 命令”的传输方向,即:WiFi -> MCU 或 MCU ->Wifi
dev_status 表示上报的所有数据点的设备状态
attr_flags 表示有效的控制型数据点
attr_vals 表示有效控制数据点的数据值

需要特别注意的是“p0 数据区约定”约定第三条,数据区会自动合并布尔和枚举变量,且有严格的顺序,不可任意改变。对应上面的“byte0”合并了“bool”和“enum”类型。

至此“p0 数据区约定”的解析到此结束,之后我们还会分析MCU的程序实现。

程序详解

1 代码目录介绍

1.1 一级目录说明

Alt text

文件夹 说明
Gizwits 协议相关目录
Hal 外设驱动库
Lib STM32驱动库
Project 工程管理文件
User 代码入口文件目录
README.txt GoKit3(V)文档

1.2 代码文件说明

Alt text

主要文件说明:

文件 说明
gizwits_product.c 该文件为产品相关处理函数,如 gizEventProcess(),平台相关硬件初始化,如串口、定时器等
gizwits_product.h 该文件为 gizwits_product.c 的头文件,存放产品相关宏定义如: HARDWARE_VERSION 、SOFTWARE_VERSION
gizwits_protocol.c 该文件为 SDK API 接口函数定义文件
gizwits_protocol.h 该文件为 gizwits_protocol.c 对应头文件,相关 API 的接口声明均在此文件中

1.3 协议API介绍

API 名称 API 功能
void gizwitsInit(void) gizwits协议初始化接口。用户调用该接口可以完成Gizwits协议相关初始化(包括协议相关定时器、串口的初始化)。
void gizwitsSetMode(uint8_t mode) 参数mode[in]:仅支持0,1和2,其他数据无效。参数为0,恢复模组出厂配置接口,调用会清空所有配置参数,恢复到出厂默认配置。参数为1时配置模组进入SoftAp模式; 参数为2配置模组进入AirLink模式。
void gizwitsSetMode(uint8_t mode) 参数mode[in]:仅支持0,1和2,其他数据无效。参数为0,恢复模组出厂配置接口,调用会清空所有配置参数,恢复到出厂默认配置。参数为1时配置模组进入SoftAp模式; 参数为2配置模组进入AirLink模式
void gizwitsHandle(dataPoint_t *dataPoint) 参数dataPoint[in]:用户设备数据点。该函数中完成了相应协议数据的处理即数据上报的等相关操作。
int8_t gizwitsEventProcess (eventInfo_t info, uint8_t data, uint32_t len) 参数info[in]:事件队列;参数data[in]:数据;参数len [in]:数据长度;用户数据处理函数,包括wifi状态更新事件和控制事件。a)Wifi状态更新事件:WIFI_开头的事件为wifi状态更新事件,data参数仅在WIFI_RSSI有效,data值为RSSI值,数据类型为uint8_t,取值范围0~7。b)控制事件:与数据点相关,本版本代码会打印相关事件信息,相关数值也一并打印输出,用户只需要做命令的具体执行即可。

2 程序实现原理

协议实现机制:

协议解析后,将P0数据区的有效数据点生成对应的数据点事件,再按事件处理数据点。

数据点转换事件的说明:

根据协议P0数据区的attr_flags位判断出有效数据点,并将其转化成对应的数据点事件,然后在事件处理函数中(gizwitsEventProcess)完成事件的处理。

3 程序初始化说明

3.1 数据协议结构体的定义

结构体dataPoint_t ,代码位置: gokit_mcu_stm32_xxx\Gizwits\gizwits_protocol.h

Alt text

说明:结构体dataPoint_t作用是存储用户区的设备状态信息,用户根据云端定义的数据点向其对应的数据位赋值后便不需关心数据的转换,其数据位对应“p0 数据区约定”中的“4.9 设备MCU向WiFi模组主动上报当前状态”中的:dev_status(11B) 位:

Alt text

attrFlags_t、attrVals_t ,代码位置: gokit_mcu_stm32_xxx\Gizwits\gizwits_protocol.h

Alt text

结构体attrFlags_t、attrVals_t分别对应“p0 数据区约定”中的“4.10 WiFi模组控制设备”中的:attr_flags(1B) + attr_vals(6B)位:

Alt text

结构体devStatus_t,代码位置: gokit_mcu_stm32_xxx\Gizwits\gizwits_protocol.h

Alt text

结构体devStatus_t对应“p0 数据区约定”中“4.9 设备MCU向WiFi模组主动上报当前状态”中的:dev_status(11B) 位:

Alt text

特别说明:

A. 数据结构说明

dataPoint_t 为应用层数据结构,开发者需要了解并会使用(具体使用方式请查看:“2.7.1 只读型数据的获取”一节)。

attrFlags_t、attrVals_t、devStatus_t为通信层数据结构,开发者需要结合通讯协议进行理解。

B. 位段举例说明:

uint8_t motor_switch:1; 是一种位段的使用方式。因为 uint8_t型数据占用 8bit(8位)的空间,协议中motor_switch占用字段bit0(第一位)所以uint8_t motor_switch:1表示使用1位的空间。

uint8_t reserve:7; 因为程序中申请内存时的最小单位是byte(字节),而这里我们是按bit(位,8bit = 1byte)进行了使用,故需补齐不足1byte的剩余bit(使用n bit后需补齐剩余的8-n bit)。

注:位段不能跨字节操作,否则会造成数据读写错误。

3.2 程序主函数

位置:gokit_mcu_stm32_xxx\User\main.c中main() 函数:

Alt text

相关说明:

函数 说明
SystemInit() 平台相关的硬件初始化(非API,不同的平台名称可能不同)
userInit() 用户相关的初始化,如:外设驱动初始化、打印串口初始化(非API,不同的平台名称可能不同)
gizwitsInit() 平台、协议处理初始化,如:用户定时器初始化、协议通信串口初始化(协议API)
userHandle() 用户事件回调函数,用户可以自定义事件在该函数中完成相应的协议处理。(非API,不同的平台名称可能不同)
gizwitsHandle() 协议相关的主函数(协议API)

3.3 用户程序初始化

接下来看用户初始化相关代码(位置:main.cuserInit() 函数):

Alt text

这部分完成了RGB LED、电机、温湿度、红外传感器的硬件驱动初始化以及电机初始状态,对应的驱动程序实现都在 gokit_mcu_stm32_xxx\Hal 下。

这里主要完成了配置入网的功能,作为开发者可以按照自己的需求来实现这部分代码。

下面是平台协议相关初始化 (位置:main.c中gizwitsInit() 函数):

Alt text

其中完成了定时器、串口的初始化(详情查看2.3.4、2.3.5两节),以及一个环形缓冲区的初始化。

最后是一个通信处理模块结构体的变量的初始化,该变量为通信模块的全局变量:

Alt text

其定义的位置:user\user_mian.c

Alt text

相关结构体内容,详情查看“2.3.1 数据协议结构体的定义”一节。

3.4 定时器使用

相关代码:

定时器初始化,代码位置:gokit_mcu_stm32_xxx\Gizwits\gizwits_product.c 中timerInit()函数
Alt text

注:这里我们定义了周期为1ms的定时器,其定时计算公式为:
Alt text

定时器中断函数,代码位置:gokit_mcu_stm32_xxx\Gizwits\gizwits_product.c
Alt text

注:在该中断函数内我们完成了周期为1ms的定时累加计数。

定时器使用说明:
代码位置:gokit_mcu_stm32_xxx\Gizwits\gizwits_product.h

Alt text

a.这里我们使用定时器TIM3(#define TIMER TIM3);

b.TIM3的中断回调函数为UTIM3_IRQHandler() (#define TIMER_IRQ_FUN TIM3_IRQHandler);

特别说明(复用TIMER2的方式,修改对应宏即可):

Alt text

Alt text

3.5 串口的使用

相关代码:

串口初始化,位置:gokit_mcu_stm32_xxx\Gizwits\gizwits_product.c 中的uartInit()
Alt text

串口中断函数,位置:gokit_mcu_stm32_xxx\Gizwits\gizwits_product.c
Alt text

串口使用说明:

代码位置:gokit_mcu_stm32_xxx\Gizwits\gizwits_product.h

Alt text

a.这里我们使用USART2(#define UART USART2),作为数据通信的串口;

b.设置它的波特率为9600(#define UART_BAUDRATE 9600)

c.USART2的串口中断回调函数为USART2_IRQHandler() (#define UART_IRQ_FUN USART2_IRQHandler),在该中断函数内我们完成了串口数据的接收。

特别说明(复用USART1的方式,修改对应宏即可):
Alt text

4 配置模式说明

设备需要进入配置模式才能进行联网,并与云端进行通信,在本示例工程中是通过按键触发进入相应的配置模式。

Wifi 配置接口说明:

/**

  • @brief WiFi配置接口
    *

  • 用户可以调用该接口使WiFi模组进入相应的配置模式或者复位模组
    *

  • @param[in] mode 配置模式选择:0x0, 模组复位 ;0x01, SoftAp模式 ;0x02, AirLink模式
    *

  • @return 错误命令码
    */
    ·int32_t gizwitsSetMode(uint8_t mode)

程序中触发逻辑位置:gokit_mcu_stm32_xxx\User\main.c

A.进入Soft AP 模式:key2按键短按。
Alt text

B.进入AirLink 模式:key2按键长按。
Alt text

C.模组复位:key1按键长。
Alt text

5 协议处理函数的实现

位置:gokit_mcu_stm32_xxx\Gizwits\gizwits_protocol.c中gizwitsHandle() 函数:

Alt text

以下是该协议处理函数的详细介绍:

● 首先是一些局部变量的初始化,比较重要的是:“protocolHead_t *recvHead = NULL;”它的作用是保存解析出来的协议包头。

Alt text

● 然后是协议的重发机制,它的作用是对发送后的协议数据进行超时判断,超时200ms进行重发,重发上限为三次:

Alt text

● 接下来程序会从环形缓冲区中抓取一包的数据,例如协议4.9:

Alt text

程序中对应如下:

Alt text

● 当我们获得到一整包的数据,就会进入下面的if判断逻辑,进行协议的解析。

Alt text

这里保存了接收到的协议包头:

Alt text

● 然后是各协议命令的处理流程:

Alt text

其中完成了《机智云 - 设备串口通讯协议》中相关的协议处理,如下:

Alt text

例如协议4.8:

Alt text

其“cmd”值 为“0x03”,对应程序中的的case为“CMD_ISSUED_P0”

Alt text

同理其他协议cmd值对应的宏定义的位置在Gizwits\gizwits_protocol.h中:

Alt text

其中与P0协议有关的处理都在“gizProtocolIssuedProcess”中完成,详情请查看“2.6 控制型协议的实现”、“2.7 上报型协议的实现”两节。

其余协议处理函数功能如下所示:

函数 说明
gizProtocolGetDeviceInfo 完成“协议4.1 WiFi模组请求设备信息”
gizProtocolIssuedProcess 完成“协议4.8 WiFi模组读取设备的当前状态”与“协议4.10 WiFi模组控制设备”。当Wifi模组接收来自云端或APP端下发的相关协议数据发送到MCU端,经过协议报文解析后将相关协议数据传入次函数,进行下一步的协议处理。
gizProtocolCommonAck 发送通用协议报文数据
gizProtocolModuleStatus 完成“协议4.5 WiFi模组向设备MCU通知WiFi模组工作状态的变化”的处理
gizProtocolWaitAckCheck 完成 “协议4.4 设备MCU重置WiFi模组 中 WiFi模组回复”后清除ACK协议报文
gizProtocolReboot 完成“协议4.4 设备MCU重置WiFi模组” 的相关操作
gizProtocolErrorCmd 完成“协议4.7 非法消息通知” 的处理
gizwitsEventProcess() 执行用户事件回调函数,用户可以自定义事件在该函数中完成相应的协议处理。

● 协议判断完成后是一个状态机的判断,用来完成对应协议命令的处理:

Alt text

例如在P0协议处理函数(gizProtocolIssuedProcess)中,当我们完成了控制型协议的解析,会让 issuedFlag = 1,如下:

Alt text

然后会执行如下的处理,执行gizwitsEventProcess函数

Alt text

gizwitsEventProcess 中,完成了对应控制型事件的处理,其他状态的issuedFlag 同理。

● 之后是一个数据上报判断机制,主要执行了gizCheckReport函数

Alt text

gizCheckReport函数的作用用来判断当前与上次上报数据的一致性,如果符合上报条件便上报,上报条件要符合协议“4.9 设备MCU向WiFi模组主动上报当前状态”中的描述:

Alt text

符合上报之后会执行数据类型的转化函数gizDataPoints2ReportData(详情查看“2.8 机智云协议数据处理”一节),以及数据上报函数gizReportData

● 最后一段代码是一个数据定时上报机制:

Alt text

对应协议“4.9 设备MCU向WiFi模组主动上报当前状态”中的描述:

Alt text

至此我们完成了协议处理函数的详解。

6 控制型协议的实现

与控制型协议相关的函数调用关系如下:
Alt text

函数调用说明:

函数 说明
gizProtocolIssuedProcess 该函数被gizwitsHandle调用,接收来自云端或app端下发的相关协议数据
ACTION_CONTROL_DEVICE 进行“控制型协议”的相关处理
gizDataPoint2Event 根据协议生成“控制型事件”,并完成相应数据类型的转换
gizwitsEventProcess 根据已生成的“控制型事件”进行相应事件处理(即调用相应的驱动函数)

6.1 控制型事件处理

相关代码位置:

gokit_mcu_stm32_xxx\Gizwits\gizwits_product.cgizwitsEventProcess() 函数:

功能说明:

完成写类型外设的事件处理。

相应代码:
Alt text

6.2 可写型数据类型转换

接收到来自云端的数据后,由于原始数据经过特殊处理,所以要在gizDataPoint2Event中进行相应的数据的转换。

转换函数说明:

函数 说明
gizDecompressionValue 完成传输数据的压缩处理,详情查看“2.8.2 数据解压与压缩处理”一节。
gizX2Y 将用户区数据转化为传输数据,详情查看“2.8.1 数据点类型转换”一节。

程序中对应:

Alt text

Alt text

7 上报型协议的实现

与上报型协议相关的函数调用关系如下:
Alt text

函数调用说明:

函数 说明
userHandle 获取用户区的上报型数据
gizCheckReport 判断是否上报当前状态的数据
gizDataPoints2ReportData 完成用户区数据到上报型数据的转换
gizReportData 将转换后的上报数据通过串口发送给WiFi模块

7.1 只读型数据的获取

相关代码位置:

gokit_mcu_stm32_xxx\User\main.cuserHandle() 函数:

使用说明:

该函数中完成了用户区上报型数据的获取。用户只需将读到的数据赋值到用户区当前设备状态结构体即可:

Alt text

注:赋值完的数据是通过gizwitsHandle (详情请查看“2.5 协议处理函数的实现”一节中:数据上报判断机制gizCheckReport部分)上报云端的,开发者不需要关注变化上报和定时上报。

7.2 上报状态判断

为了让API接口更简化,处理更简单,机智云把更多的判断放到协议模块来处理,达到了开发者只要把状态更新到协议处理模块,不需要关心何时上报,由协议处理模块自动完处理的目的。

相关代码:

gokit_mcu_stm32_xxx\Gizwits\gizwits_protocol.ccheckReport() 函数:

功能说明:

根据协议判断是否上报当前状态的数据,判断逻辑如下:

  1. 控制型数据发生状态变化,立刻主动上报当前状态
  2. 用户触发或环境变化所产生的, 其发送的频率不能快于6秒每次

协议中说明如下:(“4.9 设备MCU向WiFi模组主动上报当前状态”)

Alt text

以红灯开关为例:
Alt text

注:这部分用户可结合“2.5 协议处理函数的实现”一节中“数据上报判断机制”的内容来理解)。

7.3 只读型数据类型转换

获得到用户区的原始数据后,在传输到云端前要进行相应的数据转换,所以要在gizDataPoints2ReportData中进行相应的数据的转换。

转换函数说明:

函数 说明
gizCompressValue 完成传输数据的压缩处理,详情查看“2.8.2 数据解压与压缩处理”一节。

gizY2X | 将用户区数据转化为传输数据,详情查看“2.8.1 数据点类型转换”一节。 |

8 机智云协议数据处理

8.1 数据点类型转换

机智云为使设备功能定义更加简单直接,使用户输入的数值转换成设备能够识别的uint类型,这套算法的核心公式是:y=kx+m (y:显示值;x:传输值;k:分辨率;m:增量)

以《微信宠物屋》的温湿度传感器温度数据点为例:

Alt text

取值范围:-13(Ymin) ~ 187(Ymax),分辨率:1,增量:-13 ;

其分辨率、偏移量作为宏定义定义在app\Gizwits\gizwits_product.h中:

Alt text

根据公式:y=kx+m,k = 1 ; m = -13

实际传输的值:x = (y - m) / k

转换函数在程序中的说明:
A.X2Y的转换:
Alt text

B. Y2X的转换:
Alt text

8.2 数据解压与压缩处理

设备端与自云端的数据交互过程中,一些特殊类型(bool和enum类型)的数据点原始数据只有被特殊处理后才可被云端解析,所以设备端在接收云端数据时要进行数据的解压处理;在向云端发送数据时进行数据的压缩处理

机智云已封装出了相应的处理接口:

处理名称 接口名称
bool和enum类型数据点数据解压 gizDecompressionValue
bool和enum类型数据点数据压缩 gizCompressValue

以《微信宠物屋》的RGB LED控制为例,云端定义如下:

Alt text

对应文档中数据存储格式如下:

Alt text

字节序与bit序对应代码中宏定义如下:

Alt text

对应的数据点在接收解压时处理如下(位于gizDataPoint2Event函数中):位于

Alt text

对应的数据点在发送压缩时处理如下(位于gizDataPoints2ReportData函数中):

Alt text

相关支持

1) 如果您是开发者

GoKit是面向智能硬件开发者限量免费开放,注册我们的论坛或关注我们的官方微信均可发起申请即可。

开发者论坛: http://club.gizwits.com/forum.php

文档中心:http://docs.gizwits.com

2) 如果您是团体

GizWits针对团体有很多支持计划,您可以和GizWtis联系,快速得到GoKit以及技术支持;

网站地址:http://www.gizwits.com/about-us

官方二维码:

Alt text