embedded - 通过 SPI 的芯片到芯片通信协议(protocol)

标签 embedded spi lwip

我正在尝试通过 SPI 在一侧的微 Controller 和另一侧的多核 TI 芯片上的 ARM 处理器之间设计一种有效的通信协议(protocol)。

所需协议(protocol)的要求:

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

2 - 通过 SPI 作为底层协议(protocol)工作。

3 - 简单的错误检查。

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

我还发现了具有 PPP over serial 的轻量级 IP (LwIP) 项目(我假设我可以通过 SPI 使用它),所以我考虑了利用 TCP/UDP 等任何上层协议(protocol)来完成其余部分的可能性所需的工作。幸运的是,我发现 TI 将 LwIP 作为其以太网软件的一部分包含在 starterware 包中,我认为这至少可以简化 TI 芯片方面的移植。

所以,我的问题是:

1 - 在这种通信方案中使用 LwIP 是否有效?由于点对点(芯片级)通信不需要的 IP header ,这不会引入太多开销并杀死吞吐量吗?

2 - 驻留在 LwIP 中的 TCP 或任何类似协议(protocol)是否会处理传输请求的排队,例如,如果我在通信 channel 忙于发送/接收另一个线程的另一个套接字( session )的请求时通过套接字请求传输,这会由协议(protocol)栈管理?如果是这样,哪个协议(protocol)层管理它?

3 - 它们是比 LwIP 更有效的协议(protocol)栈,满足上述要求吗?

更新 1:要考虑的更多要点

1 - SPI 是唯一可用的选项,我将它与可用的 GPIO 一起使用,以便在从机有数据要发送时向主机指示。

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

3- 对这一点的改进是使用一种邮箱来接收碎片,因此长消息可以被更高优先级的消息打断,这样单个消息的碎片可以非顺序到达,但问题是这种设计导致使事情复杂化,特别是我没有太多可用资源供许多缓冲区使用 Controller (主)端的邮箱方法。所以我认为这就像我通过为可能效率不高的简单点对点链接设计一个协议(protocol)栈来重新发明轮子一样。

4- SPI之上一般可以使用什么样的更高级的协议(protocol)来建立多个 session 并解决消息的排队/调度?

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

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

对于预期目的,您认为这会比 LwIP 更好吗?此外,是否有像 LwIP 这样广泛使用的开源实现,但适用于 Modbus?

最佳答案

我认为也许您对不起眼的 SPI 期望过高。

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

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

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

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

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

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

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

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

关于embedded - 通过 SPI 的芯片到芯片通信协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18987440/

相关文章:

无法使用 lwIP 原始 TCP 连接接收对 HTTP 请求的多个响应

c - 如何使我的代码独立于 "RTOS"?

c - 如何在 C 中刷新 UDP 套接字的输入缓冲区?

android - Android 如何解释 SPI 接收到的输入

c - stm32 SPI+DMA

linux - Bit Bang with SPI(fwirte,写入性能)

ssl - 如何在 tls 中使用 STM32 lwip/mqtt api?

c - 函数指针在未被调用的情况下转换为 void

c++ - 没有全局运营商的裸机新

c - 在嵌入式 C 中处理小数