基于ARM处理器的HDLC通信的DMA实现

2006-05-07 15:50:09来源: 互联网

微控制器(Networking MCU)为基础,重点论述如何通过DMA(直接内存访问)方式实现HDLC通信。对软件设计中缓冲描述符、DMA状态配置和控制、ISR服务程序设计以及相关的硬件配置进行详细的描述,并讨论如何编写在操作系统下的驱动程序。

目前在嵌入式产品开发设计中,通常是在OS(Operating System)厂商提供的BSP基础上进行开发工作;对于底层硬件的操作,程序设计人员很少关注或只是少量的修改。实际上很多产品,我们完全可以抛开操作系统的模式,避免不必要的系统开销,而对底层的硬件直接进行处理。这样,可以节省资源提高利用率。当然,这样也会人为地增加系统开发设计的难度。但是从长远的角度看,进行这样的设计思考还是非常必要的。现在一些产品的设计开发中,所缺少的实际上就是深入了解底层操作,这样往往使我们丢失了创新的机会。

本文主要分析如何在硬件基础上直接进行程序设计,介绍如何在底层进行HDLC通信控制操作,以及如何处理数据结构等方面的问题。对于进行驱动程序的设计以及进行系统设计,都提供了良好的借鉴。

1 S3C4510B以及HDLC模块

S3C4510B是三星公司生产的以ARM(Advanced RISC Machines)16/32bits的RISC ARM7TDMI微处理器为内核的一种网络微控制器(NETMCU,Networking MCU),主要用于网络产品(如MUB、Router、HomePNA、SOHO)的开发设计。这款MCU在ARM7TDMI处理器的基础上,外加2个通道的HDLC控制器、I2C总线和2个通道串行接口、1个MAC控制模块以及统一的MII界面,提供10MHz/100MHz以太网的自适应连接。对于网络产品的设计提供了灵活的支持。

在软件开发设计方面,NetMCU使用的是ARM7TDMI处理器内核,所以支持ARM的开发工具(如WindRiver的Tornado、ARM的ARMstd251等)都对其适用,方便用户开发设计,最大限度地获得支持资源。

1.1 S3C4510B中的HDLC模块

S3C4510B的HDLC(High-level Digital Link Controller)控制器拥有2个串行通道。HDLC模块支持符合SDLC标准和HDLC标准的CPU/数据通道接口,包含2个DMA引警;支持使用对应帧的缓冲区描述符结构,而且可以灵活地配置通道物理编码模式(NRZ,FM,MAN),选择本地或者外部时钟;支持通过锁相环路从接收数据流提取时钟信号。使用的HDLC的帧结构如表1所列。

表1 

开始标志 地址域 控制域 信息域 帧校验 结束标志
7EH 2/4 Bytes 1Byte 8 bit/Byte 16 bit CRC 7EH

图1是S3C4510B HDLC控制器功能结构,主要包括总线仲裁单元、DMA控制器、8字的发送接收(Tx/Rx)FIFO、状态/控制寄存器和物理收发器。总线总裁单元负责向CPU申请系统总线;DMA控制器使用缓冲描述符在无CPU干预下控制数据帧的收发;8字(字=32bit)FIFO结构对CPU和串行接口的数据进行立即存储;物理收发器控制HDLC通道的运行模式、编解码等;状态/控制寄存器是运行的核心,程序设计人员通过设置,检测这些寄存器控制数据的收发。

1.2 中断模式和HDMA(HDLC DMA)模式

(1)中断模式

HTxFIFO结构通过把帧数据分别写入“帧连续地址”和“帧结束地址”控制发送行为;接收时,作为中断响应,读取HDLC状态寄存器,如果RxFA=1,则可以由CPU从HRxFIFO结构读取数据,直到最后一个Byte标志设置。中断模式下CPU去处理每一次数据的收发。对于一个长帧的数据,通常需要多次CPU进行干扰去填写(或读取)FIFO,导致过多的系统处理开销(overhead),占用CPU资源。如果在有多个外部中断源的系统中,CPU利用效率十分低下。

