Spidev不会使用ioctl同时写入/读取 [英] Spidev do not write/read simultaneously using ioctl

查看:133
本文介绍了Spidev不会使用ioctl同时写入/读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使此问题可能是硬件而不是软件相关问题,我们也希望能找到帮助(我们将会看到).我正在基于Freescales P1021处理器(ppc,e500v2内核)的定制板上工作.将连接一个外部PCB,并可以通过SPI对其进行配置.该外部PCB的规范按预期在全双工模式下读取2字节命令时读取,并且仅最后一个字节用于将数据传回MISO.

I hope to find some help even if this issue might be more hardware than software related (we'll see). I'm working on a custom board based on Freescales P1021 processor (ppc, e500v2 core). A external PCB will be connected and could be configured by SPI. The specifications of this external PCB reads as it expects a 2-byte command in full duplex mode and that only the last byte is used to transfer data back on MISO.

知道这一点后,我目前正在准备一些软件来测试该设备.因此,我从众所周知的 spi_test 程序开始.

Knowing this i currently work to prepare some pieces of software to test this device. So I started with the well known spi_test program.

root@p1021rdb:~# ./spi_test -D /dev/spidev32766.3
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00
root@p1021rdb:~#

该信号显示608个时钟,似乎前半段只有数据.我决定使用环回进行调查和测试-精简MOSI-MISO会将数据循环回rx缓冲区.结果:

The signal shows 608 clocks and it seems there are only data in the first half. I decide to investigate and testing it with loopback - shorcutting MOSI-MISO loops back the data into the rx buffer. The results:

root@p1021rdb:~# ./spi_test -D /dev/spidev32766.3
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

FF FF FF FF FF FF
40 00 00 00 00 95
FF FF FF FF FF FF
FF FF FF FF FF FF
FF FF FF FF FF FF
DE AD BE EF BA AD
F0 0D
root@p1021rdb:~#

此信号表明,由于任何原因(不知道为什么),整个电报都会重复.但是,该程序会在控制台中正确显示接收到的数据,因此可能与spi_test预期的一样.

This signals reveals, that the whole telegram is repeated for any reason (I don't know why). However, the program shows the received data in the console correctly, so it may be as the spi_test expected it.

我进一步操纵将在该程序中发送的模式减少到2个字节(以模拟我想要的命令格式),如下所示:

Further I manipulate the pattern which will be sent in this program down to 2 bytes (to simulate the requested command format I aim for) like this:

#ifdef ORIG
   uint8_t tx[] = {
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
      0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
      0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,
      0xF0, 0x0D,
   };
#else
   uint8_t tx[] = {
      0xAA, 0x81,
   };
#endif

但是,由于我没有想到32位会移到SPI总线上而不是16位.在前两个字节中,MOSI提供了tx []的两个字节,其他2个字节为low/0.这是控制台输出和信号的结果:

But as I did not expect 32bits are shifted out to SPI bus - instead of 16. During the first two bytes MOSI provides the both bytes from the tx[] and for the other 2 bytes it is low/0. Here are the results of console output and signals:

root@p1021rdb:~# ./spi_test_2bytes -D /dev/spidev32766.3
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

00 00
root@p1021rdb:~#

即使我将MOSI环回至MISO,也不会接收到任何数据(控制台输出仍然与接收"00 00"相同):

And even if I loopback MOSI to MISO no data is received (console output is still the same receiving "00 00") :

我将所有参数都摆弄一遍,并决定将测试程序更改为使用半双工(仅发送)模式:

I play around a bit with all parameters and decide to change the test program to use half duplex (transmit only) mode:

#ifdef ORIG
   uint8_t tx[] = {
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
      0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
      0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,
      0xF0, 0x0D,
   };
#else
   uint8_t tx[] = {
      0xAA, 0x81,
   };
#endif
    uint8_t rx[ARRAY_SIZE(tx)] = {0, };
    struct spi_ioc_transfer tr = {
        .tx_buf = (unsigned long)tx,
#ifdef ORIG      
        .rx_buf = (unsigned long)rx,
#else
      .rx_buf = 0,
#endif

由于已编译和执行,这与预期的一样. SPI_CLK周期为16位循环16次,MOSI可以按预期提供数据. Cosole输出显示没有接收到数据,并且信号与预期的一样:

As this is compiled and executed thing are like expected. SPI_CLK cycles 16 times for 16 bits and MOSI provide the data as expected. Cosole output shows no received data and signals are like expected:

root@p1021rdb:~# ./spi_test_2bytes -D /dev/spidev32766.3
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

00 00
root@p1021rdb:~#

实际上,在我看来,我不执行2字节全双工传输,而是先执行N字节发送,再执行N字节接收.

Actually it seems to me that instead of doing 2 bytes full duplex transfer I do a N byte transmit followed by an N byte receive.

实际上有两个问题:

  1. 为什么发送0xAA,0x81和0x00、0x00?
  2. 为什么(使用环回)原始代码能够将数据返回到rx缓冲区中,但是如果减少到2个字节,则不会接收到数据?

推荐答案

好吧,这篇帖子很安静.我只读了几部分,最近接触了Linux上的SPI.但是,正如在 https://www.kernel.org/doc/Documentation/spi/spidev 异步读/写在用户空间中不可用. AFAIK读/写只是fcntl的包装.因此,您需要编写自己的内核模块来实现异步I/O.

Well, the post is quiet overwhelming. I just read a few parts and recently got in touch with SPI on Linux. However, as mentioned in https://www.kernel.org/doc/Documentation/spi/spidev async read/write is not available in userspace. AFAIK read/write is just a wrapper around fcntl. Thus you'll need to write your own kernel module to achieve async I/O.

这篇关于Spidev不会使用ioctl同时写入/读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