通过SPI进行芯片间通信协议

11

我正在设计一种高效的通信协议,用于在一侧使用微控制器和另一侧使用多核TI芯片上的ARM处理器之间通过SPI进行通信。

所需协议的要求:

1- 支持多会话和队列,因为我有多个发送/接收线程,所以将有多个应用程序使用该通信协议,我需要协议来处理这些请求的排队(如果传输排队,则将保持缓冲区,但我只需要协议来管理调度队列)。

2- 作为底层协议在SPI上工作。

3- 简单的错误检查。

在这个线程中:“Simple serial point-to-point communication protocol”,PPP是一个推荐选项,但我发现PPP只完成了其中的一部分工作。

我还找到了轻量级IP(LwIP)项目,其中包括串口PPP(我假设可以在SPI上使用它),因此我考虑利用TCP / UDP等上层协议来完成其余所需的工作。幸运的是,我发现TI将LwIP包含在其起动程序软件包的以太网SW中,我认为这至少可以简化在TI芯片端的移植。

所以,我的问题是:

1- 在此通信方案中使用LwIP是否有效?这是否会由于不必要的IP头造成过多开销(在芯片级别上是点到点的通信),从而降低吞吐量?

2- LwIP中的TCP或类似协议是否会处理传输请求的排队,例如,如果我通过套接字请求传输,而通信通道正忙于传输/接收其他线程的另一个套接字(会话),则协议堆栈是否会管理它?如果是这样,哪个协议层进行管理?

3- 是否有比LwIP更有效率的协议栈,满足上述要求?

更新1:需要考虑更多因素

1- SPI是唯一可用的选项,我将其与可用的GPIO一起使用,以指示从设备何时发送数据给主设备。

2- 目前实现的(非标准)协议使用带SPI的DMA,消息格式为《STX_MsgID_length_payload_ETX》,具有固定的消息片段长度,但当前模式的主要缺点是主机在发送另一个消息(而不是片段)之前等待消息的响应,这会降低吞吐量并且不能充分利用SPI的全双工特性。

3- 对此改进的方法是使用一种接收片段的邮箱,因此长消息可以被高优先级的消息中断,以便单个消息的片段可以非顺序地到达,但问题是这种设计会复杂化事情,尤其是我在控制器(主机)端没有太多可用资源来使用邮箱方法。所以我认为,为一个简单的点对点链接设计协议栈就像重新发明轮子,可能不是高效的做法。

4- 在SPI上方通常可以使用什么样的更高级别协议来建立多个会话并解决消息排队/调度的问题?

更新2:另一个有用的主题:“A good serial communications protocol/stack for embedded devices?"

更新3: 我看了看Modbus协议,它似乎指定了适用于串行线通信的应用层,然后直接指定了数据链路层,这听起来跳过了网络导向协议层的不必要开销。

您认为这将比LwIP更好地实现预期目的吗?此外,是否有像LwIP一样广泛使用的Modbus开源实现?


spi是主从而不是双向的。如果你想使用lwip或其他协议,你可能需要使用串行/UART而非spi。lwip会有很多开销,你也许可以自己动手实现。 - old_timer
@dwelch - USB也是主/从关系,但通过定期轮询从设备可以轻松解决这个问题。 - Chris Stratton
1
不幸的是,SPI是可用选项,我已经与另一个GPIO一起使用它来指示从设备何时有可用数据发送给主设备。 - Wessam
Chris,我理解你的意思,但是也要明白USB就是为此而设计的,很多轮询操作都是由硬件完成的,不一定需要软件一直进行。 - old_timer
当然,在软件中进行轮询是一种轻微的低效率,但看起来OP已经实现了硬件注意信号,所以这不会成为问题。 - Chris Stratton
2个回答

4
我认为您可能对谦卑的SPI期望过高了。
SPI连接只是一对移位寄存器,每个节点都有一个。主节点选择单个节点连接到其SPI移位寄存器。当主节点输入数据时,从节点同时输出数据。除非主节点明确地将数据时钟输出,否则不会交换数据。在SPI上高效的协议需要从节点在主节点输入数据时输出有用的数据。这可能很难安排,因此通常需要一种指示空数据的方法。
PPP在建立两个任意端点之间的连接时非常有用,当端点是固定和已知的时候,PPP除了不必要地复杂化问题外没有任何作用。
SPI接口不是非常复杂也不是非常灵活,可能不适合TCP/IP等重量级通用协议。由于SPI上的“寻址”是通过物理芯片选择执行的,因此此类协议中的寻址是无意义的。
流控制也是SPI的一个问题。主节点无法确定从节点是否在推送更多数据之前从SPI移位寄存器中复制了数据。如果从节点SPI支持DMA,则最好使用它。
无论哪种方式,我建议您开发专门用于您的目的的内容。由于SPI本质上不是网络,因此您只需要一种方法来寻址所选节点上的线程。这可以简单地表示为STX<线程ID><长度><有效载荷>ETX添加于2013年9月27日,以回应评论 通常情况下,SPI如其名称所示用于连接外围设备,在这种情况下,协议由外围设备定义。例如,EEPROM通常使用跨供应商的公共或至少兼容的命令接口,而SD/MMC卡SPI接口使用标准化的命令测试和协议。
在两个微控制器之间,我想大多数实现都是专有的和特定于应用程序的。开放协议旨在实现通用互操作性,为此可能会对封闭系统施加重大且不必要的开销,除非节点正在运行已经构建了网络堆栈的系统。
我建议如果您确实想使用通用网络堆栈,则应在每个端点上使用设备驱动程序抽象SPI,为SPI提供标准I/O流接口(例如open()、close()、read()、write()等),然后可以使用更高级别的PPP和TCP/IP协议(虽然可能可以避免PPP,因为连接是永久的)。但是,只有在两个节点已经支持这些协议(例如运行Linux)时,这才具有吸引力。否则,将为获得很少的好处而付出显着的努力和代码,并且肯定不会“高效”。

