第8章:让开发板发出声音:蜂鸣器
一、Linux驱动的代码重用
Linux 驱动的代码重用有很多种方法。可以采用标准 C 程序的方式。将要重用的代码放在其他的文件(在头文件中声明)中。如果要使用某些功能, include 相应的头文件即可(这种方式称为静态重用)。也可以使用另外一种动态重用的方式,也就是一个 Linux 驱动可以使用另外一个Linux驱动中的资源(函数、变量、宏等)。本节将详细介绍这些代码重用方法。
- 编译是有多个文件组成的Linux驱动
Linux 驱动的代码不多,将所有的代码都放到一个文件中并没有什么不妥, 但对于复杂的 Linux 驱动, 就需要使用多个源代码文件存放不同的功能代码, 这样做有利于代码分类和管理。当然,如果Linux 驱动要使用第三方的源代码, 那么就不得不编译多个源代码文件,最终便成.ko文件或编译进Linux内核(估计不会有人将第三方草原代码都复制到 个文件里再进行编译)。
2.Linux驱动模块的依赖(导出符号)
代码重用分为静态和动态两种。在上一节介绍的方式是代码的静态重用,这种方式是代码级的重用,也就是将需要重用的代码和使用这些代码的使用者放在一起进行编译,最终生成一个可执行文件或程序库(.ko、.so等)。
在本节将介绍另外一种代码共享的方式:模块依赖,也称为导出符号。如果只能用一句话解释如何利用导出符号实现代码共卒,这句话就是“在一个驱动模块里使用另一个驱动模块里的被导出的符号(常章、变量、函数等)”。
二、强行卸载Linux驱动
如果编写的Ljnux驱动程序在逻辑上是正确的,那么可以正常装载和卸载,但在某些情况下,可能某些程序会出现异常情况。这时Linux驱动可能会无法正常卸载。在本节将介绍如何处这些无法卸载的驱动。
情况1:初始化函数崩溃
由于Linux驱动模块的初始化函数(通过module_init 宏指定的函数)进行了某些操作而崩溃,从而导致初始化函数无法正常返回。这种情况的表现是当前Linux 驱动模块没用被任何其他的Linux驱动模块使用,但却显示已经被引用了一次。
情况2:卸载函数被阻塞
在使用 rmmod 命令卸载 Linux 驱动时,系统会调用卸载函数(通过 module_exit 宏指定的函数),只有卸载函数成功返回肘, Linux 驱动才会被卸载。 如果卸载函数被阻塞(可能是死循环、并发等情况引起的阻塞), rmmod 命令也会被阻塞.也就是说永远不会执行到卸载 Linux 驱动模块的代码。这种情况的表现是一执行rmmod命令就会停在那不动了, 永远也不会返回到系统的操作提示符。
三、蜂鸣器(PWM)驱动实验
PWM驱动与LED驱动的实现流程类似,可能还要简单一些。在本章只是为了演示如何将一个 Linux驱动分成多个实现文件, 才使用了比较简单的PWM驱动。
总结:
通过本章的学习, 可以掌握Linux驱动常用的代码重用方式。除此之外,本章还介绍了一种强行卸载Linux驱动的方法。通过这种方法,就可免去不断重启机器的痛苦了。