当前位置: 首页 > news >正文

通信架构设计源码范例

.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、当然,还有个关键的是要写好状态机

http://www.jsqmd.com/news/1068356/

相关文章:

  • 凯源智能KT3351馈线弧光保护装置
  • VS Code设置插件默认安装路径
  • Awaken:终极跨平台EPUB阅读器 - 基于WebDAV的免费全平台同步解决方案
  • 小米智能家居与Home Assistant集成:构建高效本地化智能家居系统的终极指南
  • AI语音克隆未来展望:语音克隆技术的发展趋势与伦理考量
  • Renaissance Plateforme安全架构:保护政治数据隐私的10个关键策略
  • public-fitbit-projects未来 roadmap:新功能预告与社区贡献指南
  • 数据结构 C 代码 7.4: 关键路径
  • 构建有记忆的AI助手:深入解析OpenAI-Agents Session系统的架构设计与实战应用
  • EthereumJS-TX迁移指南:从独立库到EthereumJS VM monorepo的无缝过渡
  • 技术视角:ET框架的架构革新与分布式游戏服务端设计范式
  • TaskJuggler资源分配技巧:让团队效率最大化的秘密武器
  • UI-TARS技术深度解析:多模态智能体在GUI自动化领域的创新突破
  • Next-Admin国际化(i18n)最佳实践:多语言企业应用开发指南
  • Spraykatz高级参数详解:-u、-p、-t参数的最佳实践
  • X-SwiftFormat vs 其他格式化工具:为什么它是Swift开发者的最佳选择
  • 天翼云主机采购到域名备案再到项目发布全流程笔记
  • 如何快速上手WebRTC:5分钟实现浏览器视频通话的完整指南
  • Imogen工作流实战:从概念到成品的纹理设计全流程
  • 如何快速上手MCP-Security-Checklist:初学者完整教程与实战演练
  • 快速掌握SmartContracts-audit-checklist:Solidity审计效率提升300%
  • 如何快速集成 Hakawai:10分钟实现强大的 iOS 文本编辑器
  • React SSR Setup错误处理:构建健壮的React SSR应用的错误边界策略
  • Apache Ozone 介绍与部署使用(最新版2.0.0)
  • iOS网络请求优化终极指南:基于aqtoolkit的LowMemoryDownload实现
  • HACG搜索功能完全指南:如何高效查找动漫、漫画资源
  • 深度强化学习在ros+gazebo来实现导航的流程
  • Winterfell与后端集成指南:表单数据处理与提交最佳实践
  • CS2303 (原CS356) - 操作系统课程设计
  • Medium Editor Markdown深度解析:从安装到高级配置的完整教程