《android深入探索》第七章心得

看了本书第七章,我学到了:

1.  linux驱动实现原理:

linux驱动通过I/O内存向硬件写入数据,I/O内存是通过各种接口连接到主机的硬件在主机内存中的映射。Linux内核提供了多个与I/O内存交互的函数:ioread16、ioread32、iowrite16、iowrite32等。每个连接linux的硬件在I/O内存中都会有映射首地址,用函数读写时需要指定这些首地址。

 

2.  编写LED驱动:

①   创建LED驱动的设备文件:

1>.初始化cdev:cdev_init()

2>.指定设备号:

法一:alloc_chrdev_region()自动分配一个未使用的主设备号,次设备号默认为0。参数dev表示设备号指针,baseminor参数分配次设备号,count表示分配次设备号范围,name表示设备文件名称。

法二:register_chrdv_region()直接指定设备号。参数from表示设备号,count表示分配次设备号范围,name表示设备文件名称。

3>.将字符设备添加到内核中的字符设备数组中:cdev_add()。该函数中调用了_map()负责将设备文件的相关信息添加到保存已建立的设备文件的probes数组中。

4>.使用class_create宏创建struct class,包含了一些与文件有关的变量及一些回调函数指针变量。

5>.创建设备文件:leds_device_create(),led_init()是LED驱动的初始化函数,在其中直接调用leds_device_create()

注:LED次设备号总为10。

②   卸载LED驱动的设备文件:依次调用device_destroy()、class_destroy()、unregister_chrdev_region()函数,leds_destroy_device()用来卸载LED设备文件,在其中调用leds_exit()完成LED驱动文件的卸载。

③   设置寄存器并初始化LED驱动:

1>.LED有两个引脚:GPB0、GPB1。一个连接到ARM处理器的GPI0端口,另一个连接电源VCC3。GPI0低电平时LED发光,高电平时熄灭。控制LED需要设置3个寄存器:GPMCON(端口配置寄存器)、GPMDAT(端口数据寄存器)、GPMPUD(端口上拉寄存器)。这3个寄存器的虚拟地址分别是:0xF04500820 0xF04500824 0xF04500828

2>.初始化寄存器:leds_init_gpm()函数中写入3个寄存器的地址,调用ioread32()、iowrite32()用于读取和写入虚拟地址中的数据。在leds_init()中调用leds_init_gpm()完成寄存器的初始化。

④   控制LED:

法一:通过字符串控制LED:使用file_operations.write()

法二:通过I/O命令控制LED:使用file_operations.ioctl()

⑤   LED驱动模块的参数:

使用module_param_array(name,type,nump,perm)宏为linux驱动指定数组形式的模块参数,其中nump表示存储数组长度的变量的指针,perm表示参数文件的访问权限。

3.  测试LED驱动:

①   编写测试I/O控制命令的通用程序:

#~/drivers/ioctl/build.sh

#编译ioctl

②   使用NDK测试LED驱动:

③   使用Java测试LED驱动

 

4 . LED驱动的移植:

Linux驱动最简单的移植就是将其在不同linux内核版本下编译,修改linux驱动源码尽量不修改linux驱动的接口。

 

posted @ 2016-06-05 20:52  Chen-qiujin  阅读(164)  评论(0编辑  收藏  举报