1

我正在尝试编写一个程序,该程序将安装在 Linux MCU(Raspberry Pi)上,该程序将读取来自另一个 MCU 的串行数据(我将自己构建的东西)。

我已经研究了如何做到这一点,并认为我有“大局”,但仍然缺少一些东西。一方面,我需要启用内核模块并让自己访问设备:

sudo modprobe spi_bcm2708
sudo chown `id -u`.`id -g` /dev/spidev0.*

从那里我可以使用这个著名的 C 文件来测试 SPI 连接。

所以现在连接在那里,但我仍然需要从中读取串行数据。根据这个 SO question的答案,我只需要:

...打开相关端口进行读取,并用于read()获取数据。

然而,该答案中的代码片段似乎是通过设备驱动程序打开端口,而不是通过 SPI。

我的理解是我可以使用 SPI 从连接的 MCU 设备中读取数据,并且我不需要为该设备编写自己的设备驱动程序。这是真的?如果是这样,我将如何从 SPI 连接中读取数据,该代码与上面链接的问题的答案中的代码有何不同?

如果我的理解不正确,并且我确实“通过”了设备驱动程序,那么为什么我首先需要驱动程序?这不正是SPI希望规避的吗?提前致谢。

4

3 回答 3

6

我正在尝试编写一个程序,该程序将安装在 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 字符设备暴露给您的用户程序使用。但如果 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 连接,但没有强加主/从层次结构、更简单的硬件接口和更长的电缆长度。

请注意,您可能无法使用您安装的任何电缆实现长 SPI 距离的快速传输速率。SPI 的 10 Mbps 速率通常在具有接地层和短走线的多层板上实现。

于 2012-12-11T07:07:11.070 回答
4

在 Unix 上,一切都是文件

如果spi_bcm2708驱动程序安装正确,则应该有一个/dev/whatever设备文件(或几个用于以不同方式访问设备的文件)。

如果没有自动创建,您可以使用mknod进行输入

用户空间代码只需像打开/dev/whatever任何其他常规文件一样打开文件并从中读取/写入数据。这就是 Unix 的全部意义所在。

编辑:这正是链接问题中的代码正在做的事情,它将终端/dev/ttyS0作为带有 open() 的文件打开并读取/写入它。

于 2012-12-10T19:25:33.490 回答
1

你找到SPI 的 Linux 文档了吗?

有几个很好的文档:spi-summary 和 spidev。

文件spidev_fdx.c中也有示例,read()用于 SPI 设备。

但通常从 SPI 读取是由ioctl()函数处理的。

于 2012-12-11T08:15:43.380 回答