糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > 基于xilinx zynq7000平台(zynq7030) 使用 github上的axi_dma驱动操作dma(PL与PS通信)

基于xilinx zynq7000平台(zynq7030) 使用 github上的axi_dma驱动操作dma(PL与PS通信)

时间:2023-03-20 20:15:10

相关推荐

基于xilinx zynq7000平台(zynq7030) 使用 github上的axi_dma驱动操作dma(PL与PS通信)

前言

最近公司项目中使用到了赛灵思Xilinx zynq7000系列(7030)平台,产品中需要在arm(PS)与fpga(PL)之间进行大批量数据传输,还要考虑效率问题,因此使用了axi_dma模块,我用的xilinx工具(xilinx-sdk)以及组件(u-boot、kernel)都是.2版本。

驱动选择

方式一:

采用proxy-dma驱动,官方wiki代码链接如下:

https://xilinx-/wiki/spaces/A/pages/1027702787/Linux+DMA+From+User+Space+2.0#Receive-Only

不过没提供makefile来生成ko文件,我自己简单写了一个,供参考:

export ARCH=armexport CROSS_COMPILE=arm-linux-gnueabihf-KERNEL_DIR=xxx/linux-xlnx(这里指定内核源码根目录路径)all:make -C $(KERNEL_DIR) M=`pwd` modulesclean:rm -rf *.o *.cmd *.order Module.symvers *.ko *.mod* ./.* .tmp_versionsobj-m += dma-proxy.o

使用方法很简单,先修改设备树,注意,驱动代码中固定dma-names名称为dma_proxy_rx和dma_proxy_tx,因此不能随意修改,且驱动初始化中默认同时开启rx和tx通道,因为,你如果不是成对使用,需要注释掉驱动中多余通道的初始化代码:

dma_proxy {compatible ="xlnx,dma_proxy";dmas = <&S2MM_controller_axi_dma_0 0 &S2MM_controller_axi_dma_0 1>;dma-names = "dma_proxy_rx dma_proxy_tx";};

dma设备树相关(S2MM_controller_axi_dma_0)我就没写了,这个可以通过xilinx-sdk工具生成。

系统起来后insmod ko文件,能在/dev目录下得到dma_proxy_rx和dma_proxy_tx驱动设备文件,后面直接参考dma-proxy-test.c文件中的用法进行使用就行了。

方法一我已经用过了,可以用,不过这种方式对于大批量数据的搬运效率如何我没有测试。

方式二:

采用 github上大神开发的axidma驱动,链接如下:

/bperez77/xilinx_axidma

公司产品最终使用了就是这个驱动,使用步骤如下:

1、修改设备树

axidma_chrdev: axidma_chrdev@0 {compatible = "xlnx,axidma-chrdev";dmas = <&MM2S_controller_axi_dma_1 0 &MM2S_controller_axi_dma_1 1>;dma-names = "rx_channel", "tx_channel";};

然后在axi_dma的设备树下面添加字段:

xlnx,device-id = <0x0>和xlnx,device-id = <0x1>,如果使用了多组dma,那么 其它device-id 依次为 0x2、0x3、0x4... ...

2、修改cma大小

由于该驱动在初始化时会malloc大量连续内存(大小依据业务需要确定),我在业务中dma_malloc了256MB,所以启动参数bootargs中添加的是cma=300M

3、驱动编译

注意,编译驱动前,需要先编译linux内核,此步骤省略。

然后进入axi_dma驱动源码目录编译ko:

make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm KBUILD_DIR=../ driver

注意,我将axi_dma目录放在了kernel源码的根目录下,所以KBUILD_DIR指定的是 ../,KBUILD_DIR的意思就指定编译后的内核源码根目录在什么地方。

编译axi_dma动态库,该库在用户空间使用:

make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm library

4、驱动使用

系统上电后,如果dts配置正确,内核启动会有如下类似打印:

