基于嵌入式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操作的驱动流程图
评论