DMA模式

更新时间:2023-03-19 00:06:40 阅读: 评论:0

鼠标自己乱动是怎么回事-辣炒空心菜

DMA模式
2023年3月19日发(作者:咸菜种类)

金枫Intranet网安实验室作者:枫无眠

版权所有欢迎转载1/7

LinuxDMA使用(网摘)

关键词:

0引言

1如何在Linux下用DMA的方式进行数据

传输(硬盘)

我们都知道,使用DMA方式传输数据可以占用更少的CPU资源,因此与其它操作系统一

样,Linux支持硬盘以DMA方式转输数据,但在安装RedHat时关于DMA的默认选项是

Disable的,当然你可以在安装时就enable它。如果在安装时DMA是disable的,那该

怎么才能激活DMA呢?通过重新编译内核可以激活DMA支持,但编译内核对新手显然太

过复杂。下面的方法无需编译内核,就可以激活DMA支持。

一、检查系统中的DMA选项是否已被激活

在进行操作前,先确认硬盘是否已经在使用DMA方式传输数据了。方法:查看/

proc/ide/hda/ttings文件,其中有一行的内容为:using_dma,如果其后面的值被设

置为1就说明系统已经支持DMA了,那么下面的操作就可以免了,当然如果你要关闭DMA

功能的话,还要往下看看哟:)。

Linux中的hdparm命令是用来进行与硬盘相关操作的,用hdparm-i/dev/hda可

以列出IDE可能支持的DMA模式,如:

DMAmodes:mdma0mdma1mdma2udma0udma1udma2udma3*udma4

二、激活DMA支持

方法1:在中加入:idex=dma,其中x代表硬盘序号,其取值范围0-3,分

别代表系统中的四个IDE硬盘设备。

方法2:使用hdparm命令,hdparmd1/dev/hda其中d1表示使能DMA,你可

以将其加到中以便每次启动时都硬盘都能使用DMA方式传输数据。

金枫Intranet网安实验室作者:枫无眠

版权所有欢迎转载2/7

三、关闭DMA支持

命令格式:hdparmd0/dev/hda关闭DMA传输方式,实在想不出有什么理由要这样

做。

对支持UDMA传输方式的硬盘,也可以参照以上的方法进行设置,但要确保硬盘控制器

及硬盘都支持UDMA,最后你还要有一根支持UDMA传输方式的硬盘连线,否则即使你激

活了UDMA支持,它也会罢工的。

2S3C2410的linux下DMA驱动程序开

网上介绍LINUX下的一般驱动程序开发示例浩如烟海,或是因为简单,关于DMA驱动的

介绍却寥寥无几;近期zhaoyang因工作需要,花了几日时间开发了某设备在S3C2410

处理器Linux下DMA通信的驱动程序,有感于刚接手时无资料借鉴的茫然,故写点介绍,

期待能给有DMA开发任务的网友们一点帮助。

本文将包括如下内容:

DMA驱动主要函数功能

驱动中关键技术分析

具体的DMA实例分析

申明:本DMA驱动开发介绍仅适合S3C2410处理器类型,分析源码为韩国MIZI研究中

心维护的dma驱动代码:linux/arch/arm/鸡肉的营养价值 mach-s3c2410/dma.h,linux

/arch/arm/mach-s3c2410/dma.c,其它处理器平台DMA开发可比对此文,自行分析。

DMA驱动主要数据结构(linux/arch/arm/mach-s3c2410/dma.h)

S3C2410有四通道DMA,每通道有9个控制寄存器:6个控制寄存器控制DMA传输,其

它3个监视DMA控制器状态。

(1)DMA单个内核缓冲区数据结构:

typedefstructdma_buf_s{

intsize;/*buffersize:缓冲大小*/

dma_addr_tdma_start;/*startingDMAaddress:缓冲区起始物理地址*/

intref;/*numberofDMAreferences缓冲区起始虚拟地址*/

金枫Intranet网安实验室作者:枫无眠

版权所有欢迎转载3/7

void*id;/*toidentifybufferfromoutside标记*/

intwrite;/*1:buftowrite,0:buftoreadDMA读还是写*/

structdma_buf_s*next;/*nextbuftoprocess指向下一个缓冲区结构*/

}dma_buf_t;

(2)DMA寄存器数据结构

/*DMAcontrolregisterstructure*/

typedefstruct{

volatileu_longDISRC;/源地址寄存器

volatileu_longDISRCC;//源控制寄存器

volatileu_longDIDST;//目的寄存器

volatileu_longDIDSTC;//目的控制寄存器

volatileu_longDCON;//DMA控制寄存器

volatileu_longDSTAT;//状态寄存器

volatileu_longDCSRC;//当前源

volatileu_longDCDST;//当前目的

volatileu_longDMASKTRIG;//触发掩码寄存器

}dma_regs_t;

(3)DMA设备数据结构

/*DMAdevicestructre*/

typedefstruct{

dma_callback_tcallback;//DMA操作完成后的回调函数,在中断处理例程中调用

u_longdst;//目的寄存器内容

金枫Intranet网安实验室作者:枫无眠

版权所有欢迎转载4/7

u_longsrc;//源寄存器内容

u_longctl;//此设备的控制寄存器内容

u_longdst_ctl;//目的控制寄存器内容

u_longsrc_ctl;//源控制寄存器内容

}dma_device_t;

(4)DMA通道数据结构

/*DMAchannelstructure*/

