SylixOS DMA子系统之一

1. DMA子系统简介

1.1      DMA简介。

DMA的英文拼写是“DirectMemory Access”,是一种数据不经过CPU处理,直接由DMA控制器从一块物理内存搬运到另一块物理内存的数据交换模式。在DMA模式下,CPU只须向DMA控制器下达指令,让DMA控制器来处理数据的传送,数据传送完毕再把信息反馈给CPU,这样就很大程度上减轻了CPU资源占有率,可以大大节省系统资源。

2. DMA设备驱动模型

2.1      DMA驱动模型简介

SylixOS中的DMA架构位于“libsylixos/SylixOS/system/device/dma/”下,DMA驱动多用于外设驱动或总线驱动中。主要功能是从一块物理地址向另一块物理地址搬运数据。本文以mini2440的通用DMA驱动为例。

DMA设备库对DMA设备进行了封装,设备驱动仅需要提供初始化函数和回调函数即可。

在注册DMA设备驱动之前,需要先安装DMA设备库,其原型如程序清单 21:

程序清单21


#include <SylixOS.h>

INT    API_DmaDrvInstall (UINT               uiChannel,

PLW_DMA_FUNCS  pdmafuncs,

size_t               stMaxDataBytes)

函数API_DmaDrvInstall原型分析:

l 此函数执行成功返回PLW_DMA_FUNCS的地址。

DMA设备需要调用dmaGetFuncs函数绑定驱动并创建设备,其函数原型如程序清单 22:

程序清单22


#include <SylixOS.h>

PLW_DMA_FUNCS  dmaGetFuncs (UINT         iChannel,

ULONG   *pulMaxBytes)

函数dmaGetFuncs原型分析:

  • 此函数成功返回ERROR_NONE,失败返回PX_ERROR
  • 参数iChannel:DMA通道号;
  • 参数pulMaxBytes:最大传输字节数;

结构体PLW_DMA_FUNCS详细描述如程序清单 23:

程序清单23


typedefstruct lw_dma_funcs {

VOID            (*DMAF_pfuncReset)( UINT      uiChannel,

struct  lw_dma_funcs *pdmafuncs);

INT              (*DMAF_pfuncTrans)( UINT      uiChannel,

struct  lw_dma_funcs *pdmafuncs,

PLW_DMA_TRANSACTION  pdmatMsg);

INT              (*DMAF_pfuncStatus)(UINT     uiChannel,

Struct  lw_dma_funcs *pdmafuncs);

} LW_DMA_FUNCS;

typedef  LW_DMA_FUNCS    *PLW_DMA_FUNCS;

结构体中包含三个需要提供给DMA设备库的操作函数,其功能分别是复位当前DMA操作、启动一次DMA传输、获得当前DMA工作状态。这三个函数的第一个传入参数都是DMA的通道号,第二个参数都是指向DMA驱动结构体的指针。

2.2      DMA回调函数

使用回调函数的目的是将DMA设备库中的结构体保存到驱动中以供缓冲区数据操作,因此在驱动结构体中需要提供三个变量以保存数据,示例如程序清单 24:

程序清单24


typedefstruct {

VOID   (*DMAT_pfuncStart)(UINT      uiChannel,

PVOID    pvArg);   /* 启动本次传输之前的回调*/

PVOID  *DMAT_pvArg;                        /* 回调函数参数          */

VOID   (*DMAT_pfuncCallback)(UINT      uiChannel,

PVOID    pvArg);

/* 本次传输完成后的回调函*/

} LW_DMA_TRANSACTION;

2.3      DMA传输参数

在LW_DMA_TRANSACTION结构体中除了一些DMA回调函数,还有一些重要的DMA参数,实例如程序清单 25:

程序清单25


