Linux与采集MCU通信为什么我们用了双SPI

工程师实战分享|基于米尔电子 T113i 核心板

| 最近在做一套电能质量监测设备。整个系统没有采用"一个处理器全部搞定"的方式,而是用了两个处理器分工:GF32H737 负责电压、电流 ADC 采集以及 DI/DO 控制,米尔 T113i 核心板负责 Linux 系统、显示、存储以及网络通信。 两个处理器之间通过 SPI 通信。不过跟大家平时常见的设计稍微有一点不同:我们用了两路 SPI。一路主要传采集数据,一路负责配置和控制。 有人可能会问:两个处理器之间通信,一路 SPI 不就够了吗?为什么还要多占一路接口?最后选择双 SPI,不是因为单 SPI 实现不了,而是从整个系统后面的维护、通信逻辑和稳定性来看,我们觉得把两类数据拆开更舒服。 |

先说为什么要做"MCU + Linux"

电能质量监测设备有一个比较明显的特点:前端采集有实时性要求,但后面的功能却越来越复杂。比如我们的设备除了采电压、电流,还需要触摸屏显示、参数配置、TF 卡本地存储、千兆网络、PTP 时间同步、第二路网络接口、数据上传和后续协议扩展。

如果全部塞给 MCU,并不是完全做不了。现在高性能 MCU 的算力已经很强,RTOS 也越来越成熟。但工程上"能做"是一回事,"做起来是否合适"又是另一回事。尤其后面涉及网络协议、文件系统、图形界面、远程维护之后,整个 MCU 软件会越来越重。

所以我们的思路比较直接:**实时采集让MCU负责,复杂系统功能交给Linux。**这样 GF32H737 的任务相对稳定:把电压、电流采好,把 DI/DO 控制做好;T113i 则负责把采集数据拿过来,显示、存储,再通过网络发出去。

SPI是一个比较自然的选择

对于板内两个处理器之间的数据通信,SPI 的优点比较明显:接口简单,速度也比较合适。特别是在采集类设备里,数据是持续产生的,主控需要周期性获取 MCU 侧的采样结果。相比一些低速接口,SPI 更适合承担这样的数据传输任务。

但在具体定义通信协议的时候,我们发现通信内容其实可以明显分成两类。第一类是数据 ,例如 MCU 不断采集出来的电压、电流数据;第二类是控制,比如采集参数配置、工作模式切换、某些控制指令、状态读取和参数更新。这两类数据虽然都发生在 T113i 和 MCU 之间,但它们的特点并不一样。

采集数据和控制命令,本质上是两种业务

采集数据通常是连续的。只要设备运行,MCU 就一直在产生数据,T113i 需要持续或者周期性地把数据读走。这个通道比较看重的是:连续性和传输效率。

控制命令则不同。它通常不是一直产生,而是在用户修改参数、系统切换状态或者需要执行某个控制操作时才发生。它更看重的是:指令响应和逻辑清晰。

如果全部塞在一路 SPI 里,当然也能解决。比如自己定义协议,用不同帧类型表示采集数据、配置和控制,然后在软件里面再做队列、优先级和状态机。问题是,随着项目功能越来越多,这一路通信协议也会越来越复杂。尤其是采集数据持续传输的同时,如果系统突然要下发配置命令,就要额外考虑当前一帧数据传到哪里、控制命令什么时候插进去、异常恢复时怎么判断当前状态,以及控制指令是否需要更高优先级。

协议不是不能写,而是越来越容易把两个本来可以相对独立的问题绑在一起。

所以我们干脆把它拆成两路

最终我们的方案是:一路SPI主要负责采集数据,另外一路SPI主要负责参数和控制。

这样做之后,我自己在写软件的时候最大的感觉就是:**逻辑干净很多。**数据通道只关心数据,控制通道只关心控制。比如 T113i 需要连续读取电压、电流采样数据时,数据 SPI 正常工作;这时候用户在触摸屏上修改了某个采集参数,就可以通过另外一路 SPI 下发,不需要和当前采集数据争同一个通信过程。

从程序结构上来说,也更容易把两部分做成相对独立的模块。后面调试的时候,问题定位也比较直观:如果是采集数据异常,就看数据链路;如果是参数配置异常,就看控制链路。

