SylixOS DMA子系统之一
来源:互联网 发布:iptables禁止所有端口 编辑:程序博客网 时间:2024/06/08 17:23
1. DMA子系统简介
1.1 DMA简介。
DMA的英文拼写是“Direct Memory 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设备库,其原型如程序清单 2‑1:
程序清单 2‑1
#include <SylixOS.h>
INT API_DmaDrvInstall (UINT uiChannel,
PLW_DMA_FUNCS pdmafuncs,
size_t stMaxDataBytes)
函数API_DmaDrvInstall原型分析:
l 此函数执行成功返回PLW_DMA_FUNCS的地址。
DMA设备需要调用dmaGetFuncs函数绑定驱动并创建设备,其函数原型如程序清单 2‑2:
程序清单 2‑2
#include <SylixOS.h>
PLW_DMA_FUNCS dmaGetFuncs (UINT iChannel,
ULONG *pulMaxBytes)
函数dmaGetFuncs原型分析:
l 此函数成功返回ERROR_NONE,失败返回PX_ERROR;
l 参数iChannel:DMA通道号;
l 参数pulMaxBytes:最大传输字节数;
结构体PLW_DMA_FUNCS 详细描述如程序清单 2‑3:
程序清单 2‑3
typedef struct 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设备库中的结构体保存到驱动中以供缓冲区数据操作,因此在驱动结构体中需要提供三个变量以保存数据,示例如程序清单 2‑4:
程序清单 2‑4
typedef struct {
…
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参数,实例如程序清单 2‑5:
程序清单 2‑5
typedef struct {
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;
typedef LW_DMA_TRANSACTION *PLW_DMA_TRANSACTION;
DMA 操作的是物理地址, 所以 Src 和 Dest 地址均为物理地址。有些系统 CPU 体系构架的 CACHE 是使用虚拟地址作为索引的, 有些是使用物理地址做索引的。所以 DMA 软件层不处理任何 CACHE 相关的操作, 将这些操作留给驱动程序或应用程序完成。
2.4 DMA API函数简介
程序清单 2‑6
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
如程序清单 2‑6是SylixOS中内核定义的DMA模块,具体函数使用方法和调用流程在下篇文章中会做详细介绍。
- SylixOS DMA子系统之一
- linuxMTD子系统之一DMA(Direct Memory Access)
- SylixOS子系统原理--热插拔子系统
- SylixOS日志子系统简介
- SylixOS CAN驱动框架之一
- SylixOS热插拔子系统分析(二)
- Linux 驱动之DMA 子系统
- SylixOS与Linux接口对应关系之一
- input子系统驱动学习之一
- 资源供给:IO子系统之一
- SPI子系统分析之一:框架
- SylixOS下DMA操作带cache的地址时的处理
- Linux input子系统分析之一:软件层次
- android input子系统之一:驱动部分
- LINUX驱动之SPI子系统之一概述
- Linux input子系统分析之一:软件层次
- DMA
- DMA
- Java中Static Class及静态内部类和非静态内部类与静态导包
- Spring 源码分析(一) —— 迈向Spring之路
- android 5.0之后原生webview同时用https和http加载HTML不加载图片解决方案
- 现有spring mvc框架利用cxf发布webservice步骤
- ArcEngine Command控件
- SylixOS DMA子系统之一
- Oracle中的ROUND( )日期四舍五入函数
- springMvc处理ajax请求
- VS fopen_s与fopen支持
- vue-cli入门(三)——人员管理实例
- 手机Web开发 jQuery 获取屏幕高度、宽度
- 带有文字的 switch
- python3 xpath和requests应用
- POJ --- 2728 【最优比率生成树 --- 01分数规划】