第三章:技术选型与架构设计
技术选型和架构设计,说白了就是给产品搭骨架。骨架搭歪了,后面再怎么填肉都别扭。我见过太多项目,前期图省事随便选个方案,结果量产时发现成本压不下来,或者性能死活提不上去。嗯,这一章咱们就聊聊怎么把这事儿做扎实。
3.1 技术栈评估:别只看参数
选技术栈,很多人第一反应是看参数。主频多高、内存多大、功耗多低。但我告诉你,参数只是入场券。真正决定成败的,是生态和坑。
我个人习惯,评估一个技术方案会从四个维度打分:
- 成熟度:这方案在市场上跑了多久?有没有大规模量产案例?
- 供应链:芯片好不好买?交期稳不稳?有没有第二供应商?
- 开发效率:SDK 完善吗?文档全不全?社区活跃吗?
- 成本结构:BOM 成本只是开始,还要算上开发成本、测试成本、维护成本。
核心原则:选技术栈不是选最强的,而是选最合适的。你的团队擅长什么?你的产品生命周期多长?这些比参数重要得多。
我在项目中遇到过一件事。有个智能家居项目,团队选了最新款的 Wi-Fi 芯片,参数漂亮得不行。结果开发到一半发现,这芯片的蓝牙协议栈有 bug,连手机死活连不上。等官方修 bug 等了三个月,项目直接延期。你想想看,要是当初选个成熟方案,哪怕参数差一点,也不至于这样。
3.2 系统架构设计:分层与解耦
架构设计,我建议你记住四个字:高内聚,低耦合。说白了,就是每个模块只管自己的事,别越界。
一个典型的嵌入式系统架构,我会分成这几层:
- 硬件抽象层(HAL):把芯片厂商的驱动包一层,方便以后换芯片。
- 中间件层:协议栈、文件系统、RTOS 这些。
- 应用层:业务逻辑,比如传感器数据处理、UI 交互。
- 接口层:对外通信接口,比如 MQTT、HTTP、BLE。
为什么要分层?举个例子。你产品卖得好,想换个更便宜的芯片。如果 HAL 层封装得好,你只需要改底层驱动,应用层代码几乎不用动。反之,如果所有代码揉在一起,换芯片等于重写整个项目。我曾经见过一个团队,因为没做分层,换芯片花了半年时间,比重新开发还慢。
小技巧:架构设计时,先画数据流图。数据从传感器进来,经过哪些处理,最后怎么输出。把数据流理清了,模块划分自然就出来了。
3.3 模块划分:别贪大求全
模块划分,最容易犯的错就是「大而全」。恨不得一个模块搞定所有功能。结果呢?代码耦合严重,改一个功能影响一片。
我建议按功能域来划分:
- 感知模块:负责采集数据,比如温度、湿度、加速度。
- 处理模块:负责数据计算、逻辑判断。
- 通信模块:负责数据收发,比如 Wi-Fi、BLE、4G。
- 存储模块:负责数据持久化,比如 Flash、SD 卡。
- 电源管理模块:负责功耗控制,比如休眠、唤醒、电压调节。
每个模块都要有清晰的输入输出接口。模块之间通过消息队列或者回调函数通信,不要直接调用对方的函数。这样做的好处是,以后想升级某个模块,只要接口不变,其他模块完全不受影响。
注意:模块划分不是越细越好。太细了,模块间通信开销大,代码反而变复杂。一般一个模块的代码量控制在 1000-3000 行比较合适。
3.4 接口定义:先定协议再写代码
接口定义,是架构设计里最容易被忽视的一环。很多人上来就写代码,写到一半发现两个模块对不上,再回头改。浪费时间不说,还容易引入 bug。
我的做法是:先定义接口文档,再写代码。接口文档要包含:
- 函数原型:函数名、参数、返回值。
- 数据结构:结构体定义、枚举值。
- 通信协议:数据帧格式、命令码、校验方式。
- 错误码定义:每个错误码的含义。
举个例子,一个传感器模块的接口定义:
/* 传感器数据结构 */
typedef struct {
float temperature; /* 温度,单位:摄氏度 */
float humidity; /* 湿度,单位:百分比 */
uint8_t status; /* 状态:0-正常,1-异常 */
} sensor_data_t;
/* 传感器初始化 */
int sensor_init(void);
/* 读取传感器数据 */
int sensor_read(sensor_data_t *data);
/* 错误码定义 */
#define SENSOR_OK 0
#define SENSOR_ERR_INIT -1 /* 初始化失败 */
#define SENSOR_ERR_BUS -2 /* 总线通信错误 */
#define SENSOR_ERR_DATA -3 /* 数据异常 */
接口定义好了,不同模块的开发者就可以并行开发了。A 模块的人按接口写调用代码,B 模块的人按接口写实现代码。最后联调时,只要接口一致,基本不会出大问题。
避坑指南:我曾经因为接口定义不严谨,吃过一次大亏。有个项目,两个模块的开发者对「数据有效位」的理解不一样。一个认为是 8 位,一个认为是 16 位。结果联调时数据全是乱的。后来我定了个规矩:所有接口定义必须经过评审,双方签字确认。
3.5 技术选型与架构设计的常见误区
最后,总结几个我踩过的坑:
- 过度设计:产品还没量产,就想着以后要扩展多少功能。结果架构搞得特别复杂,开发周期拉长,成本上升。记住:够用就好,别为未来不确定的需求买单。
- 忽视测试性:架构设计时没考虑怎么测试。结果产品做出来了,测试人员不知道怎么测。我建议在架构里预留测试接口,比如日志输出、状态查询、模拟输入。
- 文档缺失:架构设计完了,文档不写。等过几个月自己都忘了当初为什么这么设计。别偷懒,文档是给未来的自己看的。
嗯,这一章的内容就这些。技术选型和架构设计,说白了就是「想清楚再动手」。别急着写代码,先把骨架搭稳了。下一章咱们聊聊硬件设计,那又是另一番天地了。
课后思考:你现在做的产品,如果换一个主控芯片,需要改多少代码?如果改的地方很多,说明架构设计还有优化空间。