分析
在我们的安卓手机中,有多种灯光,在hardware/libhardware/include/hardware文件中,可以看到如下定义
#define LIGHT_ID_BACKLIGHT "backlight"
#define LIGHT_ID_KEYBOARD "keyboard"
#define LIGHT_ID_BUTTONS "buttons"
#define LIGHT_ID_BATTERY "battery"
#define LIGHT_ID_NOTIFICATIONS "notifications"
#define LIGHT_ID_ATTENTION "attention"
#define LIGHT_ID_BLUETOOTH "bluetooth"
#define LIGHT_ID_WIFI "wifi"
这些都是android系统逻辑上支持的灯光,他到底对应开发板上的那个LED,由我们的HAL和驱动决定。灯光的使用方式有以下几种:
1.brightness:灯光亮度,可调节0~255;
2.cclor:RGB颜色设定
3.blink:闪烁,onms(亮的时间),offms(灭的时间),通过定时器实现
led_class接口分析
在linux内核中,有一个led子系统,该系统为我们提供了很多接口,在编写灯光系统驱动的时候,我们并不需要从零开始编写,在/drivers/leds目录下,存在文件led_class.c,该文件为我们提供了很多led子系统的接口,其中包括了设置brightness与blink的功能,先查看源码:
static int __init leds_init(void)
{
leds_class = class_create(THIS_MODULE, "leds");
if (IS_ERR(leds_class))
return PTR_ERR(leds_class);
leds_class->pm = &leds_class_dev_pm_ops;
leds_class->dev_groups = led_groups;
return 0;
}
3288
static int __init leds_init(void)
{
leds_class = class_create(THIS_MODULE, "leds");//创建sys/class/leds类
if (IS_ERR(leds_class))
return PTR_ERR(leds_class);
leds_class->suspend = led_suspend;//suspend的指针以及resume的指针初始化
leds_class->resume = led_resume;
leds_class->dev_attrs = led_class_attrs;//创建为基于这个class的所有设备创建属性
return 0;
}
入口函数中,在sys/class目录下创建一个leds类,往上我们可以看到一个SIMPLE_DEV_PM_OPS宏, 将led-class中的suspend中的指针,以及resume的指针初始化,当系统休眠或唤醒的时候,遍历class,调用其中的pm的书suspend() 或resume()
static SIMPLE_DEV_PM_OPS(leds_class_dev_pm_ops, led_suspend, led_resume);
==>
static const struct dev_pm_ops leds_class_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(led_suspend, led_resume)
}
==>
static const struct dev_pm_ops leds_class_dev_pm_ops = {
.suspend = led_suspend,
.resume = led_resume,
}
然后还会在sys/class/leds目录具体的led下创建3个子节点brightness、max_brightness、trigge,
static DEVICE_ATTR_RW(brightness); // 可读可写
static DEVICE_ATTR_RO(max_brightness); // 只读
static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); // 可读
我们可以用其创建的子节点对LED进行控制,如
读 cat /sys/class/leds/xxx/brightness
写 echo 255 > /sys/class/leds/xxx/brightness
我们就能查询或者控制led的亮度了,那么为什么呢?
static ssize_t brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
static ssize_t brightness_store(struct device *dev,
struct devi