5.1 实验5-1:“平台设备”模块
此平台驱动程序的功能与杂项字符驱动程序相同,但是这次将在probe()
函数而不是init()
函数中注册字符设备。当内核模块被加载时,平台设备驱动使用platform_driver_register()
函数将自己注册到平台总线驱动中。当平台设备驱动将该驱动的某个compatible
字符串(包含在它的of_device_id
数据结构之中)的值与DT设备节点的compatible
属性值匹配成功时,将调用驱动的probe()
函数。将设备与设备驱动关联的过程称为绑定。
of_device_id
数据结构定义在include/linux/mod_devicetable.h
中:
接下来将描述驱动程序的主要代码段:
1. 包含平台设备头文件,该文件包含平台设备/驱动程序所需的数据结构和函数定义:
2. 定义驱动程序支持的设备列表。创建一个of_device_id
数据结构数组,在这个数组中,你使用字符串初始化compatible字段,这些字符串被内核用来将驱动程序绑定到设备,这些被绑定的设备在设备树中呈现出相同的compatible属性。如果设备树中包含compatible设备项,这将自动触发驱动程序的probe()
函数。
3. 添加一个platform_driver
数据结构,该数据结构将会被注册到平台总线中:
4. 加载内核模块后,当某个设备与驱动支持的设备ID匹配时,将调用my_probe()
函数。当卸载驱动时,将调用my_remove()
函数。因此,my_probe()
函数行使hello_init()
函数的职责,而my_remove
函数()
行驶hello_exit()
函数的职责。因此,用my_probe()
函数替换hello_init()
函数,以及用my_remove()
函数替换hello_exit()
函数是有意义的:
5. 将平台设备驱动注册到平台总线核心中:
6. 修改设备树文件(在arch/arm/boot/dts/
目录中)以包括DT驱动的设备节点。必须存在一个DT设备节点的compatible属性,该属性与保存在某个of_device_id
数据结构中的compatible字符串相同。
对于MCIMX7D-SABRE单板,打开DT文件imx7d-sdb.dts
,并在memory
节点后面添加hellokeys
节点:
对于SAMA5D2B-XULT单板,打开DT文件at91-sama5d2_xplained_common.dtsi
,并在gpio_keys
节点后面添加hellokeys
节点:
对于Raspberry Pi 3 Model B单板,打开DT文件bcm2710-rpi-3-b.dts
,并在soc
节点后面添加hellokeys
节点:
7. 构建修改后的设备树,并将其加载到目标处理器中。
对于i.MX7D处理器,请参见随后的代码清单5-1中“平台设备”驱动源代码(hellokeys_imx.c
)。
注意:针对SAMA5D2单板(hellokeys_sam.c
)和BCM2837单板(hellokeys_rpi.c
)的驱动程序,可以从本书GitHub仓库下载。