文章目录
使用驱动框架的优势
leds驱动框架相关
常用接口
led_classdev_register函数
led_classdev_unregister函数
在驱动中的使用
在用户空间操作led
总结
点击下方阅读原文可访问文中超链接
在前面已经用创建通用字符设备的方式完成了led的操作,本次总结记录的是使用linux内核提供的leds驱动框架来点亮led灯,不同于前面应用程序通过设备节点来访问,不过也是在应用程序中通过打开文件来访问的。
使用驱动框架的优势
linux内核为各种硬件进行分类,然后针对各类硬件实现一套比较标准的驱动框架,其中每类硬件共有属性那一部分由内核开发者负责实现和维护,然后给驱动开发者留出接口用来完成具体硬件的特定操作部分。更加简化了驱动开发者的编码工作。
leds驱动框架相关
相关的源代码位于drivers/leds/目录内,头文件位于include/linux/目录内。
如果要使用leds驱动框架,首先要在内核中开启相关的配置宏:
Device Drivers --->
[*] LED Support --->
<*> LED Class Support
启动内核后可以在/sys/class/目录下看到leds类,这也就是驱动框架中内核开发者完成的那一部分,之前是需要驱动开发者自己创建的,现在对于驱动开发者来说就只需要调用相关的接口创建设备即可。
常用接口
位于头文件:include/linux/leds.h
led_classdev_register函数
用以在leds类下面创建设备。
static inline int led_classdev_register(struct device *parent,
struct led_classdev *led_cdev)
led_classdev_unregister函数
用以删除在leds类下面创建的设备。
void led_classdev_unregister(struct led_classdev *led_cdev)
在驱动中的使用
从下面的代码中可以看出比之前的代码要简化很多,只需要调用一个注册设备的接口就可以了,省去了之前手动创建字符设备、设备类、file_operations结构(驱动框架未使用file_operations结构完成硬件操作,而是使用的另外一种方法)等步骤。
/*定义一个设备*/
struct led_classdev cdev;
static void s5pv210_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness)
{
unsigned int tmp;
if(brightness)
{
/*
硬件操作点亮led灯
*/
}
else
{
/*
硬件操作熄灭led灯
*/
}
}
static int __init test_init(void)
{
int ret = 0;
/*
省略其它操作
*/
/*填充定义的设备*/
cdev.brightness_set = s5pv210_led_brightness_set;
cdev.brightness = LED_OFF;
cdev.name = "led3";
cdev.flags |= LED_CORE_SUSPENDRESUME;
ret = led_classdev_register(NULL,&cdev);
if(ret < 0)
{
ret = -EINVAL;
}
return ret;
}
static void __exit test_exit(void)
{
led_classdev_unregister(&cdev);
/*
省略其它操作
*/
}
在用户空间操作led
使用了驱动框架后可以不需要编写应用程序就可以测试led是否能正常被点亮与熄灭,这些都可以在sysfs文件系统中完成。在装载驱动后可以在/sys/class/leds/目录下看到对应的led设备目录,如本文中的led3(填充设备时的设备名字段)。
# ls /sys/class/leds/led3
brightness power uevent
max_brightness subsystem
使用echo命令操作led灯:
# 点亮led
echo 1 > brightness
# 熄灭led
echo 0 > brightness