1、应答式,主机主动发起请求从机响应的方式,解决从机无序应答。
解决丢帧或帧错误,如果从机未响应,尝试计数器:com->tx_retry会计数,在尝试 SCOM_4_TX_RETRY 后仍未响应,拆除请求数据帧。
2、栈式缓冲,解决业务数据不能及时响应时,不丢失云端业务数据。
做法:将需要请求的帧,存放不同的缓冲栈,com->TxBuf[SCOM_4_TX_STACK][SCOM_4_TX_BUF_LEN]
入栈:目标栈计算:dst_stk = com->tx_stk_cur + com->tx_stk_cnt;
3、帧协议可以传输文件,要求:a)文件传输必须快,2) 不能影响正常的业务信息
解决方式:1)文件在每一帧的空闲位置传送,帧的最大容量为 SCOM_4_TX_BUF_LEN
2)保证文件的立即快速传送
3)不另起帧专门传递文件数据,采用将文件数据插入到业务帧&心跳包的空闲空间
综上:a) 栈式分布是缓冲,避免主机请求阻塞时的处理 b) 应答式避免从机无序响应
注意:1) 虽然分布式缓冲解决了主机阻塞时的缓冲处理,但同一时刻只有一个数据帧等待响应(com->tx_stk_cur ),响应后将立即拆除缓冲栈的数据帧
2) 由于是应答式,所以从机注意接收到有效帧后必须及时应答,尽量避免主机重发数据帧。
3) 处理数据包的频率 SCOM_4_Process(),一定要高于发送心跳包的频率,否则会人为的阻塞缓冲栈。
数据抽象:
typedef struct { CWnd* m_pOwner; void *udat; f_Com4Cb msg_callback; //串口发送,串口接收数据处理 f_Com4Ex exd_callback; S_Com4Tsk *task; unsigned short rx_pos; //分析接收栈的位置指示器 unsigned char tx_retry; //应答重试次数计数器,无应答重复发送相同帧次数 unsigned char tx_sem; //计数字节,每发送一帧数据+1 unsigned short tx_tick; //发送数据帧的时间间隔,SCOM_4_BIT_CYCLE*主循环时间 unsigned char tx_stk_cnt; //待发送栈的数量,总共有SCOM_4_TX_STACK,超过后不允许打包数据 unsigned char tx_stk_cur; //当前正在等待处理的栈,即当前栈需要等待接收应答 unsigned char TxBuf[SCOM_4_TX_STACK][SCOM_4_TX_BUF_LEN];//栈发送数据实例 unsigned int TxLen[SCOM_4_TX_STACK]; //每个栈待发送数据的长度 unsigned char TxSem[SCOM_4_TX_STACK]; //每个栈的计数字节 unsigned char RxBuf[SCOM_4_RX_BUF_LEN]; //接收BUF //extra data transmit function #ifdef SCOM_4_MASTER unsigned char PadBuf[SCOM_4_TX_BUF_LEN]; #endif unsigned short ex_fun; //文件任务是否停止指示器,如果文件未发送完成,应立即发送 unsigned char ex_cmd; //文件传输状态命令字 unsigned char ex_typ; unsigned int ex_len; //发送文件的总长度 unsigned int ex_ptr; //已发送文件长度,未发送文件的起始位置 unsigned char *ex_str; unsigned char crc64[8]; } S_Com4hd;
源码使用说明
(1) ScCom_4.c文件提供了以下3个API接口函数:
① int SCOM_4_Init(S_Com4hd* com, f_Com4Cb Cb, f_Com4Ex ex, void *uDat)
协议初始化,在开始通信前调用一次(一般为应用程序启动时),用于初始化协议资源,其参数定义如下:
参数1:协议句柄,需传入一个S_Com4hd类型的变量实体的地址。
参数2:通信回调函数,用于数据交换及通知。
参数3:数据传输回调函数,用于OTA数据传输,不使用可传空。
参数4:用户变量指针,不用可传空。
② void SCOM_4_Process(S_Com4hd* com, int txc)
协议周期处理,需周期调用,建议调用周期不大于100ms,该函数会周期性读取串口数据并解析出有效的数据包,当收到有效数据包时通过回调函数通知应用程序,这意味着调用频率越高,响应越迅速,其参数定义如下:
参数1:协议句柄。
参数2:不使用,传空即可。
③ int SCOM_4_SendPack(S_Com4hd* com, unsigned char* msg, unsigned short len)
数据包发送,当收到显示屏发来的数据包后调用该函数进行回复,其参数定义如下:
参数1:协议句柄。
参数2:数据内容。
参数3:数据长度。
(2) 通过SCOM_4_Init设置的通信回调函数MSG_Callback可按照如下定义:
该回调函数用于串口数据交换及数据包通知,使用时需要填入以下接口:
① 串口发送回调,通过串口发送长度为len的数据缓冲msg
② 串口接收回调,通过串口读取数据到msg,并返回读取长度len
③ 串口同步回调,用于串口收发同步,避免冲突,正常可不填
④ 收到命令回调,cmd为命令,msg为命令内容,内容度为len
(3) OTA数据接收,通过SCOM_4_Init设置的通信回调函数EXD_Callback可按照如下定义:
该回调函数用于接收OTA数据,提供了以下接口:
⑤ 开始数据传输,用于启动接收流程(如打开文件)
⑥ 数据段传输,用于接收一段数据流(如写入文件)
⑦ 数据传输完成,用于结束接收流程(如关闭文件)
⑧ 数据传输复位,用于重置接收流程(一般不用)
(4) 数据解析与回复
① 从命令回调里直接取出命令内容进行解析。
② 每收到一帧数据包必须进行回复,可直接在命令回调里进行回复(直接调用SendPack函数对要发送的数据进行打包并发送)
协议:
备注:
所有数据高字节在前,低字节在后
计数值:逐帧递增,可通过计数值判断是否有丢帧,或者是否是重复发送的帧。
心跳及状态
命令: 0xA0
ANDRIOD -> 设备:
Byte |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18,19 |
内容 |
年 |
月 |
日 |
时 |
分 |
秒 |
联网状态 |
设备控制字 |
备注 |
|
|
|
|
|
|
0/1 |
2字节 |
设备 -> ANDRIOD:
Byte |
11~14 |
15~30 |
31~46 |
内容 |
产品id |
产品key |
故障字 |
备注 |
4字节 |
16字节 |
16字节(128位) |
Byte |
47~54 |
55 |
56 |
57~72 |
内容 |
停售指令 |
故障指令 |
设备状态 |
版本号 |
备注 |
8字节(64位) |
|
|
16字节 |
Byte |
73 |
74 |
75 |
76 |
77 |
... |
77+n*2 |
78+n*2 |
内容 |
设备操作码 |
制作进度 |
状态1 |
... |
状态n |
|||
备注 |
2字节 |
1字节 |
2字节 |
... |
2字节 |
备注:
(1)产品id和产品key在平台获取。
(2)设备控制字,SDT07对设备的全局控制参数。
(3)故障字和故障指令:
故障字共16字节,128位,毎1位代表一种故障,全部为0时表示无故障。平台最多支持定义128种故障,定义好故障后,发生故障时,平台可以解析并显示发生的故障,生成相应的维保工单。
故障指令可取值:
0 - 无故障操作。
1 - 预警,屏幕不提示,不影响售卖,仅上报平台产生维保工单。
2 - 可自动恢复故障,屏幕跳转至故障页面,停止售卖,故障消失即可恢复售卖。
3 - 不可自动恢复故障,屏幕跳转至故障页面,停止售卖,即使故障消失也不能恢复售卖,需要重新上电。
4 - 严重故障,需要厂商到场输入密码解锁。
当故障字和故障指令均不为0时,屏幕执行故障指令对应的操作。
(4)停售指令:8字节,64位,每一位表示停售某一类商品,全部置1,则设备停售所有商品。平台上最多可定义64个商品种类。
(5)设备状态:
0 - 设备启动中
1 - 设备空闲
2 - 设备正在制作商品
(6)设备操作码,可以是设备端的按键操作的键值。
(7)制作进度,0~100。
(8)状态1~n在平台上定义,定义完成后,平台上可解析并显示设备的状态;
(9)每个状态数据均占用2字节;
(10)心跳包间隔500ms;
(11)状态数据毎30s发送至云端一次。