前言:中文期刊网精心挑选了驱动程序设计范文供你参考和学习,希望我们的参考范文能激发你的文章创作灵感,欢迎阅读。
驱动程序设计范文1
关键词:PCI; vxworks;驱动程序;运动控制卡
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2012)29-6966-03
VxWorks是目前世界上用户数量最大的实时嵌入式操作系统, 它具有高度可剪裁的微内核结构、高效的多任务调度、灵活的任务间通信手段、快速灵活的I/O系统、确定的微妙级中断延迟时间等优点。
本文介绍了基于PCI 接口规范的通用运动控制卡在VxWorks下的驱动程序的设计。对其设计驱动程序需要对实时操作系统、实时软件设计、硬件设备有深入的了解。因此, 该设计不仅本身具有很高的应用价值, 也为实时驱动程序的设计提供了一个样例。
1 系统组成
在基于微机的数据采集、处理与控制系统中,计算机接口卡常常是其中的关键硬件设备。目前在运动控制领域,各类运动控制卡得到广泛运用,其中以工控机通过ISA或PCI等系统总线连接运动控制卡的主从式结构最为流行,由工控机发出控制指令和参数,控制卡根据接收到的指令及参数完成具体控制功能。由于PCI总线的高速和即插即用特性,使其取代ISA被广泛应用于高速数据采集与传输等系统中,有效地解决了实时采集、实时传输和实时存储等问题。
2 PCI 配置空间
PCI系统具有三种地址空间:存储器空间、I/O空间和配置空间。每个PCI设备都有64个配置双字用于实现配置寄存器,64个配置双字分为两部分,⑴PCI协议定义了开头16个双字的格式和用途,称为设备的配置头区域;⑵其它48个双字的用途是由设备指定的。目前PCI协议定义了两种头区域格式,第1类配置头区域用于定义PCI-PCI桥,而第0类配置头区域用于定义其它PCI设备。所有的PCI设备,包括PCI-PCI桥都必须实现下述配置寄存器:厂商标志、设备标志、命令、状态、分类码、版本标志和头区域类型寄存器。如表1所示为PCI配置寄存器。这些寄存器对编程访问PCI设备至关重要,我们就是利用vendor ID 和device ID来枚举出对应的设备,再进一步获得设备的其他信息的。
3 驱动程序的开发
VxWorks 提供在指定目标系统上运行的板级支持包(BSP),本文选用的是针对pentium的板级支持包。VxWorks是支持PCI总线的,提供了一些库函数专门用来访问PCI设备。为了调用这些函数以方便开发,需要包含如下头文件"iosLib.h"、"pciConfigLib.h"、"pciIntLib.h"、"sysLib.h"和"pciLocalBus.h",还需要导入sysOutLong()和sysInByte()等函数。在config.h里面定义INCLUDE_PCI以添加VxWorks对PCI的支持,还可以定义PCI_CFG_TYPE为PCI_CFG_FORCE、PCI_CFG_AUTO 或 PCI_CFG_NONE,我们一般定义为PCI_CFG_NONE,Vxworks只需把配置好的信息读出来就可以了。
针对PCI 总线结构的数据采集模块,其驱动程序的主要开发步骤如下:确定设备的PCI 配置信息确定设备的内部存储器、寄存器基地址及中断号设备初始化中断服务程序设备各功能函数。以下按照程序执行的顺序分步骤给出源代码,并加以详细的说明。
4 结束语
利用上文所述的方法编写的驱动程序,达到了本项目所要求的性能指标,系统经过实际验证是高速稳定可靠的,而且由于PCI总线的即插即用特性,不需要用户去手动跳线,极大得方便了使用。
参考文献:
[1] microsoft msdn[EB].2001.
驱动程序设计范文2
关键词:MCP2515 嵌入式Linux 驱动 CAN
中图分类号:TP336 文献标识码:A 文章编号:1007-9416(2016)04-0000-00
1系统硬件结构介绍
本系统的硬件平台主要由OK2440开发板、基于MCP2515的CAN总线通信模块和以STC89C52为控制器的CAN节点模块组成。CAN通信模块用来完成OK2440开发板和STC89C52控制的节点模块之间的数据传输。
1.1 MCP2515功能简介
MCP2515是一款独立的CAN总线控制器,完全支持CAN V2.0B 技术规范。MCP2515 拥有六个验收滤波寄存器和两个验收屏蔽寄存器,通过它们可以过滤掉总线上不需要的报文,从而减少MCU关于处理CAN总线上无用数据的开销。MCP2515与MCU 的连接是通过业界标准串行外设接口来实现的。
1.2 TJA1050功能简介
TJA1050 是介于CAN控制器和物理总线之间的一种符合ISO 11898标准的高速CAN收发器。其最高速率可达1Mbit/s,而且它的电磁抗干扰EMI性极高,至少可以连接110个节点。在实际电路中,可为物理总线提供差动发送和为CAN控制器提供差动接收。
2 MCP2515相关驱动程序设计
2.1 Linux设备驱动简介
在Linux系统中,由于对硬件的操作必须处在特权模式下,在用户工作模式下,程序一般不能直接和硬件进行通信。因此,设备驱动程序则承担了用户模式下硬件和用户应用程序之间的通信工作,同时它还为应用程序和内核中其他的部分访问这些设备提供了程序接口。大多数设备驱动程序可以在系统工作时,以动态方式进行加载,在不需要的时候又可以将其卸载掉。
2.2 MCP2515驱动程序设计
2.2.1 MCP2515驱动初始化函数
在MCP2515的驱动初始化函数中首先通过s3c2440_spi_ioremap()函数将S3C2440上的SPI寄存器的物理地址映射到内核空间,这样才可以在驱动程序中访问和配置S3C2440的SPI寄存器。在正确的配置S3C2410的SPI寄存器后,通过s3c2440_spi_init()来完成对S3C2440相关寄存器的赋值。然后通过s3c2440_irq_init()函数来完成中断方面相关的设置。MCP2515_init()和MCP2515_dev_init()两个函数主要是针对于MCP2515控制器进行相关的配置和为MCP2515设备驱动程序申请和初始化内存空间。最后通过MCP2515 _cdev_register(Device0)函数完成MCP2515在内核中的注册。
2.2.2 MCP2515相关中断函数的注册
在CAN总线驱动程序中,CAN通信模块接收和发送数据必须以中断的方式与系统内核之间进行数据的交换,所以在MCP2515的驱动程序中必须用到内核中的相关中断函数。对于MCP2515的中断注册函数request_irq(),如果此中断注册函数返回值为0则表示中断注册成功,返回负数则表示注册失败。
2.2.3 MCP2515的文件操作函数
MCP2515_fops中定义了很多与设备有关的操作函数,内核可以通来它来访问与MCP2515操作有关的函数。在MCP2515的文件操作函数中,read()和write()两个函数是用来完成读写CAN总线上数据的功能的,通过传递不同的参数给驱动程序中的read()和write(),我们可以读取和写入相应的数据。驱动中的CAN总线读函数read()是整个驱动程序设计的难点,其中在函数的设计中采用了Linux内核阻塞机制。read()读取完CAN总线上的数据后,通过验收滤波寄存器和屏蔽滤波寄存器来决定总线上的数据帧是否存入到总线控制器相应的接收缓冲寄存器里。
2.2.4 MCP2515的卸载函数
当我们不需要继续使用某个设备时,我们可以将这个设备从内核中卸载掉。在设备的卸载过程中,必须将其内核中所对应的设备号释放掉。在模块的卸载函数中,我们通过调用int unregister_chrdev_region(unsigned int major,const char *name)函数来完成设备驱动的卸载。此函数的两个参数分别对应设备文件的主设备号和设备名。在卸载模块时,Linux内核会把设备名与内核中已注册的设备名称进行对比,如果两者相等,则完成设备的卸载,反之则卸载失败。MCP2515的驱动卸载函数主要是完成MCP2515驱动在内核中所占用的中断的释放和MCP2515在内核中的注销。
3 结语
本文重点讨论了S3C2440中MCP2515的驱动程序设计方法,并详细介绍了Linux系统下如何开发MCP2515的驱动程序的方法。实验结果表明,本文所设计的Linux下MCP2515驱动程序可以在OK2440开发板上正常运行,基本可以完成CAN总线上数据的正常发送与接收,测试结果符合论文的要求。本文提到的基于Linux下MCP2515驱动程序的开发,对其他Linux驱动程序的开发具有一定的启示作用。
参考文献
[1]宋宝华.Linux设备驱动开发详解[M].北京:人民邮电出版社,2008.
[2]杨庆华,张景元.单片机和MCP2515的CAN总线通信模块设计[J].单片机与嵌入式系统应用,2007.
[3]刘淼.嵌入式系统接口设计与Linux驱动程序开发[M].北京:北京航空航天大学出版社,2006.
驱动程序设计范文3
关键词:DSP;TMS320C6416;PCI Linux2.6;驱动程序;DMA
中图分类号:TP368.11 文献标识码:A文章编号:1007-9599(2012)04-0000-02
一、引言
数字信号处理器(DSP)在通讯、语音图像处理、数据加密等各方面得到越来越广泛的应用。TI C6000系列DSP芯片内嵌PCI接口,支持主/从模式的读写,以33MHz的工作频率和32位地址/数据总线进行数据传输,理论上最高可以支持132MByte/s的数据传输,在速度上远远超过DSP常用的HPI、McBSP总线,完全可以满足传输实时性的要求。
本文在Linux2.6内核下,以TMS320C6416 DSP数据加密卡为平台,研究了PCI设备驱动程序的开发方法。首先介绍了常规的以IO内存方式对DSP进行读写操作的方法,接着结合DSP芯片特点,提出了一种基于DMA传输方式的DSP加密卡控制方法,与常规方法比,显著地提高了传输速度,具有较高的应用价值。
二、TMS320C6416的PCI接口
TMS320C6416是一款TI公司生产的DSP芯片,属于C6000系列。C6000系列DSP片内集成了一个主/从模式的PCI接口,可以通过PCI总线实现主机与DSP的互连。TMS320C6416的PCI接口由EDMA的地址产生硬件与DSP相连,支持PCI接口规范2.2版本[1]。
(一)PCI数据访问
DSP内嵌PCI主要包含三类寄存器:PCI配置寄存器、PCI I/O寄存器以及存储器映射寄存器。
PCI主机通过3个基地址空间(Base0-2)能够访问DSP全部的存储器映射空间。如图1所示,Base0空间定义了一段可预取4Mbytes的DSP存储器空间。Base1定义了8Mbytes不可预取的存储器空间。Base2定义了16Byte的I/O空间。当主机上电启动后,主机操作系统执行配置事务,将DSP的内存和I/O区域映射到主机处理器的地址空间,此段空间的物理地址,可以通过读取BASE0-2寄存器获得[2]。
三、Linux驱动程序开发
Linux下对TMS320C6416加密卡进行驱动程序开发,要完成的工作主要包括:对PCI设备的查找、初始化、卸载,对字符设备的数据读写和控制,中断处理等[3]。
(一)PCI设备初始化
在Linux2.6内核中,使用pci_driver结构体来定义PCI驱动。设备查找时通过id_table结构体中的的VENDER_ID、DEVICE_ID来区别不同的设备,对于TMS320C6416芯片,VENDER_ID和DEVICE_ID分别为0x104c、0xa106。
pci_driver结构体中的probe()函数向内核提供了对硬件进行探测并初始化的接口。probe()函数完成的功能有:
1.读取DSP加密卡Base0-2空间基地址和中断号,通过pci_read_config_dword()函数实现;
2.将IO内存空间映射到Linux内核虚拟地址空间。通过ioremap()函数实现;
3.申请DSP加密卡中断服务程序。通过request_irq()函数实现;
4.申请DSP加密卡的主设备号,注册DSP加密卡字符设备驱动程序。通过cdev_init()、cdev_add()函数实现。
初始化完成后,可以通过设置DSPP寄存器,访问BASE0空间读取DSP内存资源,基于I/O内存方式进行PCI数据读写关键代码如下:
static ssize_t dsp_read(struct file *fp, char *buf, size_t size, loff_t *f_pos)
{
outl(*f_pos, dsp_dev.iospace+IO_DSPP_OFFSET); //设置DSPP寄存器
copy_to_user(buf,dsp_dev.bar0, size); //拷贝DSP内存至主机
}
在实际使用中, TMS320C6416 PCI接口可以采用DMA方式进行数据操作,通过DMA控制器直接传输I/O数据,可大大提高与主机通信的吞吐量。
(二)基于DMA传输的加密卡控制
在Linux2.6内核中,file_operations结构体中的ioctl()函数向应用程序提供了对硬件进行命令控制的接口。以DSP加密卡加解密控制命令为例,加密卡加密命令要完成的操作是:通过DMA读操作将主机数据发送给DSP加密卡,等待DSP加密卡将数据加密完毕后,通过DMA写操作将加密数据回传给主机。详细步骤如下:
1.主机调用内核函数get_free_page()申请DMA空间,调用virt_to_bus()函数将内核空间虚拟地址转换成PCI总线地址,将此地址写入到DSP端PCIMA寄存器中;
2.主机访问Base1空间,调用writel()函数修改DSP端PCIMA、DSPMA寄存器配置DMA传输源地址、目的地址,修改DSP端PCIMC寄存器设置DMA传输方向并启动DMA传输[4];
3.DMA传输完成后,DSP端响应MASTER OK中断,在中断中释放信号量,开始数据加密操作。加密操作完成后,使用DMA方式将产生的密文数据回送给主机,并给主机发送中断;
4.PC机响应 中断,将密文数据拷贝至用户空间。
(三)用户态设备访问
Linux系统下可通过使用命令insmod将驱动程序编译生成的.ko文件插入到内核中,从而实现驱动程序的模块化动态加载。使用mknod命令创建由主、次设备号确定的加密卡设备文件,然后就可以像操作普通文件一样来操作DSP加密卡设备。打开设备文件后,就可以实现对设备进行诸如数据读写、设备控制等操作。
四、测试结果
在主机上编写测试程序,设置DSP的EMIF工作在100 MHz/133 MHz时钟,数据线为32位。PCI总线工作在33MHz时钟,使用DMA方式进行连续的数据读写,传输1GB的数据,测得DSP主模式下DMA方式数据写操作速度为90Mbytes/s,读操作速度为70MBytes/s,实验证明,所开发的驱动程序使用良好稳定,传输高效,满足高速数据传输和高速数据处理的需要。
参考文献:
[1]Texas Instruments.TMS320C6000 DSP Peripheral Component Interconnect(PCI)Reference Guide[Z].2007:20221
[2][美]Jonathan C,Alessandro R.LINUX设备驱动程序(第2版)[M].北京:中国电力出版社,2006
[3]宋宝华,华清远见.LINUX设备驱动开发详解[M].北京:人民邮电出版社,2010
[4]李静,赵保军.基于TMS320C6416内嵌PCI设备驱动程序开发[J].微机发展,2005(10):135-137
驱动程序设计范文4
嵌入式系统指的是为执行特定的功能而内置硬件和软件的电子控制系统。换言之,内置的是微处理器而不是一简单的单回路装置。即通过这些微处理器的运作从而执行所需的操作并管理程序的系统。
嵌入式系统开始应用于汽车、航天、航空、军事、医疗装备和工程制御等工业方面,现在应用范围扩大到家电产品、移动电话等,从而密切联系着我们的生活。特别是使智能手机和互联网接入成为可能的智能TV、超便携平板电脑、具有远程监控功能的...等已成为市场的主流。像智能手机,和小型综合无线通信电话机一样的新形态的产品的出世,使手机不到二三年已发展到一个新的范例。因为现阶段已经没有未配备微处理器和软的家电类产品,且现在软件和硬件方面技能的要求越来越高,所以说从这两方面来看的话,端嵌入式系统的发展速度将会猛增。
而目前的大中专院校,尤其本科阶段以上的高等院校,嵌入式系统工程人才培养相对落后。在这种情况下,许多高校为自动化、电子信息、计算机等专业设置了嵌入式系统等课程,但大部分高校的嵌入式系统实验都是基于ARM7的实验平台,已不能满足嵌入式系统教学发展的需要。
二、HBE-EMPOSⅢ-SV210简介
HBE-EMPOSⅢ-SV210是使用ARM公司的CortexTM-A8 Core,基于最新三星应用的S5PV210处理器,提供其各种功能及应用,开发的嵌入式平台。HBE-EMPOSⅢ-SV210适用处理器中提供的多样化的功能,可对处理器系统核心功能进行学习,以及内置了以实际生活中兴起应用的多样化设备。从HBE-EMPOSⅢ-SV210中理解以其连接设备的构造及驱动原理,可进行学习处理器与设备的应用,也是活用其他选配模块,多样化的设备及通信环境一起可进行实验练习的平台。
三、基于HBE-EMPOSⅢ-SV210的嵌入式驱动实验
在HBE-EMPOSⅢ-SV210中可完成的驱动程序设计有: LED 设备驱动程序、7-Segment 设备驱动程序、TextLCD 设备驱动程序、Dot Matrix 设备驱动程序、KeyPad 设备驱动程序、DIP Switch 设备驱动程序、OLED 设备驱动程序、Buzzer 设备驱动程序、GPIO-Button 设备驱动程序。
四、嵌入式驱动实验实例—蜂鸣器
HBE-EMPOSIII-SV210的Buzzer Controller通过由16bit构成的Buzzer_Ctrl_Reg (Buzzer Control Register) 控制。通过向 Buzzer_Ctrl_Reg 0 bit中写入 0 或者 1、可以关闭或打开 Buzzer。
下图表现了 Buzzer Control Register 的数据位构造。
Buzzer Control Register (read/write)
设备驱动程序通过 close 函数关闭时,利用 iounmap() 函数释放物理地址和虚拟地址。在 open() 函数中注册的 I/O 区域也释放。
通过 write 函数向设备驱动程序中写值时。驱动程序值写在映射的 (*addr) 存储空址中,空址 Buzzer。(0:off, 1:on)
rmmod 命令执行时被执行的例程。使用 unregister_chrdev() 函数释放字符设备驱动程序。
module_init 是内核装载 (insmod 执行时) 时指定内核调用的函数的宏,module_exit 是内核卸载 (rmmod 执行时) 时指定内核调用的函数的宏。
建立为了使用设备驱动程序的应用程序buz_test.c。
在buz_test.c代码中,利用 open 函数打开设备驱动程序。如果 /dev/buzzer 驱动程序正常运行,用户输入的数据值通过 write() 函数控制 Buzzer。(相关代码略,可以查阅实验箱配套指导手册)
实验步骤:
1)编译
现在,创建 Makefile 来编译两个文件。编译后多数的文件被生成。在这里,来观察研究 buzzer.ko 和 buz_test 这两个文件。buzzer.ko 是设备驱动程序目标文件,buz_test 是执行文件。
接下来,需要将模块插入到内核中。插入命令是 insmod,通过 mknod 装载设备驱动程序。Mknod 使用时,使用的主编号可以作为 insmod 命令语使用时出现的编号使用。主编号可以在 insmod 后查看 /var/log/messages 来了解。
如果设备驱动程序移植完成,运行 buz_test 程序,控制 Buzzer。./buz_test 1控制蜂鸣器发声,./buz_test 0关闭蜂鸣器。
五、总结
嵌入式驱动程序设计作为知识更新速度极快、教学内容越来越多的一门课程,需要教师在不断的教学实践和教学探索过程中,结合相应的实验设备,不断发现适合本校学生的教学方法和教学模式。
参考文献:
[1]邓春健,李文生,杨亮,刘伟.“ARM 嵌入式系统”课程教学方法研究[J].计算机教,2010(3):94-96.
[2]邱铁,吴国伟,刘晓艳.基于应用的高校嵌入式系统方向培养模式[J].计算机教育,2011(4):1-4.
[3]赵建勇,邬惠峰,嵌入式实验教学中液晶屏驱动实验创新与实践[J].杭州电子 科技大学学报(社会科学版), 2011(4):74-76.
[4]渠丽岩.让学生在快乐中学习:谈案例教学法在“单片机原理与应用”教学中 的应用[J].计算机教育,2009(18):93-95.
驱动程序设计范文5
关键词:程序设计教学 分组 任务驱动程序设计课程要求学生具有较强的逻辑思维和细心制作的能力,计算机真实地检验学生的程序是否做得出来而且有无错漏,这些要求使许多初学程序设计的学生有畏难情绪;传统的大班式教学从讲理论到上机编程验证程序的教学方法,往往使学生所做的程序达不到学习内容要求的结果,学生编程练习错漏多,学习效果参差不齐,制作软件的创造能力得不到提升,为此我们上程序设计课采用任务驱动教学法。
“任务驱动”是一种建立在建构主义学习理论基础上的教学方法,它将再现式教学转变为探究式学习,学生的学习活动必须与大的任务或问题相结合,以探索问题来引动和维持学习者学习的兴趣和动机,教师创建真实的教学环境,让学生带着真实的任务学习;在任务驱动教学法中学生必须拥有学习的主动权,教师则不断地挑战和激励学生学习取得进步。
在程序设计课程的教学中,教师采用任务驱动教学法大多是把任务布置给学生并作简单讲解后,由学生自己看书学习完成任务,学生的创新能力和独立分析问题、解决问题的能力明显提高,但这种教学法也有缺陷,主要是学生自学太多,总体学习效率较低,学生各自为证统一性差,而且没有改变不同层次学生学习的问题,鉴于这些原因,我们可把“任务驱动”和“分组”两种教学法结合起来应用,教学效果会更好。
一、分组
1、分组前的工作
分组前要对全班各个学生的学习能力和知识基础有全面深入的了解,要发现和培养学生中的学习带头人,这个过程往往要占去全部课程学习时间的1/3左右,在分组前的教学可用不分组的任务驱动教学法或讲解——上机——点评归纳的教学法,边教学边了解学生,同时教学的进行使学生打下一定的理论基础和制作技能。
2、怎样分组
一个班级有几十个学生,可分为若干个学习小组,但分组数不宜超过5组,组数太多使每组人数太少不便于对学生作统一要求,教师兼顾太多组亦会顾此失彼;每个小组要确立一至二名学习带头人作为学习小组长,同时兼顾学生间的友情和合作,方便互相学习,好中差三类学生适当搭配完成分组。
二、任务驱动下的分组学习
1、设置任务
教师精心设置任务是教学成功的第一步,如果要学习的新知识点多,我们可把教材中的每一章设计成一个大任务,再将大任务分为若干小任务,每一节又由一个或几个小任务组成;在教材和各种参考资料中会有许多练习题,任务驱动学习要求精选习题配合新知识点学习,而不是做大量习题的“题海战术”;如果已经把大多数的新知识点学完,我们就要设置综合程序设计任务,培养学生综合运用知识技能进行程序开发设计的能力。
对于同一章节的学习或同一部分内容所设置的任务,任务可准备多个,便于把任务分配到各个学习小组使用。
2、任务的分配
在分配任务到各个小组之前,教师应招集各个小组长进行研讨学习,小组长在教师的提点下提出自己学习并完成任务的思路,教师甚至可以让小组长先行去完成任务,使小组长能更好地带领全组同学完成任务。当这些准备工作做好后,就可以把任务分发到各个小组的学生中去,要让每个学生都明确完成任务要用到的新知识点和任务要求所要达到的目的,使他们有的放矢去学习并完成任务。各个小组间的任务可以相同,也可以不同。如果任务相同,在学生学习完成同一任务的过程中,教师把各个小组完成任务的优劣进行对比讲评,在各个小组之间形成竞争,提高学习效率,同时使对全班学生的统一要求达到更好的效果。如果各个小组的任务不同,可以使全班分小组学习应用不同的知识点,各个小组完成任务后进行小组之间的交叉对比学习,最终使各个小组都能完成多个任务,全班学生接触到更广阔的知识面,取得更高的学习效率。
3、任务的完成
完成任务的过程就是学生学习运用知识点进行程序设计的过程,在这个过程中学生是学习的主角,因为教师在之前已经培训了各个小组长,他们在各个小组学生学习完成任务的过程中要起到以点带面的作用,其实由已经学会了的学生去教那些正在学习的学生会有不错的教学效果。教师在这个过程中要做的就是督促和鼓励学生去完成任务,当然,对于学生的典型问题教师可以分小组或在全班进行讲解,保证不会因为“卡壳”造成学习效率的降低。
当各个小组的任务完成到一定程度时,教师要及时调用学生的程序,在全班进行演示点评,造成班级中各个小组之间一种竞争为了更好地完成任务的态势,同时也是小组之间相互借鉴学习的机会。通过这样的学习并完成任务的过程,各个学生按任务要求所做的作品既有个人的创造性,又能达到任务要求的统一标准,学生作品的水平普遍比其它教学方法要高得多。
4、任务的总结和测试
驱动程序设计范文6
关键词:S3C4510B;HDLC;驱动程序
中图分类号:TP316文献标识码:A文章编号:1009-3044(2007)06-11606-03
1 引言
HDLC作为一种基于点到点/多点的数据链路层协议,常常用来连接路由器和网关等网络设备。三星公司生产的S3C4510B微处理器是当前应用非常广泛的嵌入式微处理器,良好的性价比和强大的通信与网络协议处理能力以及丰富的通信接口支持使其非常适合构建VOIP网关;特别是其具有HDLC功能模块,因此可以通过它的一个HDLC接口来为VOIP网关和信令网之间提供链路支持。VOIP作为一种基于IP的数据传输技术,广泛地利用Internet全球互连环境,将传统的PSTN电话网和Internet网络合二为一,因此可以有效地降低系统成本和管理成本。作为一种高效且经济的数据和话音通信方式,它是当前技术研究和开发的热点。本文介绍如何在S3C4510B开发板上实现HDLC控制器的驱动程序,从而为信令网和网关之间提供链路支持。
2 HDLC简介
HDLC是一个在同步网上传输数据并面向位的数据链路层协议,具有透明传输、可靠性高、传输速率高以及灵活性高等特点。它采用点对点或多点(多路播送或一对多)连接的主/从结构,要求每个从站都唯一的地址,从站只有在允许通信时才能且只能和主站通信,这就消除了串行线路上由于几个从站同时发送引起冲突的可能性。其它的通用的二层协议如SS#7、AppleTalk、LAPB、LAPD等都是基于HDLC及其帧结构的。HDLC帧结构如图1所示。
图1 HDLC帧结构
Flag (F):标志位,每个HDLC帧以8位序列(01111110)标志帧的开始和结束,这是HDLC中仅有的两个包含连续六个1的可能组合。为了避免在其它域中出现这种组合,HDLC采用了一种叫作位插入的办法实现组合,即每发现有连接五个1时便在下一位自动插入一个0,接收器在收到连续五个1之后又自动删去插入的0。标志位除了标志帧的开始和结束外,还可用作时钟同步,接收设备不断地搜寻标志位,以实现帧同步,从而保证接收部分对后续字段的正确识别。另外,在帧与帧的空载期间,可以连续发送这种标志序列,用作时间填充。
Address (A) Field:目的地址位,用于指示报文发往何站。每个从站必须有唯一的地址,主站必须知道每个从站的指定地址。全“1”构成的地址在HDLC中定义为广播地址,全“0”构成的地址在
HDLC中定义为无站地址,用于测试数据链路的状态。
Control (C) Field:控制位,用于系统初始化、标志帧的序号,并在报文发送完成后通知从站响应,
对以前发送帧进行应答。尾随控制段的信息通常用于报文传输、出错报告和其它各种功能,这些功能由控制段的格式完成。有三种格式可供使用:报文格式、监控格式和无序号格式。
Information (I) Field:信息域,是可选的。如果信息存在,它必须有8位整数数量的长度。
Frame Check Sequence (FCS) Field:帧校验位,长度为16位,帧校验序列用于对帧进行循环冗余校验,其校验范围从地址字段的第一比特到信息字段的最后一比特的序列,并且规定为了透明传输而插入的“0”不在校验范围内。
HDLC常被用来向X.25、ISDN和帧中继网等提供信令和控制数据链路。
3 S3C4510B及其HDLC模块
S3C4540B是三星公司生产的一种通用的16/32位嵌入式网络控制器。它是以RISC体系结构为基础并在片内集成有微处理器和多种外设接口的专用通信芯片,具有强大的通信和网络协议处理能力,可广泛应用于各种通信和网络产品中。它主要由ARM7TDMI内核、2个通道的HDLC控制器、I2C总线和2个串行通道接口、一个MAC控制模块组成,提供10MHz/100MHz以太网的自适应连接,对于网络产品的开发设计提供了灵活的支持。
S3C4510B的HDLC(High- level Digital Link Controller)控制器拥有2个串行通道。HDLC模块支持符合SDLC标准和HDLC标准的CPU/数据通道接口,包含2个DMA引擎;支持使用对应帧的缓冲区描述符结构,而且可以灵活地配置通道物理编码模式(NRZ,FM,MAN),选择本地或者外部时钟;支持通过锁相环路从接收数据流提取时钟信号。
图2是S3C4510B HDLC控制器功能结构,主要包括总线仲裁单元、DMA控制器、8字(1字=32 bit)的发送接收(Tx/Rx)FIFO、状态/控制寄存器和物理收发器。总线仲裁单元负责向CPU申请系统总线;DMA控制器使用缓冲描述符在无CPU干预下控制数据帧的收发;8字FIFO结构对CPU和串行接口的数据进行立即存储;物理收发器控制HDLC通道的运行模式、编解码等;状态/控制寄存器是运行的核心,程序设计人员通过设置,检测这些寄存器控制数据的收发。
注:A/B为地址总线,D/B为数据总线,C为控制线
图2 S3C4510B的HDLC模块
4 驱动程序的设计思想及其实现
这里选择uClinux作为本CPU板的操作系统。uClinux是一种可移植、可裁减的嵌入式操作系统,以其良好的可靠性和开放性被广泛应用。因此,程序的设计必须按照这个操作系统的结构来构建。本文的主要目的是使用S3C4510B处理器的HDLC功能模块,以支持uClinux操作系统下的HDLC通信,所以程序的设计主要围绕这个目的进行,在此并没有按照传统驱动的模式构建驱动程序,而是直接对硬件进行操作。当驱动程序运行时,首先要进行HDLC通道的初始化,然后才开始执行收发功能,在这当中要加上中断控制。按照这个程序的基本流程,具体的实现分为下面几步
4.1 HDLC通道初始化
HDLC通道的初始化分为七个步骤;①HDLC通道复位,恢复其默认配置;②设置工作模式寄存器(HMODE)来配置HDLC工作模式;③设置控制寄存器(HCON)来控制HDLC通道的工作;④设置中断控制寄存器(HINT)来控制HDLC通道的中断产生;⑤设置站址寄存器(HSAR0-HSAR3)和站址屏蔽寄存器(HMASK),以完成接收操作的地址比较功能;⑥建立DMA方式的发送和接收BUFFER描述符链表结构,并初始化DMA发送BUFFER描述符指针寄存器(HDMATxPTR)和DMA接收BUFFER描述符指针寄存器(HDMARxPTR);⑦使能HDLC通道的收发功能。
4.2 HDLC通道数据发送及中断处理的实现
4.2.1数据发送
DMA方式下HDLC通道的数据发送通过以下几个步骤实现:
(1)读取发送帧描述符指针寄存器HDMATxPTR,得到当前发送帧描述符的地址,进而得到整个发送帧描述符的内容。
(2)得到发送帧描述符中帧数据BUFFER起始地址。
(3)将准备好的HDLC帧拷贝到BUFFER中。
(4)设置当前帧描述符中的相应控制位。
(5)将发送帧描述符的OWERSHIP位设置为DMA所有。
(6)使能HDLC的DMA发送。
完成上面各步骤后,HDLC通道的DMA机制会自动将BUFFER中的数据拷贝到HDLC通道TxFIFO中发送出去。一帧发送完毕后,S3C4510B自动将已使用的发送BUFFER描述符的OWERSHIP位设置为CPU所有,并将帧描述符指针寄存器HDMATxPTR中的内容更新为下一个未使用的发送BUFFER描述符地址。
4.2.2 数据发送的中断处理
当一帧数据通过DMA方式发送完毕,或者发送过程中出现了可引起中断的异常情况,此时软件会进入中断处理程序。引起中断的情况由中断控制寄存器的设置决定。在编程实现中,HDLC通道的中断处理主要完成以下工作:
(1)进入中断后,首先清除S3C4510B中断指示寄存器INTPEND中相应的标志位。
(2)如果DMA发送成功,则进行数据帧发送成功状态计数,并清除HDLC通道状态寄存HSTAT中的相应状态位。如果发送出现异常,则完成相应的异常状态计数,并清除HDLC通道状态寄存器HSTAT中的相应位。其中有两个异常会影响以后的DMA操作,a.发送下冲异常(TxU),发生此异常时,处理器会自动禁止DMA发送功能,因此下一次发送时必须重新使能DMA发送功能;b.下一个发送帧描述符指针为空异常(DTxNL),发生此异常时,说明建立的DMA发送BUFFER描述符链表结构出现了错误,因此需要重新初始化DMA发送BUFFER描述符链表结构。
(3)做完上述处理可关闭HDLC通道的DMA发送功能,等待有数据需要发送时再重新打开,也可以不关闭。
4.3 HDLC通道数据接收及中断处理的实现
4.3.1 数据接收
DMA方式下HDLC通道的数据接收工作主要在HDLC通道初始化和DMA接收中断处理中完成.在编程实现中,HDLC通道数据接收主要完成以下工作:
(1)通道初始化阶段,我们建立并初始化了HDLC接收BUFFER描述符链表结构,并将链表头节点的地址写入到HDLC接收BUFFER描述符指针寄存器HDMARxPTR,这是正确完成DMA方式接收的前提,下面的工作都是在这个前提下自动完成的。
(2)当有数据到来时,DMA机制会从HDMARxPTR指向的接收BUFFER描述符中找到接收BUFFER起始地址,然后把收到的数据写入到BUFFER中。
(3)如果接收无误,S3C4510B自动更新HDMARxPTR寄存器的值,使其指向下一个还未使用的接收BUFFER描述符,以备下一次接收使用。使用过的接收BUFFER描述符的OWERSHIP位将自动设置为CPU所有,因此为了能再次使用这个接收BUFFER描述符,必须将它的OWERSHIP位重置为DMA所有。
4.3.2数据接收的中断处理
DMA方式下HDLC通道接收完一帧数据,或者接收过程中出现了可引起中断的异常情况,此时软件会进入中断处理程序。引起中断的情况由中断控制寄存器的设置决定。在我们的编程中,HDLC通道接收中断处理主要完成以下工作:
(1)进入中断后,首先清除S3C4510B中断指示寄存器INTPEND中相应的标志位。
(2)如果DMA接收正确,则进行数据帧接收成功状态计数,并清除HDLC通道状态寄存器HSTAT中的相应状态位。对接收到的数据帧作相应的处理后,要重新将是用过的接收BUFFER描述符的OWERSHIP位设置为DMA所有。
(3)如果接收出现异常,则完成相应的异常状态计数,并清除HDLC通道状态寄存器HSTAT
中的相应位。其中有两个异常会影响以后的DMA操作,a.DMA接收BUFFER描述符不属于DMA所有(DRxNO);b.DMA接收BUFFER描述符指针空(DRxNL)。发生这两个异常时,说明接收BUFFER描述符双向环形链表结构出现错误,处理器会自动禁止DMA发送功能,因此建议重构接收BUFFER描述符双向环形链表结构并重新使能DMA发送功能。
5 总结
S3C4510B是一款性价比很高的ARM处理器,功能丰富,编程简单,并且可以配合几种嵌入式实时操作系统,如pSOS,NUCLEUS等。我们使用S3C4510B和uClinux操作系统,完成了底层控制软件,经过调试,该软件性能稳定。
随着各种电子,通讯产品对性能要求的日益提高,基于先进的ARM架构的各种32位微处理器也将得到越来越广泛的应用。因此,掌握了ARM处理器的使用和编程方法,必然能在工作中事半功倍,得到良好的结果和收益。
参考文献:
[1]三星公司.著.三星S3C4510B用户手册[M].北京:北京三星公司,1999.
[2]李驹光.ARM应用系统开发详解[M].北京:清华大学出版社,2004.