双SPI的价值不在"速度翻倍"

我们采用双 SPI,核心目的并不是宣传"两路一起跑,带宽就翻倍"。如果只是追求总带宽,其实还有很多其它办法。双 SPI 对这个项目更大的价值是:业务解耦。

这和软件里面把不同功能拆成不同线程、不同服务,其实有一点类似。当硬件资源允许,而且数据业务和控制业务特征差异比较明显时,把两条链路分开,能够降低后续系统复杂度。

当然,这并不意味着所有项目都应该用双 SPI。如果 MCU 和 Linux 之间数据量很小,控制命令也很少,那么一路 SPI 加一个设计合理的协议完全够用。多一路接口意味着 PCB 需要更多走线、占用更多 SoC 和 MCU 引脚、软件需要维护两个 SPI 设备,硬件设计也稍微复杂一点。工程设计没有绝对最优,只有是否适合当前项目。

Linux侧的SPI适配也很关键

硬件连好只是第一步。T113i 运行的是 Tina Linux,所以两路 SPI 最终还需要在 Linux 里面正确配置,包括 SPI 控制器启用、引脚复用、设备树节点、时钟频率、片选、工作模式,以及用户空间或者驱动层的数据交互。

项目里我们也针对 T113i 的 SPI 设备树进行了对应配置和调试。这一块我觉得是 Linux 核心板项目里面一个很典型的问题:很多接口硬件上明明有,但真正使用时必须把设备树、驱动和应用层全部串起来。

所以我现在选核心板时,不会只数产品手册上有几个 SPI、几个 UART。我更关心的是:这些接口在现有 BSP 里面好不好用?设备树有没有成熟配置方式?遇到问题有没有人帮忙一起定位?从项目推进角度看,这些东西往往比"理论接口数量"更重要。

做完这个项目以后,我对双处理器架构有了一个更明确的认识

以前看"MCU + Linux"方案,容易觉得是不是把系统做复杂了。毕竟从一个处理器变成两个处理器,中间还多了一套通信。但这次项目真正做下来以后,我觉得关键还是看怎么分工。

如果让两个处理器互相承担一堆重叠任务,系统确实容易复杂。但如果边界划清楚:**MCU专心实时采集,Linux专心系统管理。**中间再通过一套清晰稳定的通信接口连接起来,反而更容易维护。

尤其像电力监测、工业采集、数据网关这一类设备,产品一旦进入后续迭代阶段,Linux 侧通常会不断增加网络协议、数据处理和交互功能,而底层采集 MCU 可以尽量保持稳定。这也是我们这次选择 T113i + GF32H737,并进一步使用双 SPI 拆分数据和控制通道的主要原因。

如果大家也在做类似的双处理器工业设备,我觉得可以考虑一个问题:**你现在的一路通信接口里,到底承载了多少种完全不同的业务?**有时候优化协议是一种办法;有时候,把本来就不同的事情拆开,反而更简单。

相关推荐
草莓熊Lotso1 小时前
【Redis 初阶】特殊数据类型、渐进式遍历与数据库操作生产指南
linux·网络·数据库·redis·tcp/ip·缓存·bootstrap
λqaq71 小时前
Redis 数据库基础:安装、5 大核心数据类型与常用命令
linux·数据库·redis·python·缓存
CS_Zero1 小时前
Ubuntu 22.04挂载新硬盘
linux·运维·ubuntu
oushaojun21 小时前
深入 Linux 动态链接:so 库构建与运行逻辑(转)
linux
嵌入式阿蔡1 小时前
云平台设备接入实战:三元组鉴权、属性上报与命令下发(阿里云/华为云)
嵌入式硬件·物联网·嵌入式·存储
liuguomark1 小时前
TMC5160使用问题2
嵌入式硬件·tmc5160
三佛科技-187366133972 小时前
MT8F82XX系列MCU型号选型指南:兼容替代型号全梳理
单片机·嵌入式硬件
好评1242 小时前
【Linux】应用层自定义协议与序列化
linux·运维·网络
赴生-2 小时前
Lunix 操作系统 基本指令(一)
linux