dmatest 代码分析
dmatest
是内核的一个测试dma模块的代码,代码位置位于内核的./drivers/dma/dmatest.c
,关于dmatest
模块的使用可以参考内核提供的文档./Documentation/dmaengine/dmatest.txt
,这里只简单地介绍一下。
编译加载模块
配置支持位置:
Device Drivers -> DMA Engine support -> DMA Test client
或者直接修改配置文件CONFIG_DMATEST=m
,编译成模块。
可以直接加载dmatest.ko
,然后echo
相关参数到/sys/module/dmatest/parameters/
下,echo 1 > /sys/module/dmatest/parameters/run
驱动就会执行测试过程。
代码分析
模块注册
先看模块的初始化过程:
初始过程里面用到了两个结构体,我们来看一下。
struct dmatest_info
:
struct dmatest_params
:
相关的模块参数就一开始有定义,具体就不多说了,是何上面的结构体基本对应的。
这里的run
参数指定加载模块时知否直接执行测试:
这里的wait
参数指定加载模块执行测试用例时是否需要等待测试线程执行结束:
通道申请
注册过程中,会调用run_threaded_test()
进行通道申请,海思的hiedmacv310.c
中只注册了DMA_MEMCPY
,DMA_SLAVE
,DMA_CYCLIC
,所以这个模块在这里只能测试DMA_MEMCPY
。至于各种传输类型的dma
,可以查看内核的文档./Documentation/dmaengine/
,后面有机会再介绍一下,这里略过。
run_threaded_test()
调用具体的request_channels()
函数进行通道申请 :
申请通道附加资源
上面申请通道完成后,调用dmatest_add_channel()
,这里申请资源来保存申请成功的dma通道指针,并将申请的资源保存到相关链表中:
创建线程
dmatest_add_channel()
调用dmatest_add_threads
来创建工作线程,设置线程任务为dmatest_func()
后唤醒线程:
工作任务
dmatest_func()
函数比较长:
回头看一下回调函数的内容,也比较简单,就是设置变量done
为true
之后唤醒等待队列wait
:
停止传输
协助模块时会调用stop_threaded_test()
将传输停止,看一下具体代码实现,遍历链表将所有链表资源进行释放,通道资源进行释放:
再调用dmatest_cleanup_channel()
进行资源清理:
至此,整个dmatest
的代码基本分析完成了。