文档章节

SylixOS DMA子系统之一

B
 BEST_CC
发布于 2017/06/21 11:19
字数 1180
阅读 3
收藏 0
点赞 1
评论 0

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模块,具体函数使用方法和调用流程在下篇文章中会做详细介绍。

© 著作权归作者所有

共有 人打赏支持
B
粉丝 1
博文 10
码字总数 12371
作品 0
南京
SylixOS-IgH系统平台搭建

1.参考手册 下面7个文件存放在本地服务器“\10.9.1.113.研发部9.ExchangeFolder郑磊”路径下 《RealEvo-IDE使用手册》 《SylixOS应用开发手册》 《SylixOSshell用户手册》 《SylixOS-IgH使用...

zhengleich ⋅ 05/15 ⋅ 0

SylixOS 支持多核 RISC-V 处理器

2018年3月31日,SiFive 发布全球首款多核全功能 RISC-V 处理器:FU540,此款处理器也是全球第一颗有能力运行标准 Linux 的 CPU。 22天后,SylixOS 成功在 FU540 真机上运行起来,成为全球第一...

翼辉信息 ⋅ 04/22 ⋅ 0

SylixOS 在 t_main 中使用硬浮点方法

1. 问题描述 在某些使用场景中,应用程序不使用动态加载的方式执行,而是跟随BSP在 t_main 线程中启动,此时应用代码是跟随 BSP 进行编译的。由于 BSP 默认使用软浮点,所以会导致应用代码中...

zhywxyy ⋅ 前天 ⋅ 0

SylixOS中ARM架构的MMU实现分析

1. 理论知识 1.1 快表(TLB)与页表 在虚拟页式存储管理中设置了快表(TLB),用于保存正在运行进程页表的子集,通常快表存放在高速缓冲存储器(Cache)中。 而页表存放在内存中,并通过特殊...

zhywxyy ⋅ 05/02 ⋅ 0

SylixOS DMA子系统之一

1. DMA子系统简介 1.1 DMA简介。 DMA的英文拼写是“DirectMemory Access”,是一种数据不经过CPU处理,直接由DMA控制器从一块物理内存搬运到另一块物理内存的数据交换模式。在DMA模式下,CPU...

Best_CC ⋅ 2017/06/21 ⋅ 0

SylixOS x86中断探测(二)

MP Spec简介 MP Spec即MultiProcessor Specification,简称MPS,中文翻译为多重处理器规范,定义了MP系统配置的数据结构。BIOS构建MP配置数据结构,将硬件以已知格式呈现给标准设备驱动程序或...

huikai309 ⋅ 02/28 ⋅ 0

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

1. 相关概念介绍及移植简介 1.1 物理地址与总线地址 1)物理地址是与CPU相关的。在CPU的地址信号线上产生的就是物理地址,在程序指令中的的虚拟地址经过段映射和页面映射后,就生成了物理地址...

炉yu ⋅ 2017/09/11 ⋅ 0

salt-api的权限控制,如何限制自定义的sls模块的执行

例如,使用saltapi用户在所有主机上执行自定义的sls模块名叫 abcd,里面只有一个init.sls文件。 ls abcd init.sls 写控制salt-api的权限文件eauth.conf,仅允许执行这个abcd模块,如何编写?...

LionelShen ⋅ 01/31 ⋅ 0

嵌入式硬实时操作系统--SylixOS

SylixOS是一款嵌入式硬实时操作系统,同其类似的操作系统,全球比较知名的还有VxWorks(主要应用于航空航天、军事与工业自动化领域)、RTEMS(起源于美国国防部导弹与火箭控制实时系统)、Threa...

jiaojinxing ⋅ 2014/01/22 ⋅ 0

Windows下Nginx+Tomcat配置

刚刚接触了下Nginx,发现很有趣就尝试了下,下面是我的一些配置,希望可以帮助大家。 需要的工具:Nginx和tomcat,Nginx下载地址:http://nginx.org/en/download.html,Tomcat版本任意,根据...

海岸线的曙光 ⋅ 2017/12/18 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 50分钟前 ⋅ 0

VS2015配置并运行汇编(一步一步照图做)【vs2017的链接在最后】

前言 我是上学期学的汇编,因为有vs又不想用课上教的麻烦的dosbox以及masm32,但是一直没找到高亮插件和能调试的(难在运行不了而找不到答案上,出现的错误在最后放出,还请先达们不吝指点)...

simpower ⋅ 今天 ⋅ 0

一起读书《深入浅出nodejs》-node模块机制

node 模块机制 前言 说到node,就不免得提到JavaScript。JavaScript自诞生以来,经历了工具类库、组件库、前端框架、前端应用的变迁。通过无数开发人员的努力,JavaScript不断被类聚和抽象,...

小草先森 ⋅ 今天 ⋅ 0

Java桌球小游戏

其实算不上一个游戏,就是两张图片,不停的重画,改变ball图片的位置。一个左右直线碰撞的,一个有角度碰撞的。 左右直线碰撞 package com.bjsxt.test;import javax.swing.*;import j...

森林之下 ⋅ 今天 ⋅ 0

你真的明白RPC 吗?一起来探究 RPC 的实质

你真的明白RPC 吗?一起来探究 RPC 的实质 不论你是科班出身还是半路转行,这么优秀的你一定上过小学语文,那么对扩句和缩句你一定不陌生。缩句就是去除各种修饰提炼出一句话的核心,而不失基...

AI9o後 ⋅ 今天 ⋅ 0

z-index设置失效?

今天碰到了一个问题,就是在给li设置提示框的时候,有用到遮罩效果,本来想把对应的出现在最顶层,可是不管将li设置的z-index值设为多大,li都没有出现在遮罩层之上。 我在网上查了z-index设...

IrisHunag ⋅ 今天 ⋅ 0

CyclicBarrier、CountDownLatch以及Semaphore使用及其原理分析

CyclicBarrier、CountDownLatch以及Semaphore是Java并发包中几个常用的并发组件,这几个组件特点是功能相识很容易混淆。首先我们分别介绍这几个组件的功能然后再通过实例分析和源码分析其中设...

申文波 ⋅ 今天 ⋅ 0

Java对象的序列化与反序列化

Java对象的序列化与反序列化

Cobbage ⋅ 今天 ⋅ 0

Sqoop

1.Sqoop: 《=》 SQL to Hadoop 背景 1)场景:数据在RDBMS中,我们如何使用Hive或者Hadoop来进行数据分析呢? 1) RDBMS ==> Hadoop(广义) 2) Hadoop ==> RDBMS 2)原来可以通过MapReduce I...

GordonNemo ⋅ 今天 ⋅ 0

全量构建和增量构建的区别

1.全量构建每次更新时都需要更新整个数据集,增量构建只对需要更新的时间范围进行更新,所以计算量会较小。 2.全量构建查询时不需要合并不同Segment,增量构建查询时需要合并不同Segment的结...

无精疯 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部