dma-pl330 f8003000.dmac: DBUFF-128x8bytes Num_Chans-8 Num_Peri-4 Num_Events-16

xilinx-vdma 40400000.dma: Xilinx AXI DMA Engine Driver Probed!!

xilinx-vdma 40410000.dma: Xilinx AXI DMA Engine Driver Probed!!

insmod axidma驱动后,正常情况下能在/dev目录下看到axidma设备,且打印:

axidma: axidma_dma.c: axidma_dma_init: 721: DMA: Found 1 transmit channels and 1receive channels.

axidma: axidma_dma.c: axidma_dma_init: 723: VDMA: Found 0 transmit channels and 0 receive channels.

没这个打印或者dev下没有设备,基本就是设备树配置问题了,设备树稍微配置错了一点就会导致这个问题,如果你出现了这个问题,请好好检查设备树文件。

驱动加载成功后就是使用库文件了,参考源码目录下的examples目录下的文件进行使用就好了,有阻塞方式和回调方式可选择,阻塞时给定超时时间,非阻塞时先调用axidma_set_callback设置回调并且超时时间给0,回调中可再次调用transfer接口,这样就能重复达到回调目的了(例如循环处理命令的模式,我最终用的就是这种方式)。

其它说明

1、transfer接口中给定的地址必须是先根据axidma_malloc或者axidma_register_buffer得到的,不能是其它形式;

2、transfer 接口中的channel值,是根据设备树配置来的,比如id依次是0(rx1) 1(tx1) 2(rx2) 3(tx2),那么,axidma_get_dma_tx和axidma_get_dma_rx返回的数组依次就是tx1、tx2和rx1、rx2。

3、如果正常使用axi_dma的用户库接口且数据收/发正常时,内核会有类似打印:

xilinx-vdma 40400000.dma: Channel ef18ae10 has errors 10, cdr 0 tdr 0

这个问题官方在某个issue中回复过了,可以忽略,暂未定位原因。

4、每次完成传输,linux系统上其实能查到中断次数:

root-~# cat /proc/interrupts CPU0 CPU1 16:10GIC-0 27 Edgegt17:00GIC-0 43 Levelttc_clockevent18: 10542244 9262181GIC-0 29 Edgetwd19:00GIC-0 37 Levelarm-pmu20:00GIC-0 38 Levelarm-pmu21: 430GIC-0 39 Levelf8007100.adc23:00GIC-0 57 Levelcdns-i2c24: 840GIC-0 80 Levelcdns-i2c26:00GIC-0 35 Levelf800c000.ocmc27: 420GIC-0 82 Levelxuartps28:90GIC-0 51 Levele000d000.spi29: 1538292070GIC-0 54 Leveleth030:00GIC-0 45 Levelf8003000.dmac31:00GIC-0 46 Levelf8003000.dmac32:00GIC-0 47 Levelf8003000.dmac33:00GIC-0 48 Levelf8003000.dmac34:00GIC-0 49 Levelf8003000.dmac35:00GIC-0 72 Levelf8003000.dmac36:00GIC-0 73 Levelf8003000.dmac37:00GIC-0 74 Levelf8003000.dmac38:00GIC-0 75 Levelf8003000.dmac39:00GIC-0 40 Levelf8007000.devcfg45:00GIC-0 41 Edgef8005000.watchdog47:10GIC-0 64 Edgeuio048:00GIC-0 65 Edgeuio149: 272673280GIC-0 61 Levelxilinx-dma-controller50:1290240GIC-0 66 Levelxilinx-dma-controller

如上面的中断号为61和66的就是dma控制器收、发的中断次数,分别是27267328次和129024次。

5、也可以不成对使用dma通道,比如只是用1个rx或tx通道或者共使用2个tx和1个rx通道,总之,按需配置dts就行(已亲测可用)。

后续有想到的我再添加吧!

如果觉得《基于xilinx zynq7000平台(zynq7030) 使用 github上的axi_dma驱动操作dma(PL与PS通信)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。