(2)DMA模式

使用缓冲描述符BD(Buffer Descriptor)结构,可以实现以帧为单位对数据进行接收和发送控制。程序设计人员只需要填写相应BD结构的域信息,配置收发模式,具体的执行细节交给DMA单元控制完成。CPU只是对每一帧进行处理,这样在一帧收发的过程中,系统可以去处理其它的任务,有效地利用CPU资源。关键在于构建BD循环链表。同时应该注意,BD及其对应的缓冲数据区必须放在系统存储区的非缓存区(NonCache),这可以通过设置地址的第26位为1来实现。

1.3 缓冲描述符(BD)

缓冲描述符是S3C5410B使用的一种数据结构,通常构成循环链表。HDMA引擎可以直接读取结构的信息,用户通过填写这些结构中的域去控制HDMA的运行行为。如图2所示,每个BD包括4个域:

①数据缓存指针(data buffer pointer)。第31位标识主权(ownership)关系,表示当前的BD在DMA(1)控制器和CPU(0)之间的所属关系,通常在发送和接收时要对其检查。对于数据长度,通常在发送时写入BD的帧长度域,DMA引擎会根据其发送相应长度的数据。接收数据长度会自动写入这个域。

②保留域。发送BD(Tx),低8位表示发送控制(如前同步信号、CRC模式、BIG/LITTLE端选择等);接收BD(Rx),保留未用。

③长度域。发送BD,用户写入发送帧的数据长度;接收BD,DMA控制器写入接收帧的数据长度。

④Next BD指针。指向下一个BD,收发BD各自构成一组BD链。

HDMA控制器在使用过一个BD后,会自动读入下一个BD,装入HDMA指针寄存器(HDMAXxPTR)。使用指针gpXxBDStart,指示当前的可用BD位置。在设备中定义为全局变量(X表示T或R)。

1.4 重要的数据类型

BD结构的定义如图2所示。

typedef struct BD{

U32 BufferData Ptr;

//数据缓存区指针,其中第31位标识BD的所有权

U32 Reserved;

//发送BD控制位,定义发送时操作的模式,接收BD保留

U32 StatusLength;

//运行状态,在ISR中检测,也定义对应的数据缓存区的长度

struct BD *NextBD;

//下一个BD指针

}sBuffer Descriptor;

HDLC帧(Frame)定义(如表1):

typedef struct HDLCFRAME{

U8 address[4]; //地址

U8 control; //控制信息通道为FFH

U8 information[1505]; //信息域,有效的数据

}sHdlcFrame;

HDLC设备结构定义:

typedef struct HDLC_Device {

U32 HDLC_Port; /HDLC通信号

U32 HDLC_Baud; //HDLC波特率

U32 HDLC_Data_format;

//HDLC数据格式,NRZ,NRZI,FM0,FM1,Manchester

//……时钟选择(发送/接收时钟源)……

sBufferDescriptor gpTxBDStart;/*当前的发送BD指针Start of TX BDs*/

sBufferDescriptor *gpRxBDStart; /*当前的接收BD指针Start of RX BDs */

//……状态统计信息(Abort,CRC error,Null list)……

}Hdle_End_Device;

由于在中断服务程序入口无法传递参数,故定义设备为全局变量,程序设计中使用指针传递,提高效率。

Hdlc_End_Device Hdle_Dev; //全局定义

Hdlc_End_Device *pDevice; //函数内部定义

pDevice=(Hdlc_End_Device *)&Hdlc_Dev;

1.5 使用DMA方式的程序设计

(1)初始化流程

初始化流程如图3所示。

void HdlcInit(void); //系统启动HDLC主初始化函数

Int HdlcChannelInit(Hdlc_End_Device *pDrvCtrl); //关闭中断源、复位DMA控制器和HDLC控制寄存器、设置相关的寄存器、时钟源

