综合资讯 在线阅读 原文阅读 在线商城 下载专区 DATASHEET 技术论坛 商务频道

嵌入式系统  单片机  D S P  EDA/PLD  接口电路  存储技术  显示光电  电源技术
传感/控制  模拟技术  通信网络  无线通信  电测仪表  消费电子  汽车电子

所在的位置:首页技术文章嵌入式系统正文
 
基于嵌入式Linux 系统的高速设备驱动程序实现
发布日期:2008-05-14 作者:徐煜 杨华 来源:微计算机信息

摘要:本文从工程应用角度出发,针对高速设备的传输特点,在嵌入式linux系统的驱动程序的一般结构基础上,进行设备驱动结构框架的改进,以满足高速数据流传输的需要。并以AT91RM9200与DSP的视频会议系统为例,说明该结构驱动程序的实现流程,并验证在嵌入式Linux系统高速数据传输应用的可行性与鲁棒性。
关键词:嵌入式Linux 驱动程序 高速设备

1 Linux驱动程序的研究现状

嵌入式系统已越来越广泛应用于通信领域。而Linux操作系统因为其内核小、开源以及可灵活裁剪等优点,在嵌人式设备中得到了广泛的应用。下面首先介绍嵌入式linux系统驱动程序的一般结构。

1.1 传统的驱动程序结构简介

Linux操作系统最基本的组成部分包括资源管理器、调度程序、介于硬件和应用软件之间的接口、网络管理器和文档系统管理器。本文主要阐述介于硬件和应用软件之间的接口——设备驱动程序的实现。

对于多数字符设备而言,其功能主要是数据的传输。驱动程序操作的一般流程是:当read()函数被系统调用时,首先对中断寄存器进行配置,并开中断,并进入中断等待函数。此时系统会调用schedule()函数,进行其他进程的执行。一旦有中断的产生,则根据中断寄存器判断是否为设备的读寄存器中断,即是否有数据到达。若是,则将该数据从寄存器所在的地址读入,并送至相应的内存。

1.2 传统驱动程序结构存在的问题

当设备的数据量足够大时,中断将会十分的频繁,而中断服务程序将会被反复的调用,这会使得系统长时间的处于核心态中,而无法相应其他进程的请求,且极大地增加了CPU 的负担。这在高速率、大吞吐量数据传输的应用中,是无法容忍的。

因此,我们不得不考虑针对现有的驱动程序的数据传输程序结构进行改进,以适应高速率的数据传输的需要。

2 Linux高速设备驱动的实现

2.1 采用DMA方式的驱动程序

首先使用DMA 的数据传输方式对原有的结构进行改进。

DMA(direct memory access)是直接存储器访问的意思,它可以让I/O设备上的数据直接与系统的内存进行通信访问,而不需要处理器的参与,大大降低了CPU的负荷,对于需要进行除数据传输外其他一些数据处理的嵌入式处理器是很有帮助的。程序执行步骤如下:

1.  配置寄存器,指示硬件开始传输数据;开中断,进程进入睡眠等待;

2.  硬件将数据写入DMA存储器,完成后产生中断;

3.  唤醒进程,中断服务程序进行中断的处理(如将数据传输到用户态内存)。

操作流程如图1所示。这一结构的驱动程序,相对于不使用DMA方式而言,能够很大降低CPU的占用率。但是,该驱动程序结构也有个明显的缺陷:当硬件进行DMA传输时,该进程进入了睡眠等待,只有等到中断之后,才能唤醒进程,这也意味着在DMA 的过程中,我们无法对该进程的其他线程做任何操作。换句话说,其他的线程也会被阻塞住。当数据量很大且对这些读取的数据处理复杂度很高时,很可能会造成以下的问题:在长时间的用户态上数据处理期间,有新的数据到达硬件,而核心态无法及时进行下一次的DMA读取操作,数据因此而丢失。这将是很严重的。特别,如果我们使用wait_for_interrupt ()函数进行中断的等待,甚至会使整个系统被阻塞,这对于多线程编程是不可接受的。

图1 DMA操作的驱动流程图               

    图2 改进的设备驱动流程图

2.2 驱动程序的进一步改进

基于以上几点,为了能够在Linux中实现高速设备的数据通信,对驱动程序结构作出进一步改进的设计。

在设备驱动程序的实现上,采用生产者-消费者模型与循环缓存相结合的结构。将从硬件设备到核心态内存的DMA传输看作生产者,而从核心态内存搬移到用户态的数据传输过程看作消费者;同时为DMA传输分配的核心态内存采用循环链的结构。

在驱动程序中,将read()函数作为设备读操作的主函数,实现消费者的功能。当read()每次被调用时,从DMA缓存链中读取当前指针所指的内存数据,通过copy_to_user()函数,将数据传出核心态,复制到用户态内存,以便后续的数据处理。

而在驱动程序中,Irq_service()函数实现生产者的功能,当有中断产生后,系统进入Irq_service(),表明一次DMA的传输结束,并且在Irq_service()中,设置下一次DMA传输的参数,包括DMA传输的数据大小、DMA传输的目标内存。之后,调用interrupt_sleep_on()函数,使得系统进入进程调度,等待下一次DMA的操作完成。一旦完成,就会产生中断并重复以上的过程。因此,作为生产者的Irq_service()函数,只要初始化后,就会在中断的触发下不断被调用。换句话说,只要有数据到达硬件设备,就会不断将其通过DMA的方式读入到核心态的循环缓存中。我们可以将DMA缓存在允许的情况下,开的大一些,因为当接收的数据呈现一种突发的状态时,较小的缓冲池可能由于不能及时地将数据取走而溢出,造成数据的丢失。

