Ioctl“无法发送spi消息:无效的参数” Beaglebone Black

时间:2019-06-03 19:11:56

标签: c beagleboneblack spi ioctl

我正在尝试从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'都传递给我,但没有用。任何输入将不胜感激。

编辑:所以我决定使用第一个有效的代码。我想没有理由发送大量转帐。我的系统速度足够快,足以使电压有效地实时!谢谢您的帮助。 (我还整理了很多代码,以使其更易于阅读!)

2 个答案:

答案 0 :(得分:0)

仔细研究一下,我发现您可能没有正确定义tr [j] .rx_buf,这将导致参数无效。我需要假设有一个已分配的存储空间* p,但是您没有将其与tr参数关联。

答案 1 :(得分:0)

在结构spi_ioc_transfer tr后添加memset(&tr, 0, sizeof(tr));

https://community.nxp.com/thread/482375