typedefstruct {

UINT8   *DMAT_pucSrcAddress;                   /*  源端缓冲区地址    */

UINT8   *DMAT_pucDestAddress;                  /*  目的端缓冲区地址  */

size_t     DMAT_stDataBytes;                     /*  传输的字节数       */

INT      DMAT_iSrcAddrCtl;                      /*   源端地址方向控制  */

INT      DMAT_iDestAddrCtl;                     /*  目的地址方向控制  */

INT      DMAT_iHwReqNum;                     /*  外设请求端编号    */

BOOL    DMAT_bHwReqEn;                      /*  是否为外设启动传输*/

BOOL    DMAT_bHwHandshakeEn;                /*  是否使用硬件握手   *

INT      DMAT_iTransMode;                      /*   传输模式, 自定义  */

PVOID   DMAT_pvTransParam;                    /*  传输参数, 自定义   */

ULONG  DMAT_ulOption;                        /*  体系结构相关参数   */

PVOID   DMAT_pvArgStart;                      /*  启动回调参数       */

(回调函数上小节已经单独说明)

} LW_DMA_TRANSACTION;

typedefLW_DMA_TRANSACTION    *PLW_DMA_TRANSACTION;

DMA 操作的是物理地址, 所以 Src和 Dest地址均为物理地址。有些系统CPU 体系构架的 CACHE 是使用虚拟地址作为索引的, 有些是使用物理地址做索引的。所以 DMA 软件层不处理任何 CACHE 相关的操作, 将这些操作留给驱动程序或应用程序完成。

2.4      DMA API函数简介

程序清单26


LW_API  INT     API_DmaDrvInstall(UINT              uiChannel,

PLW_DMA_FUNCS     pdmafuncs,

size_t            stMaxDataBytes);      /*  安装指定通道的 DMA 驱动程序 */

LW_API  INT     API_DmaReset(UINT   uiChannel);                       /*  复位指定的 DMA 通道         */

LW_API  INT     API_DmaJobNodeNum(UINT   uiChannel,

INT   *piNodeNum);                 /*  获得当前队列节点数          */

LW_API  INT     API_DmaMaxNodeNumGet(UINT   uiChannel,

INT   *piMaxNodeNum);          /*  获得最大队列节点数         */

LW_API  INT     API_DmaMaxNodeNumSet(UINT   uiChannel,

INT    iMaxNodeNum);           /*  设置最大队列节点数          */

LW_API  INT     API_DmaJobAdd(UINT                        uiChannel,

PLW_DMA_TRANSACTION    pdmatMsg);  /*   添加一个 DMA 传输请求     */

LW_API  INT     API_DmaGetMaxDataBytes(UINT   uiChannel);               /*  获得一次可以传输的最大字节数*/

LW_API  INT     API_DmaFlush(UINT   uiChannel);                         /*  删除所有被延迟处理的传输请求*/

/*********************************************************************************************************

API 中断服务函数

*********************************************************************************************************/

LW_API  INT     API_DmaContext(UINT   uiChannel);                     /*  DMA 传输完成后的中断处理函数*/

#define  dmaDrv                   API_DmaDrvInstall

#define  dmaReset                  API_DmaReset

#define  dmaMaxNodeNumGet        API_DmaMaxNodeNumGet

#define  dmaMaxNodeNumSet        API_DmaMaxNodeNumSet

#define  dmaJobAdd                API_DmaJobAdd

#define  dmaGetMaxDataBytes       API_DmaGetMaxDataBytes

#define  dmaFlush                 API_DmaFlush

如程序清单 26是SylixOS中内核定义的DMA模块,具体函数使用方法和调用流程在下篇文章中会做详细介绍。

时间: 2024-10-17 14:44:49

SylixOS DMA子系统之一的相关文章

【DMA】配置及使用

DMA(Direct Memory Access)直接储存器访问 dsPIC33F DMA子系统使用双端口SRAM储存器(DPSRAM)和寄存器结构,这种架构无需进行周期挪用. 周期挪用的意思就是(也叫周期窃取)当CPU和DMA都需要访问储存器时,DMA优先级高于CPU,会使CPU暂停.当CPU正在访问储存器时,DMA则需等待CPU处理完再进入.按手册的说法,这710就是没有周期挪用的. DMA也需要触发,可以用定时器和外部中断进行触发,我们一般习惯用定时器,每个DMA通道都是单向的,要进行读写

(转)DMA(Direct Memory Access)

DMA(Direct Memory Access) DMA(Direct Memory Access)即直接存储器存取,是一种快速传送数据的机制. 工作原理 DMA是指外部设备不通过CPU而直接与系统内存交换数据的接口技术. 要把外设的数据读入内存或把内存的数据传送到外设,一般都要通过CPU控制完成,如CPU程序查询或中断方式.利用中断进行数据传送,可以大大提高CPU的利用率. 但是采用中断传送有它的缺点,对于一个高速I/O设备,以及批量交换数据的情况,只能采用DMA方式,才能解决效率和速度问题

