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);

关于第一个版本如何在系统上运行,我没有任何解释。