当前课程知识点:嵌入式系统设计 > 第五章:嵌入式Linux驱动开发 > 5.2 Linux 设备驱动程序 > Video
首先看一下设备驱动程序的设计原则
这个原则主要体现在驱动程序的功能在于提供机制而不是提供策略
所谓的机制指的是需要提供什么样的功能
而策略指的是如何使用这些功能
驱动程序强调的是提供功能
不是告诉用户使用这些功能
Linux设备驱动程序的功能它体现在以下几点
1.设备的打开与释放
2.设备的读写操作
3.设备的控制操作
4.设备的中断和轮询操作
要实现这样的功能
具体的驱动程序就必须预定义以及添加必要的头文件
第一个预定义是这个_KERNEL_预定义
这个用于选择使用头文件的内核部分
也就是说明驱动程序属于Linux内核
第二个符号是MODULE
这个是由于Linux的驱动程序大部分是编译成模块
因此就需要包含这样一个符号
第三个为了确保模块是否能够安全地卸载
系统为模块保留了一个使用计数
这里是预定义和头文件的示例
可以看到我们首先定义的是_KERNEL_
第二个是MODULE
必要的头文件主要是内核的相关的头文件
最后是定义这个当前的计数
驱动程序的编译方式有两种
第一种是编译进内核,第二种编译成模块
前面谈到了模块的灵活性更高
所以常见的驱动程序都编译成模块
模块和应用程序的区别主要在于,
应用程序从头到尾完成一个任务
而模块则是为了以后处理某种请求而注册自己
完成这个任务后,它的主函数就终止了
以后要用这个模块的话
实际上是调用模块里面的函数
模块初始化和终止,相关的例子我们来看一下
初始化比如这个mydriver_init()
我们可以打印这样一条语句,作为一个例子
退出呢,我们可以打印这样一条
这两个函数,初始化函数和退出清除函数
要声明成模块的初始化和退出
必须调用这两个函数来申明
下面看一下设备管理
Linux的设备和文件系统紧密结合
因为各种设备都是以文件的形式存放在/dev这个目录下
这就是设备文件
系统为设备编号,每个设备又分为主设备号和次设备号
主设备号用来区分不同类别的设备
而次设备号用来区分同一类型的多个设备
对于常用设备Linux有约定俗成的编号
比如说硬盘的主设备号是3
在机器上如果有两个硬盘的话
次设备号可以分别设为1和2
内核就是利用主设备号将设备和相应的的驱动程序对应起来
主设备号标识设备对应的驱动程序
因此向系统增加一个驱动程序意味着要赋予它一个主设备号
这个赋值过程在驱动程序模块的初始化过程中完成
是这样一个函数register_chrdev
那么装载设备程序的例子我们来看一下
就是我们刚才的mydriver_init函数
我们把它扩充一下,首先就是register_chrdev,注册设备
它的参数包括主设备号、设备名等等
如果返回值是正确的,这个初始化就成功了
与此相反的,有卸载设备
此时应该释放主设备号
具体的函数也是我们刚才的清除函数里面增加的这个内容
就是unregister_chrdev这个函数
在Linux中为所有的设备文件都提供了统一的操作函数接口
这就是file_operations这样一个结构
这个结构中包含很多操作函数的指针
比如说open(),close(),write()等
每个指针都对应着内核驱动模块用来处理某个被请求的事务的函数的地址
这是一个函数指针
这个结构体示例就是这个样子
其中我们可以把对应的函数指针替换为具体实现的函数
比如说mydriver_read,mydriver_write,mydriver_open,mydriver_release等等
当我们实现了这些函数之后
操作这个结构体就是要对这些函数进行操作
首先看一下打开设备,打开设备使用的open方法
它用来为以后的操作完成初始化准备工作
open方法中最关键的是要增加设备计数
以便防止文件在关闭前模块被卸载出内核
在打开这个设备的时候,我们增加这个设备计数
关闭设备正好相反,它是使设备计数减一
如果设备计数 减为0了,它就会进行关闭设备
这个是设备计数减一的操作
读写设备比打开设备要复杂一些
因为驱动程序是在内核空间,而我们的应用是在用户空间
所以说读写操作是要完成这两者之间的数据传输
这个传输不能通过通常的方法,比如说利用memcpy来完成
只能通过内核提供的专门的数据传输函数
这就是下面的这四个函数
copy_to_user 、copy_from_user、put_user、get_user
可以看一下,我们如何使用put_user来将数据写到用户空间
首先我们对要写的buffer进行验证
如果是正确的话我们再调用put_user
将内核中的数据写到用户空间
对于写的例子可以看下,我们实现了mydriver_write
同样我们是要验证这个buffer是否可用
如果可用的话
我们就从这个用户的buffer把数据读到内核空间
-1.1 嵌入式系统概念
--Video
-第一章:嵌入式系统基础--1.1 嵌入式系统概念
-1.2 嵌入式系统组成
--Video
-第一章:嵌入式系统基础--1.2 嵌入式系统组成
-2.1 嵌入式处理器发展历史
--Video
-第二章:嵌入式处理器--2.1 嵌入式处理器发展历史
-2.2 三星S3C2440 微处理器
--Video
-第二章:嵌入式处理器--2.2 三星S3C2440 微处理器
-3.1 嵌入式操作系统概述
--Video
-第三章:嵌入式操作系统--3.1 嵌入式操作系统概述
-3.2 嵌入式Linux 操作系统
--Video
-第三章:嵌入式操作系统--3.2 嵌入式Linux 操作系统
-3.3 Linux 操作系统实时性改造
--Video
-第三章:嵌入式操作系统--3.3 Linux 操作系统实时性改造
-4.1 基于Linux的开发流程
--Video
-第四章:嵌入式软件开发平台--4.1 基于Linux的开发流程
-4.2 GCC 编译器
--Video
-第四章:嵌入式软件开发平台--4.2 GCC 编译器
-4.3 GDB 调试器
--Video
-第四章:嵌入式软件开发平台--4.3 GDB 调试器
-5.1 Linux 设备驱动技术
--Video
-第五章:嵌入式Linux驱动开发--5.1 Linux 设备驱动技术
-5.2 Linux 设备驱动程序
--Video
-第五章:嵌入式Linux驱动开发--5.2 Linux 设备驱动程序
-实验一:基于ARM的嵌入式Linux开发环境建立
--Video
-第六章:嵌入式系统实验--实验一:基于ARM的嵌入式Linux开发环境建立
-实验二:基于ARM的模块方式驱动程序实验
--Video
-第六章:嵌入式系统实验--实验二:基于ARM的模块方式驱动程序实验