首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spidev不能同时使用ioctl进行读写。

Spidev不能同时使用ioctl进行读写。
EN

Stack Overflow用户
提问于 2013-04-09 07:00:20
回答 2查看 10.7K关注 1票数 8

我希望找到一些帮助,即使这个问题可能是更多的硬件,而不是软件(我们会看到)。我正在开发一个基于P1021处理器(ppc,e500v2核)的自定义板。外部PCB将连接并可由SPI配置。这个外部PCB的规范是按照它的要求在全双工模式下读取一个2字节的命令,并且只有最后一个字节被用来在MISO上传输数据。

知道了这一点,我目前正在准备一些软件来测试这个设备。所以我从著名的测试程序开始。

代码语言:javascript
复制
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循环来调查并测试它,将数据返回到rx缓冲区中。结果:

代码语言:javascript
复制
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所期望的一样。

此外,我操作这个程序中将发送到2个字节的模式(以模拟所请求的命令格式),如下所示:

代码语言:javascript
复制
#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个字节,它是低/0的。以下是控制台输出和信号的结果:

代码语言:javascript
复制
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 "):

我对所有参数进行了一些处理,并决定将测试程序更改为使用半双工(仅传输)模式:

代码语言:javascript
复制
#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输出显示没有接收到的数据,信号与预期的一样:

代码语言:javascript
复制
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字节接收。

其实有两个问题:

  1. 为什么0xAA,0x81和0x00,0x00被传输?
  2. 为什么(使用回送)原始代码能够在rx缓冲区中获得数据,但如果减少到2个字节,则不会接收数据?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-13 21:20:02

好吧,这个职位是安静的压倒性。我只是读了几个部分,最近在Linux上与SPI取得了联系。但是,正如在https://www.kernel.org/doc/Documentation/spi/spidev中提到的,在用户空间中无法使用异步读写。AFAIK读/写只是fcntl的包装器。因此,您需要编写自己的内核模块来实现异步I/O。

票数 2
EN

Stack Overflow用户

发布于 2014-12-04 14:19:35

我知道这是一个非常老的线程,但我在运行RT5350的OpenWRT上使用了spidev。我得到的结果和你完全一样,我只是无法得到一个全双工传输发生。读取RT5350数据表时,硬件似乎只能进行半双工SPI传输。每个传输要么是写( MOSI上的输出字节,不要读取任何东西),要么是读( MOSI上的输出零点,read MISO)。

我无法为您的P1021芯片获取数据表,但是考虑到我们结果的相似性,我认为它的硬件SPI是以类似的方式实现的。

这意味着内核模块不是答案(ioctl SPI_IOC_MESSAGE最终会调用spi_async() )。实现全双工SPI的唯一方法是在软件中使用GPIOs。

RT5350参考:http://forum.vocore.io/viewtopic.php?f=3&t=72#p233

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15895338

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档