IMX6ULL驱动学习--Linux自带LED驱动

    技术2022-07-10  136

    Linux自带LED驱动

    Linux内核LED驱动内核使能LED驱动LED驱动源码分析设备树节点编写设备树LED节点 设备操作

    Linux内核LED驱动

    Linux 内核集成了LED驱动,采用platform框架,我们只需要在编译内核时选择LED驱动,在设备树文件中添加LED节点即可。

    内核使能LED驱动

    进入Linux内核文件夹,输入如下命令进入配置菜单: $ make menuconfig 按照如下路径打开LED驱动配置项: ->Device Drivers ->LED Support(NEW_LEDS[=y]) ->LED Support for GPIO connected LEDs

    按Y使能。保存退出,然后编译内核。

    LED驱动源码分析

    在上面使能LED驱动后,drivers/leds/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); 因此设备树中的compatible属性为gpio-leds的节点都会被leds-gpio.c驱动匹配。在gpio_led_driver中name为leds-gpio,因此在注册驱动之后,/sys/bus/platform/drivers/下会有leds-gpio驱动。其中module_platform_driver(gpio_led_driver);用于注册驱动。其定义在include/linux/platform_device.h中,如下: #define module_platform_driver(__platform_driver) \ module_driver(__platform_driver, platform_driver_register, \ platform_driver_unregister)

    可以看出是一个宏,依赖于module_driver(),module_driver()定义在include/linux/device.h中,如下:

    #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);展开后为:

    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);

    即为platform驱动的注册和删除。

    设备树节点编写

    创建dtsleds 节点表示LED设备,节点中可以有多个led子节点dtsleds 节点的compatible必须是gpio-leds设置label属性,这个将设置为led的名字每个子节点必须设置gpios属性,表明其GPIO引脚linux,default-trigger属性为LED默认功能配置,可选项有: backlight : LED作为背光 default-on : LED灯默认打开 default-off : LED灯默认关闭 heartbeat : LED作为心跳灯,作为系统运行提示灯 ide-disk : LED作硬盘活动指示灯 timer : LED周期性闪烁,由定时器驱动,闪烁频率可以修改。 default-state设置默认状态,可选项有: on off keep

    设备树LED节点

    添加dtsled节点如下:

    dtsleds { compatible = "gpio-leds"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_light>; led_red { label = "red"; gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; default-state = "on"; linux,default-trigger = "timer"; }; };

    编译设备树,重启。

    设备操作

    修改完设备树之后,在/sys/devices/platform/下存在dtsles设备节点,即设备树节点添加成功。进入/sys/class/leds目录中,发现有red节点,即led驱动匹配成功,通过如下指令即可调整led状态: echo 1 > /sys/class/leds/red/brightness //打开 LED0 echo 0 > /sys/class/leds/red/brightness //关闭 LED0
    Processed: 0.008, SQL: 9