spidev ioctl return 无效参数错误
spidev ioctl return Invalid argument error
我创建了一个简单的程序来使用 spidev 发送 spi 消息。
我有两个 Raspberry pi 4 型号 B,一个带有 Ubuntu,另一个带有 Raspberrypi OS。
该程序适用于 Ubuntu,但不适用于 Rasperrypi OS。
尝试通过 ioctl 使用 SPI_IOC_MESSAGE
发送消息时 returns 出现 Invalid argument
错误。通过 ioctl 使用 SPI_IOC_WR_MODE
配置 spi 设备。
在查看spidev.h
时,对spi_ioc_transfer
做了如下陈述
NOTE: struct layout is the same in 64bit and 32bit userspace.
据此,应该不是架构差异的问题。
在这里发送消息的正确方式应该是什么?
这是代码示例。
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 状态
To make a full duplex request, provide both rx_buf and tx_buf for the
same transfer. It's even OK if those are the same buffer.
执行 xfer.tx_buf = (uint64_t)buf;
会导致相同的错误。
好像变了
int status = ioctl(fd, SPI_IOC_MESSAGE(1), xfer);
到
int status = ioctl(fd, SPI_IOC_MESSAGE(1), &xfer);
解决问题。
这尊重 spidev.h
的文档示例
SPI_IOC_MESSAGE gives userspace the equivalent of kernel spi_sync().
Pass it an array of related transfers, they'll execute together.
Each transfer may be half duplex (either direction) or full duplex.
struct spi_ioc_transfer mesg[4];
status = ioctl(fd, SPI_IOC_MESSAGE(4), mesg);
关于第一个版本如何在系统上运行,我没有任何解释。
我创建了一个简单的程序来使用 spidev 发送 spi 消息。
我有两个 Raspberry pi 4 型号 B,一个带有 Ubuntu,另一个带有 Raspberrypi OS。
该程序适用于 Ubuntu,但不适用于 Rasperrypi OS。
尝试通过 ioctl 使用 SPI_IOC_MESSAGE
发送消息时 returns 出现 Invalid argument
错误。通过 ioctl 使用 SPI_IOC_WR_MODE
配置 spi 设备。
在查看spidev.h
时,对spi_ioc_transfer
NOTE: struct layout is the same in 64bit and 32bit userspace.
据此,应该不是架构差异的问题。
在这里发送消息的正确方式应该是什么?
这是代码示例。
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 状态
To make a full duplex request, provide both rx_buf and tx_buf for the same transfer. It's even OK if those are the same buffer.
执行 xfer.tx_buf = (uint64_t)buf;
会导致相同的错误。
好像变了
int status = ioctl(fd, SPI_IOC_MESSAGE(1), xfer);
到
int status = ioctl(fd, SPI_IOC_MESSAGE(1), &xfer);
解决问题。
这尊重 spidev.h
SPI_IOC_MESSAGE gives userspace the equivalent of kernel spi_sync(). Pass it an array of related transfers, they'll execute together. Each transfer may be half duplex (either direction) or full duplex.
struct spi_ioc_transfer mesg[4];
status = ioctl(fd, SPI_IOC_MESSAGE(4), mesg);
关于第一个版本如何在系统上运行,我没有任何解释。