关注+星号公众号,不容错过精彩
作者:HywelStar
Hi, 今天主要分享的是写代码的模块化设计,主要以一个例子进行探讨分析。
想要写的好自己的代码,就需要学习一些思想,当拿到一个项目时候,切忌嘎嘎一段就开始造代码,而是在写代码之前需要考虑整个代码框架的设计,模块化设计,让代码显得更加优雅。俗称高内聚,低耦合!
1. 案例介绍
本案例以MCU STM32 作为主控,蜂窝模块作为无线通信模块,采用串口通信。
目标:实现访问HTTP 网络功能;
硬件链接图如下:
从硬件图来说非常简单,Cellular 模块与MCU 通过常用的串口连接,通过AT指令进行交互获取数据;
在没有使用过蜂窝模块的朋友,这里先简单介绍下,蜂窝模块就是常用的上网模块,在嵌入式设备中长如图这样:
常用通信接口:
UART, SPI , 或者其他
通信协议:
大多数都采用AT
2. 系统代码设计
从功能和后期维护来看,考虑到有蜂窝模块硬件通信部分(UART,SPI或者其他),蜂窝控制部分,蜂窝模块的AT命令部分,提供上层网络应用使用部分;
引入中间层接口,统一不同模块的接入,更换其他蜂窝模块非常方便,上层代码结构也不会有很大变化。通过module 底层收发可以设定通信的接口方式,而不绑定到具体接口。
通信部分:
对于蜂窝模块考虑作为一个设备创建,对其通信部分赋予读写接口层,控制赋予相应接口,创建多个指针函数:
typedef struct {
void (*modem_power_up_ptr)();
void (*modem_reset_ptr)();
void (*modem_power_off_ptr)();
uint32_t (*modem_read_ptr)(int32_t fd, uint8_t *buffer, uint32_t length, uint32_t timeout);
uint32_t (*modem_write_ptr)(int32_t fd, const uint8_t *data, uint32_t length);
void (*modem_dtr_ptr)(bool state);
bool (*modem_ri_read)();
void (*modem_wake_up_psm)();
} HalModemOps;
AT部分:
AT指令部分涉及到业务,比如联网,设置制式,发送TCP/UDP,接收TCP/UDP 等等具体接口。但这里需要注意不同的厂家的模块可能存在点点差异,虽然大多都是一样,但总有一些差距。
AT 业务放到中间层上,采用include 到具体模块解决,这样可以灵活切换到其他蜂窝模块。
3. 总结
主要对例子进行一个简单分析,主要对于这些业务和底层进行分层,物理模块进行虚拟化,创建中间层进行隔离,采用函数指针,回调方式,对代码的耦合性大大减小。虽然说这样带来工作量会多一些,但是对于维护应该非常方便。
往期推荐