typedefstruct{

dmach_tchannel;气愤的反义词 //通道号:可为0,1,2,3

unsignedintin_u;/*Deviceisallocated设备是否已*/

constchar*device_id;/*Devicename设备名*/

dma_buf_t*head;/*wheretoinrtbuffers该DMA通道缓冲区链表头*/

dma_buf_t*tail;/*wheretoremovebuffers该DMA通道缓冲区链表尾*/

dma_buf_t*curr;/*buffercurrentlyDMA'ed该DMA通道缓冲区链表中的当前缓

冲区*/

unsignedlongqueue_c木瓜的功效与作用禁忌 ount;/*numberofbuffersinthequeue链表中缓冲区

个数*/

intactive;/*1ifDMAisactuallyprocessingdata该通道是否已经在使用*/

dma_regs_t*regs;/*poin欧蕙 tstoappropriateDMAregisters该通道使用的DMA

控制寄存器*/

intirq;/*IRQudbythechannel//通道申请的中断号*/

dma_device_twrite;/*towrite//执行读操作的DMA设备*/

dma_device_tread;/*toread执行写操作的DMA设备*/

金枫Intranet网安实验室作者:枫无眠

版权所有欢迎转载5/7

}s3c2410_dma_t;

以下分配了四个DMA通道:

s3c2410_dma_tdma_chan[MAX_S3C2410_DMA_CHANNELS];

每个DMA通道维护着一个多缓冲区组成的单链表等待队列,执行DMA操作时先更新DMA

通道控制寄存器内容,再依次摘取当前缓冲区投入使用,缓冲区头指针顺次前移;需要插入

新的缓冲区时,可从head或tail插入;

图A详细分析了数据结构关系:

DMA驱动主要函数功能分析(linux/arch/arm/mach-s3c2410/dma.c)

写一个DMA驱动的主要工作包括:DMA通道申请、DMA中断申请、控制寄存器设置、挂

入DMA等待队列、清除DMA中断、释放DMA通道。Dma.c中对这些工作作了很好的实

现,以下具体分析关键函数:

ints3c2410_request_dma(constchar*device_id,dmach_tchannel,

dma_callback_twrite_cb,dma_callback_tread_cb)(s3c2410_dma_queue_buffer);

函数描述:申请某通道的DMA资源,填充s3c2410_dma_t数据结构的内容,申请DMA

中断。

输入参数:device_idDMA设备名;channel通道号;

write_cbDMA写操作完成的回调函数;read_cbDMA读操作完成的回调函数

输出参数:若channel通道已使用,出错返回;否则,返回0

ints3c2410_dma_queue_buffer(dmach_tchannel,void*buf_id,

dma_addr_tdata,intsize,intwrite)(s3c2410_dma_stop);校园消防安全

函数描述:这是DMA操作最关键的函数,它完成了一系列动作:分配并初始化一个DMA

内核缓冲区控制结构,并将它插入DMA等待队列,设置DMA控制寄存器内容,等待DMA

操作触发

输入参数:channel通道号;buf_id,缓冲区标识

dma_addr_tdataDMA数据缓冲区起始物理地址;sizeDMA数据缓冲区大小;write是

写还是读操作

输出参数:操作成功,返回0;否则,返回错误号

ints3c2410_dma_stop(dmach_tchannel)

金枫Intranet网安实验室作者:枫无眠

版权所有欢迎转载6/7

函数描述:停止DMA操作。

ints3c2410_dma_flush_all(dmach_tchannel)

函数描述:释放DMA通道所申请的所有内存资源

voids3c2410_free_dma(dmach_tchannel)

函数描述:释放DMA通道

因为各函数功能强大,一个完整的DMA驱动程序中一般只需调用以上3个函数即可。可在

驱动初始化中调用s3c2410_request_dma,开始DMA传输前调用s3c2410_

dma_queue_buffer,释放驱动模块时调用s3c2410_free_dma。

具体的DMA实例分析

Linux下的IIS音频驱动主要都在/kernel/drivers/sound/s3c2410-uda1341.c文件中。

它定义了2个重要的数据结构aud2021年立冬 io_bufer_t,管理audio缓冲区的数据结构;

audio_stream_t管理多缓冲区的数据结构,它为音频流数据组成了一个环形缓冲区。

我们先看一下加载驱动模块时的初始化函数:int__inits3c2410_uda1341_init(void),

该函数先初始化IO和UDA341芯片,然后语句s3c2410_request_dma("I2SSDO",s

->dma_ch,audio_dmaout_done_callback,NULL);申请了一个DMA通道用于输出音频

数据;

smdk2410_audio_write是音频驱动最关键的函数,它从用户进程中拷贝音频数据流至

DMA内核缓冲区,然后适用DMA通道2把音频数据发送出去,从而输出声音。我们可以

在smdk2410_audio_write中发现语句s3c2410_dma_queue_buffer(s->dma_ch,

(void*)b,b->dma_addr,b->size,DMA_BUF_WR);就是它为DMA写操作作好了一切

准备,当I2SSDO中断到来,DMA2通道执行一次写操作(从DMA缓冲写往IO地址

0x55000010)。

smdk2410_audio_relea函数中先后调用了s3c2410_dma_flush_all、s3c2410_

free_dma释放DMA2占用的内存资源、和释放DMA2通道。

后记

DMA操作直接关系到CPU性能的提升,s3c2410提供了4个DMA通道可实现无约束的

系统总线(AHB)或者外设总线之间(APB)的数据传输,功能强大。本文若有不当之处,

欢迎探讨。若想转贴,请注明出处。

参考文献

[1]作者.文档名.单位.年份

金枫Intranet网安实验室作者:枫无眠

版权所有欢迎转载7/7

修订记录:

版本日期内容

本文发布于:2023-03-19 00:06:38,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/1679155600304478.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:DMA模式.doc

本文 PDF 下载地址:DMA模式.pdf

上一篇:画好看的画
下一篇:返回列表
标签:DMA模式
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图