void TxBD_initialize(U32 channel,Hdlc_End_Device *pDrvCtrl);

void RxBD_initialize(U32 channel,Hdlc_End_Device *pDrvCtrl);//初始化发送接收BD链,gpXxBDStart指针指向第1个BD,HDMAXXPTR寄存器装入第1个BD地址void HdlcChannelStart(U32 channel); //连接中断服务程序,打开中断,启动接收

(2)HDMA发送过程中断服务程序

HDMA发送过程及中断服务程序如图4所示。void Transmit_Frame(Hdlc_End_Device *pDrvCtrl);//准备数据调用HdlcFramsSend()

Int HdlcFrameSend(Hdlc_End_Device *pDrvCtrl,U8 *pData,U32 len);

在发送过程中,首先检查gpTxBDStart指向的BD的所有权:如果为DMA所用,应当退出;如果CPU拥有,则可按照HDLC帧的格式填入gpTxBDStart指向的BD对应的缓冲数据区,然后设置BD的控制信息,设置所有权关系为DMA和LASTF指示位,启动发送(使能Tx、TxDMA),并把gpTxBDStart移到下一个位置。

void HdlcTx_Isr(void);//发送中断服务程序,通常只做检测任务,生成错误统计报告

(3)HDMA接收过程及中断服务程序

HDMA接收过程及中断服务程序如图5所示。

void HdlcRx_Isr(void); //如果接收正常完成,调用

//HdlcFrameReceive ();

void HdlcFrameReceive(Hdle_End_Device *pDrvCtrl,U32 IntHDLCStatus);

void HdlcFrameDataGet(Hdlc_End_Device *pDrvCtrl,U8 *pFrameData,U32 len);

数据到达,进入接收中断服务程序。如果接收1帧完成标志位(RxFA)设置,可以进入数据接收程序,由HdlcFrameDataGet()负责把数据从接收缓冲数据区送用户数据区,进行处理;如果错误,生成错误类型报告。

数据接收完毕,应该把当前的BD交还给接收DMA控制器,设置对应的所有权为DMA,然后把gpRxBDStart移到BD链中的下一个位置。

2 操作系统(OS)设备驱动接口

虽然程序是在ARMstd251中编译,但是整个结构基本是按照驱动程序设计思路,可以通过局部更改转化为OS驱动程序。

在HDLC控制中,如何生成BD链和相应的数据缓存区,是一个关键的问题。通常在无操作系统开发的环境中,这些相应的存储器分配可以采用全局的方式,固定在相应的系统内存区域,并遇射到Noncache区,使用指针快速访问。

在使用OS的情况下,例如pSOS、VxWorks,相应的存储器分配采用动态(calloc())的方式,尤其需要注意的在退出前必须回收资源。驱动程序设计的目的要为OS提供一个透明(Transparent)的接口,实现OS的I/O例程和硬件驱动无缝衔接。

同时,构建一个良好的设备结构也是十分必要的,可以方便设置、加载和卸载处理。

关键字:处理器  通信  实现

编辑: 引用地址:http://www.eeworld.com.cn/gykz/GYTX/200605/430.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
论坛活动 E手掌握
微信扫一扫加关注
论坛活动 E手掌握
芯片资讯 锐利解读
微信扫一扫加关注
芯片资讯 锐利解读
推荐阅读
全部
处理器
通信
实现

小广播

独家专题更多

富士通铁电随机存储器FRAM主题展馆
富士通铁电随机存储器FRAM主题展馆
馆内包含了 纵览FRAM、独立FRAM存储器专区、FRAM内置LSI专区三大部分内容。 
走,跟Molex一起去看《中国电子消费品趋势》!
走,跟Molex一起去看《中国电子消费品趋势》!
 
带你走进LED王国——Microchip LED应用专题
带你走进LED王国——Microchip LED应用专题
 
电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2016 EEWORLD.com.cn, Inc. All rights reserved