通信架构设计源码范例
.c文件内容
1、变量
1、日志标签
2、自定义的收发队列
3、解析后的报文缓冲区/发送报文打包区
4、交互参数
1、对端的参数结构体管理,用来记录对端参数状态的,交互用
2、己端的参数结构体管理,用来记录己端参数状态的,交互用
3、控制过程参数,一般用来做控制用,状态机流程相关的控制参数
2、参数名转成字符串函数,翻译函数
在打印日志时,特变是打印参数时,翻译函数可将参数从某个枚举类型值,转成枚举值字符串
3、参数Set Get 函数
参数不在通过简单的赋值去控制,而是通过Set、Get 接口函数操作,通过static 关键字和.h文件的函数声明管理参数的操作权限
1、Set函数说明
1、函数名设计:比如参数 ccuParam 的 cpState 成员的 Set 函数命名为 ccuParamSet_cpState
2、当参数变化时才允许修改,且把变化前后值打印出来,并打印一条报文,报文打印调用日志标签、翻译函数
2、Get函数说明
1、函数名设计:比如参数 ccuParam 的 cpState 成员的 Get 函数命名为 ccuParamGet_cpState
4、整个参数的RST函数
当需要直接对 ccuParam 整个参数置0时,可以设计如下函数
5、发送/接收 hex 源码打印函数
调用相应的日志标签,打印 hex 源码报文
6、发送报文打包接口函数
按照报文信息,一个一个数据,顺序打包到txMsgbuff,并打印一次发送 hex 源码;此后即可将数据包发送到 发送队列txQue里,驱动层自动调队列数据从串口发送出去
7、具体某条报文的打包发送函数
比如 发送到对端的一条 ccuStatus 报文,用该函数打包具体的内容,并打印hex打印源码一条
8、table表
table表是用来封装对端不同报文的处理函数
9、具体对端的报文处理函数
得到对端报文后用结构体指针解析每个参数的值,打印参数信息格式:[DB_INFO] SECC_STATUS{SessState:%s, CpPwmDuty:%d, ContactorOp:%s, CpPwmDutySet:%s}
之后就是得到相应报文后,做相应的操作
10、对端报文解析处理函数
11、通信 Comm 处理函数
第一部分:对端报文for 查表
1、通过报文解析函数反馈值,判断是否收到正确报文
2、for循环查 table 表,进入相应对端报文的处理函数,做相应的处理
第二部分:主动循环处理
比如状态变化,100ms周期要发某条报文等等
12、初始化函数
1、接收回调函数初始化
2、接收发送队列初始化函数
3、初始化接口函数,即上述的集合函数
13、任务函数
当初始化成功后,才允许 comm通信处理
.h文件内容
1、字符串常量,翻译函数用到的
2、可用宏封装一些冗余的表达式,更直观
3、table表结构体:函数指针+枚举
4、对端报文帧格式类型声明:结构体/联合体
1、通常我们通过指针去直接操作接收报文的,方便快捷
2、一般都需要按字节对齐
#pragma pack(push, 1)
#pragma pack(pop)
5、交互参数结构体声明
6、允许外部调用的函数声明
3、日志打印时机
日志打印时机是很重要的一个意识,何时使用日志打印、哪个地方加打印,这很重要!!!上述主包的通信收发例子中,主要以下的地方增加打印
1、接收报文处理的地方:接收的报文跟上一包有变化,打印所有参数、HEX源码,如下
打印的内容就是:
[RX_HEX]:DB AC 00 01 02 ....
CCU_STATUS{ocpd:1, resumeTri:2 ......}
2、发送报文处理的地方:发送的报文跟上一包有变化,打印所有参数、HEX源码,如下
打印的内容就是:
[TX_HEX]:DB AC 00 01 02 ....
SECC_STATUS{sessionState:SECC_CHARGE_IDLE, dataTransRes:2,.....}
3、参数设置接口:当设置参数,且参数变化的时候,打印变化前后值,如下
打印的内容是:
[SET_SECC_STATUS_PARA] sessionState:0 -> 1
4、状态机切换、异常发生:把状态机切换或异常发送的条件,以及跳转的下一个状态名,打印出来
日志打印总结:
以上打印主要完成了如下指标:
1、避免重复打印
2、清晰看透收发报文的内容
3、系统状态运作,能够通过打印日志看透
4、可以看到属性参数何时发生变化
5、当然,还有个关键的是要写好状态机