日期:2020-12-10
1 实验程序编写
2 编写应用测试程序
3 运行测试
本实验例程路径:i.MX6UL终结者光盘资料/06_Linux驱动例程/04_gpioled_atomic
首先创建新的文件gpioled_atomic.c,在LED驱动程序基础上进行修改。使用原子操作来实现一次只能允许一个应用访问LED灯。修改后的驱动内容如下:
第33行,在LED的设备结构体中添加原子变量lock,用来实现一次只能允许一个应用访问LED灯,led_init入口函数会将lock的值设备为1。
第45~55行,当应用测试程序打开led设备时,先判读原子变量的值,检查当前LED设备有没有被其他应用使用。每次打开驱动设备的时候先使用 atomic_dec_and_test 函数将 lock 减 1,如果 atomic_dec_and_test函数返回值为真就表示 lock 当前值为 0,说明设备可以使用。如果 atomic_dec_and_test 函数返回值为假,就表示 lock 当前值为负数(lock 值默认是 1),lock 值为负数的可能性只有一个,那就是其他设备正在使用 LED。其他设备正在使用 LED 灯,那么就只能退出了,在退出之前调用函数 atomic_inc 将 lock 加 1,因为此时 lock 的值被减成了负数,必须要对其加 1,将 lock 的值变为 0。
第113行,应用测试程序通过close关闭设备驱动文件,在led_release 函数中通过atomic_inc 释放 lcok,也就是将 lock 加 1。
第136行,初始化原子变量 lock,初始值设置为 1,这样每次就只允许一个应用使用 LED灯。
创建应用测试文件gpioled_atomic_test.c文件,具体内容如下:
1、编译驱动程序
编写Makefile文件,修改obj-m的值为gpioled_atomic.o,具体内容如下:
首先我们在终端输入两个命令(设置两个环境变量):
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
然后使用“make”命令进行编译,生成gpioled_atomic.ko驱动模块文件。
2、编译应用测试程序
输入下列命令编译gpioled_atomic_test.c应用测试程序:
arm-linux-gnueabihf-gcc -o gpioled_atomic_test gpioled_atomic_test.c
编译成功后,就会生成gpioled_atomic_test应用可执行程序。
3、运行测试
启动开发板,将编译好的gpioled_atomic.ko驱动模块文件和gpioled_atomic_test应用测试程序拷贝到/lib/modules/4.1.15目录下(检查开发板根文件系统中有没有“/lib/modules/4.1.15”这个目录,如果没有的话需要自行创建一下。开发板中使用的是光盘资料里面提供的busybox文件系统,光盘资料的“i.MX6UL终结者光盘资料\08_开发板系统镜像\03_文件系统镜像\01_Busybox文件系统”目录下)。输入下面命令加载模块:
depmod
modprobe gpioled_atomic
模块加载成功有如图 3.1信息打印:
然后使用gpioled_atomic_test应用测试程序测试驱动文件。
输入下面的命令打开LED灯:
./gpioled_atomic_test /dev/gpioled 1 &
查看开发板上的红色LED灯是否点亮,“&”表示在后头打开程序,这样终端不会被占用。
运行结果如图 3.2所示:
可以看出gpioled_atomic_test应用测试程序正常运行,打印“App running times:1”和“App running times:2”,表示模拟25s的设备占用。如果在25s占用期间输入关闭LED灯的命令:
./gpioled_atomic_test /dev/gpioled 0
会有如图 3.3信息产生:
错误信息“file /dev/gpioled open failed!”,/dev/gpioled设备文件打开失败,说明之前打开LED的命令,使gpioled_atomic_test正在占用/dev/gpioled设备文件,如果再次执行gpioled_atomic_test去打开/dev/gpioled设备文件则会失败。需要等25s结束之后,其他软件才能去使用/dev/gpioled设备文件。这个就是采用原子变量实现一次只能有一个应用程序访问 LED 灯。
卸载模块文件命令:
rmmod gpioled_atomic