Linux设备驱动概述

本篇文章将介绍linux设备驱动开发的基本知识,带你快速拨开Linux驱动这团迷雾 。文章分为如下3个小节进行讲解:
1、设备驱动的概念和作用;
2、在无操作系统和有操作系统的情况下设备驱动的设计开发;
3、Linux设备驱动的重点、难点和学习方法 。
文章最后会给出一个简单的LED驱动在无操作系统和Linux操作系统下的实现示例 。
好,Let's go
 
1、设备驱动的概念和作用
大家都知道在Linux开发中是一个分层的思想,也就是说应用层、操作系统层、驱动层和硬件层分别独立,然后为上一层提供API接口 。对设备驱动通俗一点的解释就是:驱使硬件设备行动 。驱动与底层硬件直接打交道,按照硬件设备的具体工作方式,读写其寄存器,完成设备轮询、中断处理和DMA通信等 。设备驱动实际上充当了硬件和应用软件之间的纽带,在系统没有操作系统的情况下工程师可以根据硬件设备的特点自行定义接口,如对串口定义SerialSend()、SerialReceive(),对继电器定义RelayOn()、RelayOff()等 。而在有操作系统的情况下,驱动的架构则由操作系统定义,因为驱动架构也属于操作系统内核的一部分,驱动工程师必须按照相应的架构设计驱动,这样的话驱动才能融入操作系统内核中,并正常运行 。

Linux设备驱动概述

文章插图
 
2、在无操作系统和有操作系统的情况下设备驱动的设计开发
2.1、无操作系统的情况下
事实上,在许多情况下我们的程序也运行在无操作系统的环境中(裸机程序),因为对于那些功能比较单一、控制并不复杂的系统不需要多任务调度和文件系统等复杂的功能,用单任务架构完全可以很好的实现我们的需求,也就是在一个无限循环(单片机编程中的while(1)死循环)中夹杂着对设备中断的检测或者对设备的轮询 。这一部分的知识相信有过单片机编程经验的朋友一定非常熟悉了,下面是这种单任务软件的架构:
Linux设备驱动概述

文章插图
主函数
在这样的系统中,虽然不存在操作系统,但是设备驱动必须存在 。一般情况下每一种设备驱动都会定义成一个软件模块,包含.c文件和.h文件 。
2.2、有操作系统的情况下
当包含操作系统时,我们还需要将驱动融入内核,为了实现这种融合,必须在所有设备的驱动中设计提供给操作系统内核的接口,这类接口由操作系统规定(这是一个复杂的过程,在后续更新的文章中会由浅及深的说明) 。所以,存在操作系统的时候,驱动便成为了连接硬件和Linux内核的桥梁 。当设备成功注册到系统中,也就是让系统知道了我们需要使用的设备的存在之后,Linux会将设备映射到文件系统的文件和目录中,然后通过系统调用的接口open()、write()、read()、close()等即可访问我们的设备 。
3、Linux设备驱动的重点、难点和学习方法
Linux设备驱动的学习是一项浩繁和长久的过程,其中包含了如下重点和难点:
1、编写Linux设备驱动要求工程师有一定的硬件基础;
2、编写Linux设备驱动要求工程师有非常好的C语言基础,能灵活的运用C语言的结构体、指针以及内存动态申请和释放等;
3、编写Linux设备驱动要求工程师有一定的Linux内核基础,并不要求对内核的各个部分有深入的研究,但至少我们要明白驱动程序与内核的接口;
4、编写Linux设备驱动要求工程师有多任务并发控制和同步的基础,因为在驱动中会大量的使用自旋锁、互斥、信号量和等待队列等并发与同步机制 。
看到这里,相信你已经对Linux设备驱动有了基本的认识,首先我们要明白,Linux驱动程序是门槛最高难度最大的一部分,当然薪资也是相对最高的,所以只要我们掌握了方法坚持学习下去,一定可以拨开这团迷雾看见阳光 。笔者会定期更新关于嵌入式Linux和C语言在开发和学习中的经验和技巧 。欢迎关注!
 
文章的最后,给出LED驱动在无操作系统和Linux操作系统下的实现示例,以供大家作以比较 。LED一般直接由CPU的GPIO口控制,GPIO一般由两组寄存器控制,即一组控制寄存器和一组数据寄存器 。控制寄存器可设置GPIO口的工作方式为输入或输出 。当引脚被设置为输出时,向数据寄存器的对应位写入1和0分别在引脚上产生高电平和低电平;当引脚设置为输入时,读取数据寄存器的对应位可获得引脚上的电平高低 。
在无操作系统时的LED驱动如下:


推荐阅读