1
这些观点(除了可能的最终吞吐量)大多也适用于USB,然而在外部网络适配器上运行网络协议被认为是完全合理的,即使在12MB/s USB时代,SPI也可以通过适当的关注匹配。使用SPI也可以采用相同的解决方法,例如主节点定期轮询从节点。 - Chris Stratton
1
@ChrisStratton:的确如此,但对于所描述的应用程序来说,这或许并不值得花费那么多精力。USB比SPI复杂得多,定义了硬件、互联、软件堆栈和设备配置文件。SPI没有定义任何东西,并且SPI控制器要原始得多,事实上可以使用GPIO和软件实现SPI。使用USB的回报是能够连接到第三方设备;而使用SPI,诸如SD/MMC卡和EEPROM之类的第三方设备使用的协议要简单得多。 - Clifford
感谢您的回答和评论,您的意思是ppp执行了spi已经处理的工作,因为连接已经建立了吗?请参考编辑后的问题,其中包含与您的答案相关的一些补充说明。 - Wessam
@ChrisStratton:我从未听说过有人实现基于位的 USB,如果成功甚至符合 USB-IF 标准,我会感到惊讶。基于位的 SPI 是很常见的。 - Clifford
@Wessam:我是说PPP执行的任务与已知且永远不会改变的设备之间的固定/永久连接无关。SPI不会“处理”连接的建立,因为连接始终存在。 - Clifford
显示剩余5条评论

1
我假设您并不需要或没有足够的空间在微控制器上使用完整的IP(lwip)堆栈?这听起来有点过度。为什么不自己编写简单的数据包结构来传输所需的数据项。根据SPI在两侧的支持情况,您可以或者不能使用它来定义数据帧,如果不能,则一个简单的起始模式、长度和尾随校验和以及可能的尾部模式就足以在流中找到数据包边界(与串行/UART解决方案没有区别)。您甚至可以使用PPP解决方案,在负载中使用两个字节模式,每当起始模式出现在数据中时,即可使用起始模式和结束模式。
无论您的帧是什么,都要添加数据包类型和握手,或者如果数据只是从微控制器到Arm,则甚至不需要这样做。

回到你的直接问题,我认为使用ip协议栈(如lwip或其他)会引入很多开销。带宽和更重要的是需要支持该协议栈的代码量将占用双方的rom/ram。如果你最终需要以ip方式呈现此数据(嵌入式系统托管的网站),那么在路径的某个位置上,你需要一个ip协议栈等。

我无法想象lwip会为您管理队列。 我认为您需要自己处理。各种队列可能需要与处理单个spi总线的单个驱动程序进行通信(假设有多个片选)。 这还取决于您如何使用spi接口,如果允许arm与多个微控制器通信,并且数据包从这个控制器中的一小部分和那个控制器中的另一小部分中分解出来,以便在它们获得更多字节的数据之前不必等待太长时间。或者完整的帧是否必须从一个微控制器移动到下一个gpio中断,然后再移动到下一个控制器以获取该控制器的数据?重要的是,我认为您必须像在任何其他具有共享资源的情况下一样管理共享资源(rtos,完整的操作系统等)。 我对lwip的记忆不好,但是使用完整的伯克利套接字应用程序界面,用户可以编写单独的应用程序,每个应用程序只关心一个TCP或UDP端口,库和驱动程序也将这些数据包分开发送给每个应用程序,并负责处理IP堆栈的所有规则。

如果您还没有开始使用spi接口移动数据进行实验,我建议先从简单的实验开始,以便了解它的工作效果和可靠性,例如每个spi传输可以可靠地传输的数据大小等。您的解决方案可能会自然而然地从这些实验中浮现出来。

感谢您详细的回答,实际上在第2点提到的当前实现方案已经可以正常工作,但存在半双工和单消息响应阻塞的缺点。这就是为什么我正在寻找通常在SPI上使用的标准堆栈,甚至以标准方式实现它,而不是重新设计可能引入缺点的新方案。 - Wessam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接