SPI:Linux驱动模型

Posted

技术标签:

【中文标题】SPI:Linux驱动模型【英文标题】:SPI: Linux driver model 【发布时间】:2013-07-03 20:09:41 【问题描述】:

我是 SPI 新手; Linux 内核提供了一个 API,用于声明 SPI 总线和设备,并根据标准 Linux 驱动程序模型对其进行管理。

你可以在这里找到struct spi_master的描述:https://www.kernel.org/doc/htmldocs/device-drivers/API-struct-spi-master.html

上面链接中的描述说“每个设备都可以配置为使用不同的时钟速率,因为除非选择芯片,否则这些共享信号将被忽略”。把这句话放在比赛中,我不得不说,“设备”是指SPI从设备,而“那些共享信号”是指 MOSI、MISO 和 SCK 信号。

事实上,在 struct spi_device (https://www.kernel.org/doc/htmldocs/device-drivers/API-struct-spi-device.html) 中有一个名为 max_speed_hz 的属性在 struct spi_master 中不存在。所以我可以理解上面陈述的第一部分:“每个设备都可以配置为使用不同的时钟频率”。

但是,第二部分是什么意思? “除非选择芯片,否则这些共享信号将被忽略”是否意味着我可以通过启用/禁用具有不同速率的从机来使用不同的时钟速率,但一次只能使用一个?

感谢您的帮助!问候,

-- 马特奥

【问题讨论】:

是的,但这是因为您一次只想与一台设备通话。每个设备都在总线上“轮到”。每个设备都有自己的一组命令、最大 SCLK 等。因此我们希望一次只启用一个设备。这可能有一些警告,但我认为这通常是正确的。 @rkyser:你为什么说“你一次只想和一台设备通话”?为简单起见,我们假设一个时钟速率。我们来看看typical SPI bus on wikipedia。假设从设备有 8 位数据寄存器,主设备有 24 位数据寄存器。你是说我不允许通过将 SS1、SS2 和 SS3 置零来让所有从机一起工作(假设从机选择为低电平有效)? 我认为这取决于硬件架构。在您给出的示例中,如果主设备正在输出 24 位数据,那么任何从设备如何知道哪些 8 位属于它,因为每个从设备都接收完全相同的位? This architecture 会更适合您所谈论的内容。但是,话又说回来,这真的取决于正在与之交谈的 SPI 设备。我只是根据我有限的经验说的。 【参考方案1】:

@Matteo M.:我认为您实际上不允许同时将 SS1、SS2 和 SS3 设置为零,并以这种方式同时启用所有三个 SPI 从机。原因是 SPI 从机在接收 MOSI 线上的数据时,会同时在 MISO 线上发回数据。如果实际上所有三个从站都将数据放在(共享的)MOSI 线上,那么就数据和电流而言,可能会发生非常糟糕的事情。

【讨论】:

【参考方案2】:

SPI 是一个非常松散的“标准”,没有太多可遵循的规则,这是好的(我猜也是坏的)。这很好,因为它很灵活。这很糟糕,因为它可以根据您正在处理的特定硬件以不同的方式实现。一些设备仅支持半双工通信,如您所知,这需要协调何时可以驱动总线。选择线(芯片使能、从机选择,无论您想如何称呼它们)提供了一种方便的方法来执行此操作,而无需使用位来识别哪个从机应该从总线上获取消息。

在全双工模式下,数据在每个时钟脉冲上从主设备和从设备拖放到总线上,正如 Wolfgang 所说,可能非常需要选择线来防止出现不良情况。我想强调可能是必需的;让主处理器与仅在响应某些特定位模式(例如“地址”)时驱动总线的其他处理器通信是完全合理的......更多软件/固件?是的,但这并不能阻止你。

因此,如果说您的 8 位从机,例如 8 位 DAC,您确实可以写入主数据寄存器的值块。独立的选择线将使您能够做到这一点,而无需所有这些从设备同时驱动总线。是的,您必须一次将每个从属寄存器中的值转移到主寄存器中,但这也是一个完全合理的设计。

与一些更复杂的串行协议不同,SPI 实际上非常灵活;因为它不会将您锁定在最大字长或要求您写入总线的任何数据由地址和偏移量之类的东西组成。

【讨论】:

以上是关于SPI:Linux驱动模型的主要内容,如果未能解决你的问题,请参考以下文章

总线模型与spi驱动模型

Linux SPI总线和设备驱动架构之二:SPI通用接口层

Linux驱动开发SPI

Linux驱动开发SPI

Linux驱动开发SPI

Linux——Linux驱动之玩转SPI(上)Linux下SPI驱动框架简析及SPI设备驱动代码框架实现步骤