第八章

   蜂鸣器开发板上带的一个硬件设备。可以通过向寄存器写入特定的值来控制蜂鸣器发出的声音。下来将介绍蜂鸣器的使用原理,并实现蜂鸣器的驱动。pwm驱动的使用不同于LED驱动的使用,其由多个文件组成,这是大多数linux驱动实现的标准方式。

编译pwm驱动,有多个文件组成的驱动。虽然俩个驱动实现的功能不同,但俩个驱动的源代码是相同,linux驱动模块的依赖,代码重用分为静态和动态俩种。静态重用把代码放一块就可以编译最终生成一个可执行文件或程序库。本节介绍一种代码共享方式:模块依赖也称导出符号。强行卸载linux驱动,如果编写的linux驱动在逻辑上是正确的,那么就可以正常装载和卸载。在意外环境下出现异常,就无法正常卸载。分为初始化函数崩溃,初始化函数无法正常返回。卸载函数堵塞,在调用卸载函数时成功返回才能顺利完成。否则就会出现堵塞。

蜂鸣器驱动是开发板自带的一个简单硬件,打开的时候就会发出叫声。基本原理就是通过脉冲控制蜂鸣器的而打开和停止。通过I/O命令可以打开和停止pwm。测试驱动编写的I/O命令的程序 ioctl.pwm驱动与LED驱动实现类似,可以还要简单一些。将linux驱动分成多个实现文件才使用了较为简单的pwm驱动。也学到了更多的驱动代码,对控制开发板有了进一步的了解。

第九章

    HAL是建立在Linux驱动之上的一套程序库,这套程序库并不属于Linux内核,而是属于Linux内核层之上的应用层。Google为Android加入HAL主要有如下的目的:统一硬件的调用接口、解决了GPL版权问题。加入HAL的驱动使应用程序不需要再关心Linux驱动和设备文件的交互方式,而只需要像访问普通API一样就可以和Linux驱动进行交互。

    基本原理是只从指定寄存器读取或写入5个字节,第1个字节用于指定读写的动作以及寄存器类型。后4个字节是读写的实际的数据。在与LED驱动交互时,只要向设备文件读取或发送5个字节的数据,就可以读写指定的寄存器。由于LED驱动程序的设备文件接收的不是字符串,而是字节类型的数据,因此需要单独做一个程序向设备文件写入字节形式的数据,或从设备文件中读取字节类型的数据。

    编写HAL模块的步骤和原理:定义结构体和宏,编写HAL模块的open函数,定义hw_module_methods_t结构体变量,定义HAL_MODULE_INFO_SYM变量,编写HAL模块的 close函数,编写控制LED的函数。HAL模块可以被Android系统自动调用,自然也拥有类似main或init函数的接口,只不过这个接口不是函数,而是一个固定名称的结构体变量也就是说,所有的HAL程序都必须要有一个变量。Linux驱动有两种方式,一种就是通过传统的方式直接与Linux驱动交互,如直接读写设备文件的数据。另外一种是Android特有的,就是通过HAL模块。HAL模块本质上就是通过Linux共享库与Linux驱动交互,然后应用程序再访问Linux共享库。

第十章

   对于复杂的Linux驱动及HAL等程序库,需要使用各种方法对其进行调试,例如,设置断点、逐步跟踪代码、输出调试信息等。Printk函数运行在内核空间,printf函数运行在用户空间。

   使用printk函数可以很方便地将消息写入日志文件或控制台,但大量使用printk函数操作日志文件或控制台设备文件会严重影响Linux驱动的性能,因此,这就要求Linux驱动只在开发阶段使用printk函数输出消息。Printk函数在控制台显示消息是通过/dev/console设备文件实现的,该设备文件只在字符界面的控制台下才起作用,所以printk函数只有用在字符界面的控制台上才能正常输出消息。

    在Linux文件系统中,/proc经常被用来作为内核空间与用户空间进行数据交互的工具。/proc是虚拟文件系统,所以读写/proc文件系统的速度要远比读写/dev文件系统的速度快。因此,/proc文件系统也可作为Linux驱动与用户空间程序交互的工具。在Linux驱动程序中可以使用内核函数在/proc目录中创建和删除虚拟文件,也可以建立和删除虚拟目录。/proc文件系统和/dev文件系统一样,也需要设置访问文件的动作处理函数,/dev文件系统通过file_operations.read和file_operations.write函数指针变量读写设备文件的读写动作处理函数。Proc_dir_entry结构体代表一个虚拟目录或文件。Android模拟器只能通过端口映射方式使用gdbserver调试程序,但开发板除了可以通过IP连接到gdbserver外,还可以通过串口进行连接。

posted on 2016-07-03 16:46  spurs2121  阅读(143)  评论(0编辑  收藏  举报