通过SPI实现芯片到芯片的通信协议

Wes*_*sam 10 embedded spi lwip

我试图通过SPI在一侧的微控制器和另一侧的多核TI芯片上的ARM处理器之间设计有效的通信协议.

所需协议的要求:

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

2 - 通过SPI作为底层协议.

3 - 简单的错误检查.

在这个线程:" 简单的串行点对点通信协议 ",PPP是一个推荐的选项,但我看到PPP只做部分工作.

我还发现轻量级IP(LwIP)项目采用PPP over serial(我假设我可以通过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:另一个有用的线程" 嵌入式设备的良好串行通信协议/堆栈? "

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

你认为这对于预期目的来说是比LwIP更好的选择吗?另外,有一个广泛使用的开源实现,如LwIP,但对于Modbus?

Cli*_*ord 4

我想也许你对不起眼的 SPI 期望太高了。

SPI 链路只不过是一对移位寄存器,每个节点各有一个。主机选择单个节点连接到其 SPI 移位寄存器。当从设备移入数据时,它同时将数据移出。除非主设备明确输出数据,否则不会交换数据。SPI 上的高效协议涉及从机在主机输入时输出有用的内容。这可能很难安排,因此您通常需要一种指示空数据的方法。

当在两个任意端点之间建立连接时,PPP 很有用,当端点是固定的并且先验已知时,PPP 除了使事情变得不必要地复杂化之外没有其他任何用途。

SPI 不是一个非常复杂和灵活的接口,可能不适合 TCP/IP 等重量级通用协议。由于 SPI 上的“寻址”是通过物理片选来执行的,因此此类协议中固有的寻址是没有意义的。

流量控制也是 SPI 的一个问题。在推送更多数据之前,主设备无法确定从设备是否已将数据从 SPI 复制到移位寄存器。如果您的从机 SPI 支持 DMA,那么您最好使用它。

无论哪种方式,我建议您开发一些特定于您的目的的东西。由于 SPI 本身并不是一个网络,因此您只需要一种方法来寻址所选节点上的线程。这可以像这样简单STX<thread ID><length><payload>ETX

添加于 2013 年 9 月 27 日以回应评论 一般而言,SPI 顾名思义用于连接到外围设备,在这种情况下,协议由外围设备定义。例如,EEPROM 通常使用跨供应商的通用或至少兼容的命令接口,而 SD/MMC 卡 SPI 接口则使用标准化命令测试和协议。

在两个微控制器之间,我认为大多数实现都是专有的和特定于应用程序的。开放协议是为通用互操作性而设计的,并且为了实现这一点可能会给封闭系统带来大量不必要的开销,除非节点运行的系统可能已经内置了网络堆栈。

我建议,如果您确实想使用通用网络堆栈,则应该在每一端使用设备驱动程序抽象 SPI,为 SPI 提供标准 I/O 流接口(open()、close()、read()、 write() 等),那么您可以使用更高级别的 PPP 和 TCP/IP 协议(​​尽管可能可以避免 PPP,因为连接是永久的)。然而,只有当两个节点都已经支持这些协议(例如运行 Linux)时,这才具有吸引力,否则,这将是大量的工作和代码,但收效甚微,而且肯定不会“高效”。