dc核心板-软件sw15-开发说明_第1页
dc核心板-软件sw15-开发说明_第2页
dc核心板-软件sw15-开发说明_第3页
dc核心板-软件sw15-开发说明_第4页
dc核心板-软件sw15-开发说明_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

RevisionChangescomparedtoprevious概 编写目 适用范 相 模块介 模块功能介 相关术语介 描述符 散列传 模块配置介 源码结构介 模块体系结构描 DMA驱动架构 DMA状 模块数据结构描 模块接口描 模块开发 DMA使用流程 demo程 Android系统支 模块调 config的配 测试用例选 测试操作步 总 概DMA开发模块介dmaDirectMemoryAccess(直接内存存取),cpu,直接在设备和内存,内存和内存,设备和设备之间传输.DMA可以减cpu负担,cpu可用于忙别的活,传输速度也比cpu搬运高得多.A20许多模块内置了DMA,sd,usbehci,nand等,DMA驱动,usbotg,audiocodec.DMA驱动,DirectMemoryAccess,即直接内存存取,cpu,直接在设备和内存,内存和内存,设备和设备之间传输.描述符指能被DMA硬件解析的一段内存区域,其数据按一定的格式组织,包含源地址,目的地址,传输的数据长度等.DMA一次,就将多笔数据传完,即一次启动,批量传输上的散列传输,指前一笔数据传完后,DMA驱动自动启动下一笔传输,硬件硬件上的散列传输,指硬件将多笔传完,硬件能自动解析下一个数据块信息,无DMA驱动代码在\linux-3.3\arch\arm\mach-sun7i\dma下模块体系结构描内内核dma接APdma使用dma硬内核层对应驱动响应应用层请求,调用DMA模块API进行数据传输.比如alsa驱动DMA模块根据数据请求设置DMA硬件DMA硬件完成数据的实际传输DMA驱动组织Dma.c:dma模块初始化dma中断处理Dma_core.c:实Dma_interface.c:Dma_csp.c:dma硬件操作函数DMA状增增加Id启动dm停止dm停止dm增加增加Rdon所有buffer传开定义了三种状态idle:DMA硬件空闲的状态running:DMA正在传输的状态模块数据结构描DMA通道信息DMA得到的句柄.structdma_channel_t{/*1used,0unuse/*channelid,0~15 /*dmachnnnelownername*/ reg_base;/*regsbaseaddr*/ /*cotinuemode*/ irq_spt;/*channelirqsupprottype,usedforirqhandleronlyenabledthencancallirqcallback*/structdma_cb_t /*halfdonecallbackfunc*/structdma_cb_t /*fulldonecallbackfunc*/structdma_cb_t /*queuedonecallbackfunc*/structdma_op_cb_t /*dmaoperationcallbackfunc*/structdes_save_info_tdes_info_save;/*savetheprevbufpara,usedsw_dma_enqueueenumdma_work_mode_eunion /*channelstateforchain/single /*dmachannellock*forchainmodestructlist_head cur_list;/*buflistwhichisbeingtranferring*/structlist_head /*buflistbkupfornexttranfer*/*forsinglemode *pcur_des;/*curbufferwhichistransferring*/structlist_head dma配置描述符结构structstructcofig_des_t/*dmaconfigurationreg/*dmasrcphysaddrreg/*dmadstphysaddrreg/*dmabytecntreg/*dmaparamregstructcofig_des_t /*nextdescriptoraddresstypedefstructtypedefstructdes_itemstruct /*descriptorthatwillbesettohw structlist_head/*physicaladdrofthisdes_itemstruct/*listnode描述符管理单元DMA通道状态typedeftypedefenum/*maybebeforestartorafterstopCHAN_STA_RUNING,/*transferringCHAN_STA_LAST_DONE/*thelastbufferhasdone,inthisstate,sw_dma_enqueuewillstartdma*/dmahalf/full/queuedone回调函数 dma_cb_cause_ecause);structdma_cb_t /*函数指针*/ /*func的参数*/dma操作类型/*setoperationcallback/*sethalfdonecallback/*setfulldonecallback/*setqueuedonecallback /*getchannelstatus:idle/busy*/ /*getcurrentsrcaddress*/ /*getcurrentdstaddress*/ /*getbytecntleft/*startdma/*pausetransferring/*resumetransferring/*stopdmaenum{DMA_OP_START,模块接口描原型:dm_hdl_tsw_dma_reqhar*name,enumdma_work_mode_e功能dma通道.name:dma通道名,由调用者取,可以为NULL,但不能与已有的 work_mode:dma工作模式,DMA_WORK_MODE_CHAIN表示chain模式,.返回:成功返回句柄,原型u32sw_dma_release(dm_hdl_t功能:dma通道返回:0,失败返回出错的行号原型u32sw_dma_ctl(dm_hdl_tdma_hdlenumdma_op_type_eopvoid功能dma控制函数,用于启动dma,停止dma,获取数据传输状态,等enumdma_op_type_eenumdma_op_type_e/*startdma/*pausetransferring/*resume/*stopdma/*getchannelstatus:address op:pargparg操作所带参数,op参数意义不同返回:成功返回0,失败返回出错的行号./*setoperationcallback/*sethalfdonecallback/*setfulldonecallback/*setqueuedonecallback /*getbytecntleftaddress原型: dma_enque_phase_ephase);功能:dma之前,dma硬件参数,参数 添加buffer的阶段 该参数现无意义 请固定设enum形加加

一般的添加,即非以下三种情dmafulldone回调函数中添返回:0,失败返回出错的行号原型u32sw_dma_enqueue(dm_hdl_tdma_hdlu32src_addru32dst_addru32t,dma_enque_phase_ephase);功能buffer到队列.src_addr:dst_addr:t:phase:传输阶段.该参数现无意义,返回:0,失败返回出错的行号原型intsw_dma_getposition(dm_hdl_tdma_hdlu32*pSrc,u32功能:获取当前传输位置信息.注:仅音频模块(spdif/i2s/ audio/pcm)用到,其参数pSrc:srcaddrpDst:dstaddr寄存器值返回:0,失败返回出错的行号功能:打印通道信息函数.用于调试.返回:无.开开有新数据Y需要等待传输 成还Y结sw_dma_release dma通道sw_dma_ctl停止dma等待传输sw_dma_enqueue(sw_dma_ctl(启动dmasw_dma_enqueue添加buffersw_dma_ctl(设置sw_dma_request申请dma通道sw_dma_config(硬件参数dma通道设置回调函数hd_cb(desbuffer传输一半时回调fd_cb(des队列中buffer传输完时回调),qd_cb(des队列中所有buffer传输完时回调)配置dma参数,如srcdrqtype(源地址类型burstlength(burst长度);dma通道demo#include#include/*src/dststartaddressstaticu32g_src_addr=0,g_dst_addr=/*curbufindexstatic t=cb_fd_normal-fulldonecallbackforcase@dma_hdl:dma@parg:argsregisterdwithcbReturns0ifsucess,theerrlinenumberif cb_fd_normal(dma_hdl_tdma_hdl,void{ uret=u32ucur_saddr=0,ucur_daddr=t=TOTAL_LEN_NORMAL/ONE_LEN_NORMAL; t=0; /*enqueueifnotdonet=atomic_add_return(1, t< t){printk("%s,line /*NOTE:fatalerr,whenreadhere, thaschangedbyotherplace,2012-12-2*/ ucur_saddr=g_src_addr+ t*ONE_LEN_NORMAL;ucur_daddr=g_dst_addr t* printk("%serr,line }else{/*bufenqueuecompleteprintk("%s,line //sw_dma_dump_chan(dma_hdl);/*fordebug/*maybeit'sthelastirq*/}if(0!=pr_err("%serr,line ,}cb_hd_normal-halfdonecallbackforcase@dma_hdl:dma@parg:argsregisterdwithcbReturns0ifsucess,theerrlinenumberif cb_hd_normal(dma_hdl_tdma_hdl,void{ uret=u32ucur_saddr=0,ucur_daddr=t=TOTAL_LEN_NORMAL/ONE_LEN_NORMAL; t=0; /*enqueueifnotdonet=atomic_add_return(1, t< t){printk("%s,line /*NOTE:fatalerr,whenreadhere, thaschangedbyotherplace,2012-12-2*/ ucur_saddr=g_src_addr+ t*ONE_LEN_NORMAL;ucur_daddr=g_dst_addr t* printk("%serr,line }if(0!=pr_err("%serr,line ,}waitdone_normal-waitdmatransferfunctionforcaseReturns0ifsucess,theerrlinenumberif { ret= timeout=2*/*waitdmadoneret=wait_event_interruptible_timeout(g_dtc_queue[DTC_NORMAL],\atomic_read(&g_adma_done)==1,timeout);/*resetdmadoneflagto0*/if(-ERESTARTSYS==ret)pr_info("%ssuccess!\n", return0;}elseif(0==ret)pr_info("%serr,timeout!\n", }elsepr_info("%ssuccesswithconditionmatch,ret }}

return { uret=0/*,tmp=0 *src_vaddr=NULL,*dst_vaddr=NULL; src_paddr=0,dst_paddr=0;dma_hdl_tdma_hdl=(dma_hdl_t)NULL;dma_cb_tdone_cb;dma_config_tdma_config; /*preparethebufferanddata (dma_addr_t*)&src_paddr,GFP_KERNEL);if(NULL=={uret=LINE gotoend;} (u32)src_vaddr,src_paddr);

(dma_addr_t*)&dst_paddr,GFP_KERNEL);if(NULL=={uret=LINE gotoend;} (u32)dst_vaddr,dst_paddr);/*initsrcbuffermemset(dst_vaddr,0x54,TOTAL_LEN_NORMAL);/*initlooppara*/ g_src_addr=src_paddr;g_dst_addr=dst_paddr;/*requestdmachanneldma_hdl=sw_dma_request("m2m_dma",CHAN_NORAML);if(NULL==dma_hdl){uret= gotoend;}pr_info("%s:sw_dma_requestsuccess,dma_hdl0x%08x\n",

/*setfulldonecallback*/done_cb.func= done_cb.parg=NULL;if(0!=sw_dma_ctl(dma_hdl,DMA_OP_SET_FD_CB,(void{uret=LINE gotoend;}pr_info("%s:setfulldone_cb /*sethalfdonecallback*/done_cb.func= done_cb.parg=NULL;if(0!=sw_dma_ctl(dma_hdl,DMA_OP_SET_HD_CB,(void*)&done_cb))uret= gotoend;}pr_info("%s:sethalfdone_cb /*configparamemset(&dma_config,0,sizeof(dma_config)); dma_config.xfer_type.src_bst_len=DATA_BRST_4; dma_config.xfer_type.dst_bst_len=DATA_BRST_4;dma_config.address_type.src_addr_mode=dma_config.address_type.dst_addr_mode=dma_config.src_drq_type=N_SRC_SDRAM;dma_config.dst_drq_type=N_DST_SDRAM;dma_config.bconti_mode=false; =CHAN_IRQ_HD|CHAN_IRQ_FD;if(0!=sw_dma_config(dma_hdl,&dma_config)){uret= gotoend;}pr_info("%s:sw_dma_config #if0/*addornotadd,bothok,2013-2-2821:08/*setsrc/dstsecutmp={uret=LINE gotoend;}pr_info("%s:DMA_OP_SET_SECURITY /*setwaitstate,ndmaonly{u32state=0;/*0~7,fromspecif(0!=sw_dma_ctl(dma_hdl,DMA_OP_SET_WAIT_STATE,{uret=LINE gotoend;} }#if/*setparareg,ddmaonly{dma_para_tpara; =para.src_wait_cyc= =para.dst_wait_cyc={uret=LINE gotoend;}

/* buf ONE_LEN_NORMAL)){uret= gotoend;} buf /*dumpchain*//*startdmaif(0!=sw_dma_ctl(dma_hdl,DMA_OP_START,{uret=LINE gotoend;}/*enqueueotherbuffer,withcallbackenqueuesimutanously{ t=0,ucur_saddr=0,ucur_daddr=t=TOTAL_LEN_NORMAL/ t= t)) {ucur_saddr=g_src_addr t*ucur_daddr=g_dst_addr t* printk("%serr,line }}pr_info("%s,line /*waitdmadoneif(0 {uret=LINE gotoend;} waitdone_normal NOTE:mustsleephere,becasewhen enqueuecomplete,butdatamightnottransfercomplete,2012-11-/*checkifdataokpr_info("%s:d heckok!\n", elsepr_err("%s:d heckerr!\n", uret= ;/*returnerr*/goto}/*stopandreleasedmachannelif(0!=sw_dma_ctl(dma_hdl,DMA_OP_STOP,{uret=LINE gotoend;}pr_info("%s:sw_dma_stopsuccess\n", if(0!=sw_dma_release(dma_hdl)){uret= gotoend;}dma_hdl=pr_info("%s:sw_dma_release if(0!=pr_err("%serr,line%d!\n", ,uret);/*printerrline*/ /*stopandfreedmachannel,ifneed*/if((dma_hdl_t)NULL!=dma_hdl){pr_err("%s,stopandreleasedmahandlenow!\n", if(0!=sw_dma_ctl(dma_hdl,DMA_OP_STOP,NULL))pr_err("%serr,line%d!\n", if(0!=sw_dma_release(dma_hdl))pr_err("%serr,line }pr_info("%s,line /*freedmamemory*/if(NULL!= if(NULL!= pr_info("%s,end!\n", returnuret;}#ifndef#ifndefTEST_CASE_NORMAL#define/*totallengthandonebuflength#defineTOTAL_LEN_NORMAL #defineONE_LEN_NORMAL u32 u32 u32u32 u32 #endif/*#endif/* #ifndefSUN7I_DMA_TEST_H#define#ifndefSUN7I_DMA_TEST_H#defineSUN7I_DMA_TEST_H#include<linux/kernel.h>#include<linux/init.h>#include<linux/module.h>#include<linux/types.h>#include< #include<linux/gfp.h>#include<linux/interrupt.h>#include<linux/init.h>#include<linux/ioport.h>#include<linux/in.h>#include<linux/string.h>#include<linux/delay.h>#include<linux/errno.h>#include<linux/skbuff.h>#include#include<linux/dma-map#include<linux/slab.h>#include<asm/io.h>#include<asm/pgtable.h>#include<asm/dma.h>#include<linux/delay.h>#include<asm/dma-map#include<linux/wait.h>#include#include#include*dmatestcaseenumdma_test_case_eDTC_NORMAL=0, /*casefornormalchannel*/ /*casefornormalchannelcontinuemode /*casefordedicatechannel*/ /*casefordedicatechannelcontinuemode*fordedicate /*enqueuedbufferafterdmalastdone,toseeifcancotinueautostart*/ /*manybufferenqueued,functiontest*/ /*stopwhendmarunning*/ /*two-threadrunsimutalously,pressuretestandmemoryleaktest*/externatomic_tg_adma_done;#endif SUN7I_DMA_TEST_H#include#include/*waitdmadonequeue,usedforwaitdmadone*/ g_adma_done=ATOMIC_INIT(0);/*dmadoneflagconstchar*case_name[]{"DTC_NORMAL", dma_test_init_waitqueue-initdmawaitstatic {u32i=}staticintdma_test_main(int{enumdma_test_case_ecur_test=(enumdma_test_case_e)id;u32ret=0;{caseret= case//ret= case//ret= case//ret= case//ret= case//ret case//ret= case//ret= ret= }if(0==printk("%s:testsuccess!\n", printk("%s:testfailed!\n", returnret;}ssize_ttest_store(structclass*class,structclass_attribute*attr,constchar*buf,size_tsize){intid=/*gettestidif(strict_strtoul(buf,10,(longunsignedint{pr_err("%s:invalidstring%s\n",func return-EINVAL;}pr_info("%s:string%s,testcase ,buf,if(0!=pr_err("%s:dma_test_mainfailed!id%d\n", pr_info("%s:dma_test_mainsuccess!id%d\n", returnsize;}ssize_thelp_show(structclass*class,structclass_attribute*attr,char{ssize_tcnt=cnt+=sprintf(buf+cnt,"usage:echoid>cnt+=sprintf(buf+cnt, idforcase %d\n",cnt+=sprintf(buf+cnt," idforcaseDTC_NORMAL_CONT_MODEis%d\n",(int)DTC_NORMAL_CONT_MODE);cnt+=sprintf(buf+cnt, idforcase %d\n",cnt+=sprintf(buf+cnt," idforcaseDTC_DEDICATE_CONT_MODEis%d\n",(int)DTC_DEDICATE_CONT_MODE);cnt+=sprintf(buf+cnt," idforcaseDTC_ENQ_AFT_DONEis%d\n",(int)DTC_ENQ_AFT_DONE);cnt+=sprintf(buf+cnt, idforcase %d\n",cnt+=sprintf(buf+cnt, idforcase %d\n",cnt+=sprintf(buf+cnt," idforcaseDTC_M2M_TWO_THREADis%d\n",(int)DTC_M2M_TWO_THREAD);cnt+=sprintf(buf+cnt,"casecnt+=sprintf(buf+cnt," casefornormalchannel\n");cnt+=sprintf(buf+cnt," normalchannelcontinuemode\n");cnt+=sprintf(buf+cnt," casefordedicatechannel\n");cnt+=sprintf(buf+cnt," DTC_DEDICATE_CONT_MODE:casefordedicatechannelcontinuemode\n");cnt+=sprintf(buf+cnt, belowisforcnt+=sprintf(buf+cnt," bufferafterdmalastdone,toseeifcancotinueautostart\n");cnt+=sprintf(buf+cnt," enqueued,functiontest\n");cnt+=sprintf(buf+cnt," dmarunning\n"); two-threadrunsimutalously,pressuretestandmemoryleaktest\n");return}staticstructclass_attributedma_test_class_attrs[]=ATTR(test,0220,NULL,test_store),/*not222,forCTS,othergroupcannothavewritepermission,2013-1-11*/ATTR(help,0444,help_show,staticstructclassdma_test_class= = =.class_attrs=static init{int /*initdmawaitqueue*//*registersysclassif(status<0)pr_info("%serr,status%d\n", pr_info("%ssuccess\n", return0;}*sw_dma_test_exit-exitthedmateststatic exit{pr_info("sw_dma_test_exit:}#ifdefMODULEMODULE_LICENSE("GPL");MODULE_AUTHOR("liugang");MODULE_DESCRIPTION("sun7iDmaTestdrivercode"); #endif/*MODULE*/Androiddma属linux内核模块 和

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论