一. 简介
前面我们都是自己编写
LED
灯驱动,其实像
LED
灯这样非常基础的设备驱动,
Linux
内核已经集成了。
Linux
内核的
LED
灯驱动采用
platform
框架,因此我们只需要按照要求在设备
树文件中添加相应的
LED
节点即可。
本文来简单分析一下Linux内核自带的Led灯的驱动框架,主要分析一下涉及驱动与设备匹配的的方面。
LED
灯驱动文件为
/drivers/leds/leds-gpio.c
,大家可以打开
/drivers/leds/Makefile
这个文件,找到如下所示内容:
# LED Core
obj-$(CONFIG_NEW_LEDS) += led-core.o
.....
obj-$(CONFIG_LEDS_GPIO_REGISTER) += leds-gpio-register.o
obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o
第5行,如果定义了
CONFIG_LEDS_GPIO
的话就会编译
leds-gpio.c
这个文件。
我们选择将 LED 驱动编译进 Linux 内核,在.config 文件中就会有“CONFIG_LEDS_GPIO=y”这一行,因此, leds-gpio.c 驱动文件就会被编译。
接下来我们看一下
leds-gpio.c
这个驱动文件,找到如下所示内容:
static const struct of_device_id of_gpio_leds_match[] = {
{ .compatible = "gpio-leds", },
{},
};
................
static struct platform_driver gpio_led_driver = {
.probe = gpio_led_probe,
.remove = gpio_led_remove,
.driver = {
.name = "leds-gpio",
.of_match_table = of_gpio_leds_match,
},
};
module_platform_driver(gpio_led_driver);
第 1~4 行,LED 驱动的匹配表,此表只有一个匹配项,compatible 内容为“gpio-leds”,因此,设备树中的 LED 灯设备节点的 compatible 属性值也要为“gpio-leds”,否则设备和驱动匹
配不成功,驱动就没法工作。
第
6~13
行,
platform_driver
驱动结构体变量,可以看出,
Linux
内核自带的
LED
驱动采用了
platform
框架。
第 7 行的 probe 函数为 gpio_led_probe,因此,当驱动和设备匹配成功以后,gpio_led_probe 函数就会执行。
第 10 行可以看出,驱动名字为 “leds-gpio”,而这个name是传统的设备与驱动匹配方法(即在不支持设备树的情况下),最终会在 /sys/bus/platform/drivers 目录下存在一个名为 “leds-gpio” 的文件。
第
15
行,通过
module_platform_driver
函数向
Linux
内核注册
gpio_led_driver
这个
platform驱动。
其实在
Linux
内核中会大量采用
module_platform_driver函数,
来完成向
Linux
内核注册
platform
驱动的操作。
module_platform_driver函数实际上展开后就是前面一直学到的字符设备注册与注销实现:
static int __init gpio_led_driver_init(void)
{
return platform_driver_register (&(gpio_led_driver));
}
module_init(gpio_led_driver_init);
static void __exit gpio_led_driver_exit(void)
{
platform_driver_unregister (&(gpio_led_driver) );
}
module_exit(gpio_led_driver_exit);
可以看出,module_platform_driver函数展开后,就是 platform_driver 的注册与注销。
总结
Linux 内核的 LED 灯驱动采用 platform 驱动框架,本文对大体框架进行简单分析,终点分析了驱动与设备匹配的关键点。