第十七讲 Linux自带LED驱动实验
一、内核自带LED驱动使能
1、内核自带的驱动,都是通过图形化界面配置,选择使能或者不使用。
输入:make menuconfig
使能驱动以后在.config里面就会存在:CONFIG_LEDS_GPIO=y
在linux内核源码里面一般驱动文件夹下Makefile会使用CONFIG_XXX来决定要编译哪个文件。
obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
obj-y += leds-gpio.o *-> leds-gpio.c*
二、内核自带LED驱动分析
打开驱动文件,找到:
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);
#define module_platform_driver(__platform_driver) \
module_driver(__platform_driver, platform_driver_register, \
platform_driver_unregister)
#define module_driver(driver, register, __unregister, ...) \
static int init driver##_init(void) \
{ \
return register(&(driver) , ##VA_ARGS); \
} \
module_init(_driver##init); \
static void exit driver##_exit(void) \
{ \
unregister(&(driver) , ##VA_ARGS); \
} \
module_exit(_driver##exit);
展开:
module_platform_driver(gpio_led_driver);
module_driver(gpio_led_driver, platform_driver_register, \
platform_driver_unregister)
#define module_driver(driver, register, __unregister, ...) \
static int __init gpio_led_driver_init(void)
{
return platform_driver_register (&gpio_led_driver);
}
module_init(gpio_led_driver_init);
static void exit driver##_exit(void)
{
unregister(&(driver) , ##VA_ARGS);
}
module_exit(_driver##exit);
根据gpio_led_driver可知,设备树的of_match_table为of_gpio_leds_match,匹配表里面的匹配值:
static const struct of_device_id of_gpio_leds_match[] = {
{ .compatible = "gpio-leds", },
{},
};
当驱动和设备匹配以后gpio_led_probe函数执行:
-> gpio_leds_create
-> create_gpio_led
三、内核自带LED驱动使用
1、首先将驱动编译进内核里面,
2、根据绑定文档在设备树里面添加对应的设备节点信息。
如果无设备树,那么就要使用platform_device_register向总线注册设备。
如果有设备树,那么就直接修改设备树,添加指定的节点。
第十八讲 Linux杂项(MISC)驱动实验
一、内核自带MISC驱动简介
1、MISC设备的主设备号为10。
2、MISC设备 会自动创建cdev,不需要我们手动创建
3、MISC驱动是基于platform。
MISC驱动编写的核心就是初始化miscdevice结构体变量。然后使用misc_register向内核注册,卸载驱动的时候使用misc_deregister来卸载miscdevice。
如果设置miscdevice里面minor为255的话,表示由内核自动分配也给次设备号。
二、使用MISC驱动框架
1、beep设备树。
/* zozhongkai beep */
beep{
compatible = "alientek,beep";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_beep>;
beep-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
status = "okay";
};
2、驱动文件