【发布时间】:2021-08-31 14:21:16
【问题描述】:
我创建了一个简单的程序来使用 spidev 发送 spi 消息。
我有两台 Raspberry pi 4 型号 B,一台使用 Ubuntu,另一台使用 Raspberrypi OS。
该程序适用于 Ubuntu,但不适用于 Rasperrypi 操作系统。
当尝试通过 ioctl 使用 SPI_IOC_MESSAGE 发送消息时,它会返回 Invalid argument 错误。通过 ioctl 使用SPI_IOC_WR_MODE 配置 spi 设备有效。
看spidev.h的时候,下面是关于spi_ioc_transfer的说法
注意:结构布局在 64 位和 32 位用户空间中是相同的。
基于此,问题不应该来自架构差异。
在这里发送消息的正确方法应该是什么?
这是代码示例。
char *device = "spidev0.0";
fd = open(device, O_RDWR);
if (fd < 0)
{
cout << "Can't open " << device << endl;
return 1;
}
int mode = SPI_MODE_0;
int ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret < 0)
{
cout << "Can't set the spi mode : " << endl
<< strerror(errno) << endl;
close(fd);
return 1;
}
struct spi_ioc_transfer xfer;
uint8_t buf[34];
memset(&xfer, 0, sizeof xfer);
xfer.tx_buf = (unsigned long)buf;
xfer.rx_buf = (unsigned long)buf;
xfer.len = 34;
int status = ioctl(fd, SPI_IOC_MESSAGE(1), xfer);
if (status < 0)
{
cout << "Ioctl error : " << strerror(errno) << endl;
return 1;
}
Ubuntu 以 64 位运行以下内核
uname -a
Linux ubuntu 5.4.0-1042-raspi #46-Ubuntu SMP PREEMPT Fri Jul 30 00:35:40 UTC 2021 aarch64 aarch64 aarch64 GNU/Linux
RasberryOS 以 32 位运行以下内核
uname -a
Linux raspberrypi 4.19.71-rt24-v7l+ #1 SMP PREEMPT RT Mon Aug 30 14:52:43 CEST 2021 armv7l GNU/Linux
编辑:
tx 和 rx 缓冲区相同,但 spidev documentation 状态
要发出全双工请求,请同时提供 rx_buf 和 tx_buf 相同的转移。如果是同一个缓冲区也没关系。
执行xfer.tx_buf = (uint64_t)buf; 会导致同样的错误。
【问题讨论】:
-
请尝试
xfer.tx_buf = (uint64_t)buf;和类似rx。 -
对 tx_buf 和 rx_buf 相同感到不满吗?尝试两种不同的缓冲区。