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

所需协议(protocol)的要求:

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

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

3 - 简单的错误检查。

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

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

所以,我的问题是:

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

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

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

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

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

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

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

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

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

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

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

最佳答案

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

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

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

SPI 不是一个非常复杂也不灵活的接口(interface),可能不适合重量级的通用协议(protocol),如 TCP/IP。由于 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/

10-16 06:52