在前面两章,我们介绍了led子系统的软件框架与数据结构,本章我们实现一个led设备驱动、ledtrigger,用于led子系统的驱动开发练习,本章的主要内容如下:
一、led设备驱动开发流程
二、led trigger驱动开发流程
三、本次练习所涉及的开发内容说明
四、led-gpio驱动开发说明
五、led-trigger-pwm-gpio驱动开发说明
六、验证说明
一、led设备驱动开发流程
针对led设备驱动,主要完成如下几步即可:
- 初始化并设置一个struct led_classdev 类型的变量;
- 调用led_classdev_register完成led device的注册
二、led trigger驱动开发流程
针对led触发器,主要完成如下几步即可:
- 定义并设置struct led_trigger 类型的变量;
- 调用led_trigger_register完成led trigger的注册即可。
三、本次练习所涉及的开发内容说明
- 需要熟悉platform device、platform driver使用;
- 借助上一专栏(gpio子系统分析专栏)实现的virt gpio chip驱动,作为虚拟gpio设备;
- 实现一个基于gpio控制的led设备,该设备可完成一个gpio led device的注册,并提供亮度设置接口;
- 实现一个基于gpio-led的led trigger,该led trigger实现的功能是输出pwm波形(主要是借助virt gpio实现)
四、led-gpio驱动开发说明
相关数据结构说明
struct led_gpio_data为该gpio-led设备的数据结构:
- 其内部包含led_classdev类型的变量led_dev,用于实现led设备的注册;
- 包含gpio的值;
- 该gpio是否为低有效
struct led_gpio_platform_data主要用于gpio-led对应的platform device设备向platform driver传递参数,参数包含gpio的值、gpio是否低有效,默认gpio值、默认选择的led-trigger名称等内容。
代码实现说明
- 在platform driver的probe函数中,完成struct led_gpio_data类型变量的创建,对应gpio的申请及设置为输出模式,并完成struct led_classdev类型变量的设置(主要设置函数brightness_set、默认选择的led-trigger的名称等内容,接着调用led_classdev_register完成注册即可),如下是代码实现
led-trigger-pwm-gpio驱动开发说明
本trigger实现的功能是根据gpio值输出pwm波形(这个是借助led子系统的闪烁功能实现通过gpio进行pwm波形的输出验证,也可以理解成就是led周期闪烁,唯一的不同是使用高精度定时器实现微秒级亮灭罢了,此处主要是为了验证led-trigger功能)
相关数据结构
主要是数据结构struct gpio_pwm_trig_data,包含如下内容:
- 定义一个高精度定时器timer,该定时器实现周期亮灭功能;
- 定义delay_on指示led亮的时间;
- 定义delay_off指示led灭的时间
代码设计
led_trigger的active函数
在该函数中,完成如下功能:
- 完成struct gpio_pwm_trig_data类型变量内存的申请;
- 完成delay_on、delay_off对应设备属性的创建
- 完成高精度定时器的初始化,该定时器的超时函数主要完成亮灭的设置及下一个超时时间的设置(仅在用户设置delay_on、delay_off均不为0时,方可启动定时器)。如下是该接口的定义
led_trigger_deactive函数
该函数完成active函数申请内存的释放,定时器的关闭、设备属性的删除等内容。
六、验证说明
下面说明验证步骤:
- insmod virt_gpio_dev.ko、insmod virt_gpio.ko,完成虚拟gpio chip的注册;
- insmod led_gpio.ko 、insmod ledtrigger-gpio-pwm.ko完成led device、led trigger的注册;
- insmod virt_gpio_led.ko 完成led-gpio对应platform device的注册
完成以上三步,在/sys/class/leds/virt_led_pwm下面就可以设置该led的trigger,此处我们设置为gpiopwm
echo gpiopwm >trigger
然后设置亮灭时间(单位是微秒,此处我们设置亮灭各1秒)
echo 1000000 >delay_on
echo 1000000 >delay_off
然后进入目录/sys/devices/platform/virt_gpio_dev,查看文件vgpio_out,如下所示即实现了周期设置gpio的值。
本次测试代码已在ubuntu16.04上,完成验证。代码链接:https://gitee.com/jerry_chg/led_dev_led_trigger.git。
本篇文章主要介绍如何实现led device、led trigger驱动开发,希望对大家有所帮助。