ioctl“无法发送 spi 消息:无效参数”Beaglebone Black
Posted
技术标签:
【中文标题】ioctl“无法发送 spi 消息:无效参数”Beaglebone Black【英文标题】:Ioctl "can't send spi message: Invalid argument" Beaglebone Black 【发布时间】:2019-06-03 19:11:56 【问题描述】:我正在尝试从我的 spidev1.0(总线 1 设备 0)上的 beaglebone black 发送 16 位消息到 IC 芯片 TLV5618AC
在移位寄存器开始在时钟下降沿拾取位之前,片选线需要从高电平变为低电平。
我执行了 spidev_test.c 的修改版本(原始版本运行良好)。由于我需要芯片选择线在消息之间从高到低 - ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
行将不起作用,因为它将数据作为单个消息传输。即使我将 ioctl() 放在 for 循环中,它也不起作用,因为它是第一条也是最后一条消息。
以下代码有效
static void transfer(int fd)
int ret;
unsigned short buffer[1];
int zero = 0;
FILE *iFile = fopen("firsttest.bin", "r");
if (iFile == NULL)
printf("Cannot open file \n");
exit(0);
struct spi_ioc_transfer tr =
.tx_buf = (unsigned long)zero,
.rx_buf = (unsigned long)zero,
.len = 2,
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
;
while(!feof(iFile))
fread(buffer,2,1,iFile);
unsigned short *tx = buffer;
unsigned short rx[1] = 0, ;
tr.tx_buf = (unsigned long)tx;
tr.rx_buf = (unsigned long)rx;
int size = ARRAY_SIZE(tx);
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
pabort("can't send spi message");
for (ret = 0; ret < 1; ret++)
printf("0x%04x\n", tx[ret]);
第二个代码块没有
int ret;
unsigned short buffer[1];
int zero = 0;
FILE *iFile = fopen("firsttest.bin", "r");
if (iFile == NULL)
printf("Cannot open file \n");
exit(0);
struct spi_ioc_transfer tr[100];
unsigned short *p = (unsigned short*) calloc(100, sizeof(unsigned short));
unsigned short *p2 = (unsigned short*) calloc(100, sizeof(unsigned short));
while(!feof(iFile))
unsigned short *tx = p2;
unsigned short *rx=p;
for(int j = 0; j< 100; j++)
fread(buffer,2,1,iFile);
tx = (unsigned short*) &buffer+j;
tr[j].tx_buf = (unsigned long)tx;
tr[j].rx_buf = 0;
tr[j].len = 2;/* Total length of message in bytes*/
tr[j].delay_usecs = delay;
tr[j].speed_hz = speed;
tr[j].bits_per_word = bits;
tr[j].cs_change = 1;
ret = ioctl(fd, SPI_IOC_MESSAGE(100), &tr);
if (ret < 1)
pabort("can't send spi message");
for(int v = 0; v<100; v++)
printf("0x%04x\n", rx);
free(p);
第二个代码块产生了这个错误
“无法发送 spi 消息:参数无效”
由于它是一个无效参数,我尝试传入 '&tr' 以及 'tr' 均无济于事。任何意见将不胜感激。
编辑:所以我决定使用第一个有效的代码。我想没有理由发送大额转账。我的系统足够快,电压足够快,可以有效地实时!!谢谢您的帮助。 (我还清理了很多代码以使其更易于阅读!)
【问题讨论】:
unsigned short buffer[1];
,后来是tx = (unsigned short*) &buffer+j;
。好吧,除非 j==0,len==1,否则这将无法正常工作。您正在访问尚未分配的地址。
另外,请尽量减少强制转换(不幸的是 tx_buf 和 rx_buf 强制转换需要保留)。它隐藏了有效的编译器投诉。
【参考方案1】:
通过这个,我想到你可能没有正确定义你的 tr[j].rx_buf,这会导致无效的参数。需要有一个分配的存储空间,我假设它是 *p,但你没有将它与 tr 参数相关联。
【讨论】:
我尝试更改声明,但没有成功。 (无符号短*) rx = p; for 循环 rx = (unsigned short*) &rx+j; tr[j].rx_buf = (unsigned long) rx; 我认为你不需要声明 rx = (unsigned short*) &rx+j;如果您删除该行,它会起作用吗?如果不是,是否仍然是相同的“无效参数”错误? 所以,实际上,我又在看这个,想知道为什么你不能使用第一个代码块,而只是插入行 tr.cs_change = 1;在 while 循环的第六行附近的某个地方。这应该为您的设备提供所需的行为,即在每条消息之间重新声明芯片选择。 是的,但是 tr 是包含 100 个结构元素的结构数组。我对 C 不是很熟悉,但我认为这会导致编译器错误。 是的,它确实给出了编译器错误。我只是修改了这段代码以发送超过 1 条消息,但我认为缓冲区有问题。我尝试删除您建议的那条线,仍然没有。 corelis.com/education/tutorials/spi-tutorial【参考方案2】:在struct spi_ioc_transfer tr之后添加memset(&tr, 0, sizeof(tr));
https://community.nxp.com/thread/482375
【讨论】:
以上是关于ioctl“无法发送 spi 消息:无效参数”Beaglebone Black的主要内容,如果未能解决你的问题,请参考以下文章