当前课程知识点:嵌入式系统设计 > 第六章:嵌入式系统实验 > 实验二:基于ARM的模块方式驱动程序实验 > Video
实验目的
1、掌握Linux系统下设备驱动程序的作用与编写技巧
2、掌握Linux驱动程序模块加载和卸载的方法
3、了解Linux内核中的makefile和kconfig文件
实验内容
1、基于s3c2440开发板编写led驱动程序
2、将编写好的led驱动加入linux内核中,修改makefile和kconfig文件,配置和编译内核
3、编写关于led的测试程序,交叉编译后运行,控制led灯的亮灭
下面看实验原理与说明
1、linux设备驱动程序
在前面我们讲到了
linux设备分为字符设备、块设备和网络设备
本实验主要编写字符设备的驱动程序
对于linux驱动程序而言
它主要以模块的方式体现
比较关键的
有加载和卸载这两个固定的函数
3、Linux内核中的makefile和kconfig文件
是用于编译内核模块的关键文件
其中makefile是编译管理
kconfig是一个内核管理数据库
所有的配置都在这个数据库中体现
4、led驱动的原理
led是一个二极管
要点亮一个二极管
只需要加上一个电源
其中有一个限流电阻
因此,当我们把它的这一端接到
我们2440的GPJ口
然后,改变GPJ口的输出电平高低
就能控制二极管的点亮与熄灭
对于本实验中的开发板
这个二极管的
对应的GPJ口是接口
从0到7
因此,在程序中只需要操作这8个GPJ口
就能够对二极管进行操作
下面看一下实验步骤
1、分析driver下面的s3c2440_led.c文件
这就是模块驱动文件
2、实现update_led()函数和s3c2440_led_init()函数中的缺失代码
然后将这个文件拷贝到内核源代码driver/char文件夹下面
并修改对应的Kconfig和Makefile文件
然后配置和编译内核
4、对test_led.c进行交叉编译,生成可执行文件test_led
5、进入minicom
启动开发板
6、在开发板上加载led驱动模块
7、在开发板下建立led的设备节点
8、在开发板上运行test_led
然后,观察开发板上led的显示情况
最后卸载模块
下面看一下具体的实验过程
首先,看一下驱动模块的源程序
这是源代码
从这个代码中
可以看到
我们要用到的接口
就必须包含它的头文件
然后,我们如果编译成内核模块的话
这两个头文件是必须的
接下来是一些静态变量的定义
下面看一下第一个函数
update_led
判断led的状态
如果为1的话
就关闭led
否则打开led
每个引脚都是一样
一直到J7
然后第二个重要的函数就是led_write
终端输入数字
控制led的点亮与熄灭
那么这个数字怎么传到驱动程序呢
它实际上是从用户空间要传到内核空间
所以说需要调用copy_from_user这个内核模块函数
传下来之后
我们就根据这个状态值update_led
再下一个函数是open
只需要打印信息
再下一个是release
只是输出信息
再下一个
是我们前面讲到的operations这个结构
这个结构实际上是
声明了这些函数的指针
比如说open对应的是我们前面的这个函数
再往下是模块的初始化
这个初始化主要是设置这几个引脚用作输出
然后,当完成了设置之后
我们就要创建设备
创建设备调用的是mkdev
这个函数
根据主设备号和次设备号来创建一个设备
有了这个设备号
就需要将这个字符设备进行注册
并为它分配相应的数据结构
再对设备进行初始化
最后,产生设备节点并打印出相关信息
这里将前面的初始化函数和退出函数
注册模块的初始化和退出
最后给出作者信息
当设备驱动程序源代码编写完毕之后
要将其拷贝到linux内核对应的源代码路径下面
拷贝完之后
就需要进行编译
在编译的时候
需要进行配置
kconfig文件
在config文件里面
重点是要添加2440 led驱动支持这部分
这个配置完之后
还要修改makefile
在makefile里面
需要添加对2440这个驱动程序编译选项的支持
当这两者修改完之后
就进入内核的上层目录
进行配置
在配置中选择设备驱动中的字符设备
然后找到对2440 led的支持
通过空格将其选择为模块方式
完成配置之后
可以用make来编译驱动模块
可以看到驱动模块2440_led.ko已经正常产生
下一步
需要将这里的2440_led.ko
也就是模块驱动程序
拷贝到/arm/rootfs
也就是我们开发板用到的根文件系统下面的/home/driver下面
此时驱动模块已经准备完毕
下一步准备测试程序
首先进入到driver这个目录下面
然后看一下test_led.c这个文件
这个就是用于测试二极管点亮的源文件
在这个主程序中
首先是open这个设备
然后,打印提示输入信息
就是说
要想把二极管点亮
就需要输入对应的数字
接下来调用驱动程序的write函数
将对应的状态传到内核驱动
使得对应的二极管点亮或是熄灭
这个程序需要进行交叉编译
编译完毕
到这里
整个准备工作已经完毕
此时打开开发板电源
通过minicom监测与其通讯
等待启动完毕
此时我们见到home/driver这个目录
可以看到我们刚才生成的驱动程序和测试程序
都在下面存在
但此时
我们现在要做到的
创建led这个设备
产生一个231 0这样一个设备
下一步可以测试驱动程序
首先,装载驱动模块
提示初始化成功
接下来运行test_led测试程序
提示输入数字
比如说
输入一个7
回车
此时,从0到4,共5个二极管点亮
最后释放驱动模块
此时实验完毕
本实验结束之后
有以下思考题
1、设备驱动程序的功能是什么?
2、模块化的最大优点是什么?
3、如果在驱动模块中删除module_exit对程序的运行有什么影响?
4、驱动代码中调用的宏mkdev的作用是什么?
-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的模块方式驱动程序实验