windbg命令详解

DLL 该扩展仅在内核模式下使用,即使它是在Ext.dll中的. Windows NT 4.0 Ext.dll Windows 2000 Ext.dll Windows XP和之后 Ext.dll 注释 如果不提供参数,调试器会列出所有进程,以及时间和优先级统计.这和使用!process @#Process 0 作为CommandString值一样. To terminate execution at any point, press CTRL+BREAK (in WinDbg) or CTRL

SylixOS USB虚拟网卡框架

1. USB子系统简介 1.1      USB简介 USB,是英文Universal Serial Bus(通用串行总线)的缩写,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯.是应用在PC领域的接口技术.USB接口支持设备的即插即用和热插拔功能.USB是在1994年底由英特尔.康柏.IBM.Microsoft等多家公司联合提出的. 1.2      USB虚拟网卡框架 1.2.1   普通网卡与USB网卡框架对比 如图 11所示,普通网卡驱动与USB网卡驱动相比最大的区别是,USB网

SylixOS 中断响应时间测试

1.应用场景 在一些情况下,对于一些紧急的中断任务,系统需要为其提供稳定可靠的中断响应时间,但一般的中断服务函数,它的响应时间可能会受到其他中断向量的影响,延迟响应.在SylixOS中有两种解方案. 1.提高该中断向量优先级,打开中断嵌套来确保紧急中断的响应时间. 2.对于多核处理器,可以采用中断绑核的形式,即将紧急中断绑定到某一核上,该核只处理紧急任务. 下面通过测试正常情况下.中断嵌套情况下.中断绑核情况下的中断响应时间,来对比采用上述两种方式的优点. 2.中断响应时间测试方案 使用示波器自

DMA过程分析

1.1 当我们在应用程序中编写write系统调用,向磁盘中写入数据时,写入请求会先调用底层写函数,将请求先写入内存中的页快速缓存(page cache)中,写入成功则立马返回,真正的写入磁盘操作会延迟运行.Page cache是硬盘在内存中的一个缓存,是linux内核所使用的主要磁盘快速缓存,在绝大多数情况下,内核在读写磁盘时都引用page cache(极少数应用会绕过页快速缓存,如数据库软件). 当把page cache中的一页数据写到块设备之前,内核首先检查相应的页是否已经在快速缓存中,假设

SylixOS 之epoll异常分析

1. SylixOS epoll介绍 SylixOS为了兼容Linux的epoll,创建了epoll的兼容子系统,并支持了epoll的部分功能.SylixOS epoll兼容子系统是由select子系统模拟出来的,所以效率没有select高. 2. epoll异常分析 2.1epoll异常场景 在使用线程A创建AF_UNIX匿名套接字发送数据:线程B把套接字加入epoll监听,且设置属性为一次有效:线程C等待epoll事件产生,并读取套接字中的数据.如程序清单 2-1所示.           

驱动移植过程中DMA内存相关接口替换

1. 相关概念介绍及移植简介 1.1 物理地址与总线地址         1)物理地址是与CPU相关的.在CPU的地址信号线上产生的就是物理地址,在程序指令中的的虚拟地址经过段映射和页面映射后,就生成了物理地址,这个物理地址被放到CPU的地址线上.         2)总线地址,顾名思义,是与总线相关的,外设使用的就是总线地址.         在x86平台下,外设的I/O地址是独立的,即有专门的指令访问外设I/O,I/O地址就是所谓的"总线地址".而"物理地址"就

Framebuffer子系统【转】

本文转载自:http://blog.csdn.net/av_geek/article/details/40897115 本文将介绍Framebuffer子系统 目标平台:TQ2440 CPU:s3c2440 LCD设备:3.5英寸,分辨率320X240 1. 概述 Framebuffer,中文名字是帧缓冲,这个帧也就是一副图像所需要的数据.因此,帧缓冲其实就是LCD设备的驱动程序.Linux中,framebuffer子系统框架如下: 核心层的代码以fbmem.c为主,核心层包括许多与具体硬件无关