我已经为SPI设备构建了一个linux驱动程序。当准备读取新数据时,SPI设备向处理器发送IRQ。
IRQ大约每3毫秒触发一次,然后驱动程序用SPI读取2个字节。
我的问题是,有时,IRQ被触发和SPI传输开始的那一刻之间有超过6 ms,这意味着我丢失了2字节的SPI设备。
另外,这两个字节之间有一个不确定的延迟;有时接近0,有时达到300‘s。
那么我的问题是:如何减少IRQ和SPI读数之间的延迟?
以及如何避免两个字节之间的延迟?
我尝试过用premptive选项编译内核,但它并没有改变那么多。
至于硬件,我使用的是运行在400 MHz的mini2440板,使用的是硬件SPI端口(而不是i/o模拟SPI)。
谢谢你帮忙。
比尔文森特。
发布于 2014-08-27 15:25:56
问题是Linux堆栈使用队列来传输消息。
这意味着您请求发送SPI消息的时刻与有效发送SPI消息的时刻之间的延迟无法保证。
最后,为了满足每个SPI消息之间的3ms需求,我不得不停止使用Linux堆栈,直接写入我自己的IRQ内部的CPU寄存器。
这是非常肮脏的,但这是唯一的办法,使它的工作与小的延迟。
发布于 2014-08-24 06:43:19
从三星S3C2440A CPU手册中,SPI接口硬件支持中断和基于DMA的操作.查看一下实际数据表,就会发现硬件也支持轮询模式。
如果您想要可靠地实现高数据速率,则需要基于DMA的方法。一旦配置了DMA操作,硬件就会自行将数据移动到RAM中,而无需进行低延迟中断处理。
也就是说,我不知道您的CPU的Linux驱动程序的状态。这可能是缺少对DMA的支持、特定的系统设置,甚至是您如何从自己的代码中使用驱动程序的问题。详情请看。SPI通常高度依赖于特定的实现..。
发布于 2022-06-13 18:38:26
我有一个类似的问题,:我基本上得到了一个IRQ,需要在不到10 ms的时间内通过SPI排出一个队列,否则芯片就会开始丢弃数据。在系统负载较高的情况下(ssh登录实际上已经足够了),有时IRQ处理程序在使用spi_async
排队进行下一次SPI传输和SPI传输之间的延迟实际上超过11 ms。
我发现的解决方案是struct spi_device
中的rt
标志(参见这里)。启用这将将控制SPI的线程设置为实时优先级,这使得所有SPI传输的时间都非常可靠。顺便说一句,这种更改还消除了complete
回调之前的延迟。
正如提醒一下,我认为这在早期内核版本中是不可用的。
https://stackoverflow.com/questions/25462568
复制相似问题