首页 > 解决方案 > 在 SPI 传输函数中返回 -1 EINVAL 的 ioctl 错误

问题描述

不确定这是否与 C 相关或与 linux 内核有关。我正在为 Beaglebone 使用一个名为 BlackLib 的 SPI 库,它具有 SPI 传输功能。

由于某种原因,当我第一次尝试它时它不起作用。我玩了几天,当我在函数本身中声明了两个随机数组时,它意外地工作了,即使它的效果为零。如果我删除它们,该函数会在 ioctl 行再次中断。

例如,如果我打电话:

uint8_t writeBuffer[2] = {0x00, 0x01};
uint8_t readBuffer[2] = {0,0};
transfer(writeBuffer, readBuffer, sizeof(readBuffer), 10, 0)

关于功能

bool   BlackSPI::transfer(uint8_t *writeBuffer, uint8_t *readBuffer, size_t bufferSize, uint16_t wait_us, uint16_t pad)
{  
    uint8_t tempReadBuffer[ bufferSize ];
    memset( tempReadBuffer, 0, bufferSize);

    spi_ioc_transfer package;

    package.tx_buf          = (unsigned long)writeBuffer;
    package.rx_buf          = (unsigned long)tempReadBuffer;
    package.len             = bufferSize;
    package.delay_usecs     = wait_us;
    package.speed_hz        = 5000000; //uint32_t
    package.bits_per_word   = 8; //uint8_t
    package.pad             = pad;

    // IF I DELETE THESE TWO DECLARATIONS, SPI transfer will fail. 
    // I have no idea why.. maybe causing a specific delay in the code that lets spi work, or overwriting old memory addresses that c++ attemps to access?
    uint8_t arr[4] = {0x02, 0x03, 0x04, 0x05};
    uint8_t arrr[4] = {0x03, 0x04, 0x05, 0x06};

    //ioctl call
    if( ::ioctl(this->spiFD, SPI_IOC_MESSAGE(1), &package) >= 0){
        memcpy(readBuffer, tempReadBuffer, bufferSize+pad);
        return true;
    } else {
        return false;
    }
}

它返回真(工作)。但是如果我像这样注释掉这两个数组

//uint8_t arr[4] = {0x02, 0x03, 0x04, 0x05};
//uint8_t arrr[4] = {0x03, 0x04, 0x05, 0x06};

该函数返回 false(无效),strace输出包含:

ioctl(4, 0x40206b00, 0xbe899b80)        = -1 EINVAL (Invalid argument)

这会导致我的代码出现问题,因为如果我对其他链接库甚至我自己的代码进行一些更改,它会导致此 SPI 传输函数停止工作。

这超出了我对 C/C++ 代码如何与 linux 操作系统交互的了解,因此感谢任何帮助。

标签: c++clinuxspiioctl

解决方案


解决了。如果您不将数组/结构的所有元素初始化为任何内容,C/C++ 不保证将它们初始化为 0。使用memset并且memcpy可能也不能保证这一点。因此ioctl调用返回错误,因为package结构在某些成员中包含不正确的值。

我必须像这样初始化 spi_ioc_transfer 结构packagetempReadBuffer归零,以确保我没有得到任何令人讨厌的惊喜:

spi_ioc_transfer package = {};
uint8_t tempReadBuffer[ bufferSize ] = {};

推荐阅读