与此同时,还有个问题必须注意,即当read()函数将缓存池中的数据都搬完之后,仍然没有DMA的输入。此时,read()继续读取的话,显然会造成数据的错误,因此采用信号量是必须的。当信号量表明,DMA的缓存已空时,若应用程序调用read()进行读数据的话,将不做任何操作,并返回已读数据量为0。当信号量表明DMA的缓存为满时,将DMA读入的数据丢弃,并设置buff_full = 0。

除此以外,我们还必须对Linux驱动进行以下步骤的操作:设备的注册和注销、设备的打开和释放。通过register_chrdev()函数向系统注册设备的设备号,在设备使用结束后,可以使用unregister_chrdev()从内核注销设备,释放主设备号。在设备注册之后,由open()函数打开设备,close()释放设备。在驱动的初始化中,需要对DMA进行首次设置,以及缓存的分配。我们可以调用 get_free_pages()函数进行内存页面的分配,它会给DMA分配内存中连续的页面,这对于DMA是必须的,因为DMA操作的物理地址是连续的。在内存分配之后,我们进行中断的配置,通过调用函数request_irq()。接着调用request_dma() 函数对DMA进行申请注册。

最后,有一点不得不引起我们的重视,即DMA一致性问题。DMA一致性的问题是指当进行数据DMA方式读入时,由于没有经过CPU的处理,因此CPU的CACHE会认为该地址的内存没有被重写过,而实际该内存所存储的数据已被改变;当CPU需要处理该内存的数据时,由于认为数据没有改变,会直接调用CACHE内的数据,造成数据错误,一般表现为数据的重复。在实际操作中,我们可以通过禁用该内存的CACHE功能,来避免错误。在新版的Linux内核中提供dma_alloc_coherent()dma_free_coherent()函数进行DMA一致性内存的分配。

以上就是我们针对高速设备驱动改进的程序代码结构。该驱动程序结构通过将核心态的DMA操作与数据到拷贝以及用户态上数据的处理独立开来,依靠信号量进行相互的制约,可以有效的避免高速设备DMA操作的频繁性和大数据量处理的较长时间之间的矛盾。驱动程序的流程如图2所示。

3 应用实例

下面我们以视频会议系统为例,介绍基于以上结构的高速设备驱动程序的实现。

在视频会议系统中,AT91RM9200通过SPI接口与TI DM642 DSP芯片的McBSP接口相连进行图像数据的传输。由于数据吞吐量很大,采用一般结构甚至是一般的DMA结构的驱动程序都无法满足数据的接收要求,造成数据无法实时的数据处理。我们针对该系统的特点,对驱动程序按照以上结构作出改进,不但大大减轻了ARM处理器的负荷,同时能够有效的进行大数据量的传输和处理。

表1 驱动程序改进前后对比表

 

测得码率上限

性能测试描述

改进前

1Mbps

当码率接近1Mbps时,出现数据丢失

改进后

10Mbps

当码率达到10Mbps时,驱动仍然能够正常工作

 

在我们的系统中,由于SPI接口需要传输标清的视频压缩图像,码率一般为2Mbps,原结构的驱动程序在码率较高的情况下,会出现数据的丢失,而数据的丢失不但影响了当前帧的图像的质量,而且同时会造成后面多帧图像的质量严重下降,因而无法满足这样高数据率传输的需要。而经过改进的驱动程序经过测试,至少可以承受10Mbps码率的数据传输,验证证明该结构的驱动程序可以完全胜任高速设备的数据传输且经过长时间测试,性能可靠。

4 结束语

本文的创新点是提出了一种基于ARM芯片的高速数据传输的设备驱动实现方案。首先对嵌入式Linux驱动程序程序的传统结构框架进行了介绍。而在实际的应用中,为了能够适应高速率的数据传输,针对ARM芯片以及Linux操作系统的特点,对设备驱动程序进行了改进。最后,以视频会议系统为例,对该结构的驱动程序进行实现、测试和验证,可完全胜任高速设备的数据传输且性能可靠。不仅如此,该结构的设备驱动程序同样适合于嵌入式Linux系统的各种高速设备传输的应用。

 

 

参考文献

[1] Alessandro Rubini Linux Device Drivers 0'Reilly & Assocoates,Inc. 1998.

[2] Karim Yagbmour Building Embedded Linux System 0'Reilly Media,Inc. 2004.

[3] Linux kernel, version 2.4.30

[4] 雷锋成 方滨 李慧杰,嵌入式网络数字图像监控系统,微计算机信息.2006.9-2


 (全文结束)

信息发布:   转引自: 【 】 【打印】 【关闭
 相 关 文 章
谢谢,现在还没有相关信息...
关于我们 ┋ 友情链接


深圳市福田区海滨广场恒福花园恒华阁11F
电话:0755-88305872 传真:0755-88305880
Copyright©2005-2007 无忧电子开发网版权所有

粤ICP备05064233号