第八章 让开发板发出声音:蜂鸣器驱动
Linux驱动的代码重用
Linux 驱动的代码重用有很多种方法。可以采用标准C 程序的方式。将要重用的代码放在其他的文件(在头文件中声明〉中。如果要使用某些功能, include 相应的头文件即可(这种方式称为静态重用)。也可以使用另外一种动态重用的方式,也就是一个Linux 驱动可以使用另外←个Linux驱动中的资源(函数、变量、宏等〉。
强行卸载Linux驱动
如果编写的Ljnux 驱动程序在逻辑上是正确的,那么可以正常装载和卸载,但在某些情况下,可能某些程序会出现异常情况。这时Linux 驱动可能会无法正常卸载。
情况1 : 初始化函数崩溃
由于Linux 驱动模块的初始化函数(通过module_init 宏指定的函数〉进行了某些操作而崩溃,从而导致初始化函数无法正常返田二这种情况的表现是当前Linux 驱动模块没用被任何其他的Linux 驱动模块使用,但却显示已经被引用了一次。
情况2: 卸载函数被阻塞
在使用rmmod 命令卸载Linux 驱动时,系统会调用卸载函数(跑过module_exit 宏指定的函数),只有卸载函数成功返回肘, Linux 驱动才会被翻载。如果卸载函数被阻塞(可能是死循环、并发等情况引起的阻塞), rmmod 命令也会被阻塞. 也就是说永远不会执行到卸载Linux 驱动模块的代码。这种情况的表现是一执行rmmod 命令就会停在那不动了,永远也不会返回到系统的操作提示符。
不管是哪种情况,都需要解决一个不可回避的问题,就是要获取表示要卸载的Linux 驱动模块的module 结构体指针。因为struct module 表示了Linux 驱动的相关信息.
蜂鸣器(PWM)驱动
蜂鸣器(buzzer)与LED 类似,也是开发板上自带的一个简单的硬件。如果打开蜂鸣器,开发板会发出类似蜂鸣的尖叫声,关闭蜂鸣器则会停止尖叫声。
如图所示,定时器1 的输出引脚TOUT1 和蜂鸣器的三极管相连, 此电路的三极管是PNP 性,当TOUT1 是高电平时,此三极管处于饱和状态,电路导通,电流流过蜂鸣器,此时蜂鸣器发声;反之,当TOUT1 是高电平时,此三极管处于截止状态,电路关断,时蜂鸣器停止发声。蜂鸣器发声的长短和频率,完全有TOUT1 控制导通时间,一般都是设定一段延时就可以了,长短可以自己实验。
编译代码
$ cd ~/workdir/driver/Linux3.2Drivers/fs210_beep_pwm
$ make
查看编译生成的ko 文件,并拷贝到nfs 文件系统目录中。
$ ls
$ cp fs210_pwm.ko /source/rootfs/
执行 make pwm_test 命令编译测试文件。
$ make pwm_test
启动开发板,加载驱动。
# insmod fs210_pwm.ko
# mknod /dev/pwm c 251 0
# chmod 777 /dev/pwm
# ./pwm_test
可以看到蜂鸣器间隔响。