如何从C中的串行(SPI)连接读取数据?
我正在尝试编写一个程序,该程序将安装在Linux MCU(Raspberry Pi)上,该程序将读取从另一个MCU(我将自己构建的本地产品)的串行数据。
我已经研究过如何做到这一点,并认为我有“大局”,但仍然缺少一些东西。 首先,我需要启用内核模块并让自己访问设备:
sudo modprobe spi_bcm2708 sudo chown `id -u`.`id -g` /dev/spidev0.*
从那里我可以使用这个着名的C文件来测试SPI连接。
所以现在连接就在那里,但我仍然需要从中读取串行数据。 根据这个问题的答案,我只需要:
…打开相关端口进行读取,并使用
read()
获取数据。
然而,该答案中的代码片段似乎是通过设备驱动程序而不是通过SPI打开端口。
我的理解是我可以使用SPI从连接的MCU设备读取数据,并且我不需要为该设备编写自己的设备驱动程序。 这是真的? 如果是这样,我将如何从SPI连接中读取,以及该代码与上面链接的问题的答案中的代码有何不同?
如果我的理解不正确,并且我确实阅读了“通过”设备驱动程序,为什么我首先需要驱动程序? 这不是SPI希望绕过的吗? 提前致谢。
我正在尝试编写一个程序,该程序将安装在Linux MCU(Raspberry Pi)上,该程序将读取从另一个MCU(我将自己构建的本地产品)的串行数据。
[ MCU不适合使用。 Raspberry Pi使用SoC(片上系统)。 微控制器将是比SoC更便宜和更简单的设备。 如果你想使用TLA,那就使用SBC,单板计算机。]
[您滥用术语“串行端口”和“串行数据”。 今天,由于PC无处不在,“串口”已经专门用于指EIA / RS-232异步串行连接。 SPI。 USB。 I2C,TWI,SATA 等不应被称为“串行”连接,除非您要解释它们的工作原理。
在Linux中,SPI设备驱动程序通常实现为*平台驱动程序而不是字符驱动程序 。因此,这样的驱动程序不会执行文件操作或fops来执行open() , read() , write()或close(这种操作适用于平台设备连接到系统的目标设备。因此,平台设备在/dev
像目标设备那样的设备节点.SPI与USB和PCI属于同一类别;它们是所有总线,通常作为平台驱动程序实现。
我的理解是我可以使用SPI从连接的MCU设备读取数据,并且我不需要为该设备编写自己的设备驱动程序。 这是真的?
答案取决于您使用的内核是否为您的用户程序公开了一个SPI char设备。 但如果SPI驱动程序是平台驱动程序,则必须实现自定义SBC的设备驱动程序。 此目标设备需要/dev
的节点,分配的主要和次要编号以及与这些编号关联的驱动程序。 该驱动程序将利用SPI驱动程序提供的平台操作或使用Linux SPI API执行传输。 SPI及其驱动程序仅仅是用于在此处理器和目标设备之间传输数据的管道。 对于SATA和PCI,用户很少知道将外围设备连接到计算机的这些(内部)总线。
linux/drivers/spi/spi_bcm2708.c
是一个平台驱动程序。 它没有支持/执行open() , read() , write()或close()操作的fops 。 它将自身注册为SPI主控制器,因此其他(目标)驱动程序可以将SPI API用于其服务。
IMO你最好在RPI和你的自定义SBC之间实现EIA / RS-232链接。 如果使用非规范(原始)传输,那么如果/当您转换/升级到SPI连接时,您编写的代码中可能有99%将是可重用的。 没有流量控制的3线串行连接类似于SPI连接,但没有施加主/从层次结构,更简单的HW接口和更长的电缆长度。
请注意,使用您安装的任何电缆,您可能无法通过长SPI距离实现快速传输速率。 SPI的10 Mbps速率通常在具有接地层和短迹线的多层板上实现。
在Unix上,一切都是文件
如果正确安装了spi_bcm2708
驱动程序,则应该有/dev/whatever
该设备的/dev/whatever
文件(或者用于以不同方式访问设备的几个文件)。
如果没有自动创建,您可以使用mknod创建一个条目
用户空间代码只需打开/dev/whatever
文件,就好像它是任何其他常规文件一样,并从中读取/写入数据。 这就是Unix的重点。
编辑:这正是链接问题中的代码正在做的事情,它将终端/dev/ttyS0
打开为带有open()和读/写的文件。
您是否找到了SPI的Linux文档 ?
有几个好文档:spi-summary和spidev。
文件spidev_fdx.c中也有示例,其中read()
用于SPI设备。
但通常从SPI读取由ioctl()
函数处理。