This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] Linux/AM3352:GPIO 触发的 DMA 传输

Guru**** 2587365 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/635401/linux-am3352-gpio-triggered-dma-transfer

器件型号:AM3352

工具/软件:Linux

您好!

我有一个基于 Pavel 在该线程中提到的 gpevt 示例驱动程序的配置:

https://e2e.ti.com/support/arm/sitara_arm/f/791/t/633610 

这是由 GPIO0引脚触发的 DMA 传输。 此传输似乎有效、但仅当我提交4个字节的传输时才有效。

用于配置的伪代码(我想从0x10000000传输1024字节到0x9f000000 -这两个字节都是静态配置的地址-首先是器件映射到此地址范围、其次是输出缓冲器预配置):

Request_IRQ()
dma->rx_chan = dma_request_slave_channel (&pdev->dev、"dmarxtx");

dma->rx_conf.dst_addr = dma->dma_buf_phys_addr;
dma->rx_conf.dst_addr_width = dma_slave_BUSWIDTH_4_bytes;
dma->rx_conf.dst_maxburst = 1;

RET = dmaenginer_slave_config (dma->rx_chan、&dma->rx_conf);

sg_init_table (&dma->sg、1);
dma->sG.dma_address = SRC_buffer_address;  
sg_dma_len (&dma->sg)= 4;

dma->tx_desc = dmaenginer_prep_slave_sg (dma->rx_chan、&dma->sg、1、dma_dev_TO_MEM、
DMA_PRE_INTERRUPT | DMA_CTRL_ACK);

dma->tx_desc->callback = fpgasd_dma_callback_func;
dma->TX_desc->callback_param =&pdev->dev;
dmaenginer_submit (dma->tx_desc);

dma_async_issend_pending (dma->rx_chan);

现在、如果我进行设置  

sg_dma_len (&dma->sg)= 4;

然后、在系统日志中、我可以看到 EDMA 的配置:

[66.955306] EDMA 49000000.EDMA:
[66.955306] pset [0]:
[66.955306]编号22.
[66.955306]插槽51
[66.955306]选择00116000
[66.955306] src 10004000
[66.955306] dst 9f000000
[66.955306] abcnt 00010004
[66.955306] ccnt 00000001
[66.955306] bidx 00000004
[66.955306] cidx 00000004
[66.955306] lkrld ffff
[66.955401] EDMA 49000000.EDMA:第一个传输从通道22开始
[66.955428] EDMA 49000000.EDMA:ER0 04000000
[66.955454] EDMA 49000000.EDMA:EER0 08400000

这是我请求的内容(设置为传输4个字节的 EDMA 的 a、b、c cnt 寄存器、回调中断调用打开)。 在 GPIO 事件传输完成且中断被调用后:

[67.011961] EDMA 49000000.EDMA:DMA_IRQ_handler
[67.012003] EDMA 49000000.EDMA:EER0 08000000
[67.012033] EDMA 49000000.EDMA:TXD db721540[2]:标记为完成
[67.012061] EDMA 49000000.EDMA:通道22上的传输完成

到目前为止都很好。 但是、当我希望发送8个字节时:

sg_dma_len (&dma->sg)= 8;

我获取此 EDMA 配置:

[123.934027] EDMA 49000000.EDMA:vchan db141668:TXD db5fd9c0[2]:已提交
[123.934088] EDMA 49000000.EDMA:
[123.934088] pset [0]:
[123.934088]通道号22.
[123.934088]插槽51
[123.934088]选择00116000
[123.934088] src 10004000
[123.934088] dst 9f000000
[123.934088] abcnt 00020004
[123.934088] ccnt 00000001
[123.934088] bidx 00000004
[123.934088] cidx 00000004
[123.934088] lkrld ffffff
[123.934184] EDMA 49000000.EDMA:第一个传输从通道22开始
[123.934210] EDMA 49000000.EDMA:ER0 04000000
[123.934236] EDMA 49000000.EDMA:EER0 08400000

对8个字节来说可以、但 DMA 中断处理程序未被调用。 这样做的原因可能是什么? 欢迎使用任何提示。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    软件团队已收到通知。 他们将在这里作出回应。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Jacek:

    您使用的是哪款 TI SDK?

    您是否试用过内核4.9.41附带的最新 AM335x TI PSDK v4.1?

    此致、
    帕维尔
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Jacek、

    您可以浏览最成熟的内核驱动程序,它使用的是 sg_dma_len()函数:

    linux-kernel/drivers/dma/dmatest.c
    Linux-kernel/Documentation/dmaengine/dmatest.txt

    您还可以参考 McASP、MMC/SD 和/或 McSPI 驱动程序、这些驱动程序使用 EDMA 驱动程序来传输数据。

    此致、
    帕维尔
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    dma->rx_conf.dst_maxburst = / 4;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    我使用的是内核4.4.4.41的 ti-processor-sdk-linux-am335x-evm-03.03.00.04。 感谢您参考其他使用 sg_dma_len 的驱动程序。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    现在、我使用了由 GPIO 触发的存储器到存储器的传输。 这对于我们需要从外部器件复制的单个连续缓冲器来说已经足够了。 完成驱动程序后、我将返回基于 SG 的解决方案、以查看 dst_maxburst 更改是否会导致传输发生。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Jacek:

    一旦您尝试这些建议、请告诉我们结果。 如果您能够解决问题、请关闭/验证此主题。

    此致、
    帕维尔