SPI_IOC_MESSAGE(N)宏让我适合

时间:2015-07-22 19:51:29

标签: c++ linux arm spi ioctl

我在获取SPI程序时遇到问题我正在努力正常工作,这似乎是SPI_IOC_MESSAGE(N)宏的一些问题。

这里的示例代码是DOESN工作(ioctl返回EINVAL(22)):

std::vector<spi_ioc_transfer> tr;
<code that fills tr with 1+ transfers>
// Hand the transmission(s) off to the SPI driver
if (tr.size() > 0)
{
    int ret = ioctl(fd, SPI_IOC_MESSAGE(tr.size()), tr.data());
    if (ret < 1)
    {
         int err = errno;
    }
}

我的测试代码现在正在创建一个长度为1的向量。 如果我明确地将代码更改为:

int ret = ioctl(fd, SPI_IOC_MESSAGE( 1 ), tr.data());

...然后ioctl(...)成功,我的位落下管道。 看看Eclipse中SPI_IOC_MESSAGE宏的扩展,我不明白为什么这不开心。

建议?

我是从64位Linux VM对Linux / ARM(Beaglebone Black)进行交叉编译,但是我无法看到影响宏的情况。

编辑: 以下是C预处理器中的两个宏扩展

int ret = ioctl(fd, (((1U) << (((0 +8)+8)+14)) | ((('k')) << (0 +8)) | (((0)) << 0) | ((((sizeof(char[((((tr.size())*(sizeof (struct spi_ioc_transfer))) < (1 << 14)) ? ((tr.size())*(sizeof (struct spi_ioc_transfer))) : 0)])))) << ((0 +8)+8))), tr.data());

和文字:

int ret = ioctl(fd, (((1U) << (((0 +8)+8)+14)) | ((('k')) << (0 +8)) | (((0)) << 0) | ((((sizeof(char[((((1)*(sizeof (struct spi_ioc_transfer))) < (1 << 14)) ? ((1)*(sizeof (struct spi_ioc_transfer))) : 0)])))) << ((0 +8)+8))), tr.data());

绝对可怕,但我不会在tr.size()如何在那里使用时看到任何令人惊讶的事情。

编辑以包含似乎是答案的内容

#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
extern "C" {
#endif
#include <linux/spi/spidev.h>
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
}
#endif

将Linux SPI包含文件包含在&#34; extern C&#34;指示系统将该部分视为普通的旧C,这似乎让我调用SPI_IOC_MESSAGE( tr.size() )SPI_IOC_MESSAGE( an_int )并发生正确的事情(通过GDB逐步和信号分析器验证)。

1 个答案:

答案 0 :(得分:2)

我怀疑问题可能在于埋在宏汤中的这个特殊的金块:

...sizeof(char[...tr.size()...])...

注意到Linux代码只是C,C标准(我这里有C99草案n1256)声明sizeof运算符表达式操作数未评估,结果是常量,除非操作数的类型是可变长度数组,在这种情况下,它被计算并且结果是整数。

但是,C ++标准(C ++ 11 draft n3242)似乎没有给出评估操作数的任何条件,只表示结果是常量。

因此看起来这可能是C和C ++不同的一个角落,而另一个则编译一个导致未定义的行为。在这种情况下,我认为选择要么只是破解你自己的宏版本,要么有一个单独的外部C函数来包装它。