android开发灯控系统app代码,Android灯光系统(1)——led_class驱动实现

1.对灯光的要求

(1)亮度可调节,如背光灯

(2)颜色可变化,如电池电量指示灯

(3)能闪烁,如通知灯

2.Linux内核对led的支持

在Linux内核中已经实现了一个led class, 它里面已经实现了brightness的调节和blink,文件为:drivers/leds/led-class.c

在ledinit()中的led_class_attrs在/sys/class/leds下创建了brightness max_brightness trigger文件。

3.使用Linux内核中的led class

(1)配置内核

make menuconfig选中:

CONFIG_LEDS_CLASS

CONFIG_LEDS_TRIGGERS

CONFIG_LEDS_TRIGGER_TIMER

(2)驱动编写流程

a.分配led_classdev结构体

b.设置

c.注册

可以参考leds-s3c24xx.c,驱动Demo如下:

#include #include#include#include#include#include#include#include#include#include#include#include#include#include#include

structled_desc {intgpio;char *name;

};/*三星的goio引脚根本就不需要获取就可以直接使用*/

static struct led_desc led_gpios[] ={

{EXYNOS4212_GPM4(0), "led1"},

{EXYNOS4212_GPM4(1), "led2"},

{EXYNOS4212_GPM4(2), "led3"},

{EXYNOS4212_GPM4(3), "led4"},

};structled_classdev_4412 {struct led_classdev cdev; /*核心结构体*/

int gpio; /*每一个led绑定的gpio*/};static struct led_classdev_4412 *led_devs;static void brightness_set_4412(struct led_classdev *led_cdev,enumled_brightness brightness)

{struct led_classdev_4412 *dev = (struct led_classdev_4412 *)led_cdev;

led_cdev->brightness =brightness;if (brightness !=LED_OFF)

gpio_set_value(dev->gpio, 0); /*打开led*/

elsegpio_set_value(dev->gpio, 1); /*关闭led*/}static int leds_init(void)

{inti;intret;/*1. alloc led_classdev*/led_devs= kzalloc(sizeof(struct led_classdev_4412) *ARRAY_SIZE(led_gpios), GFP_KERNEL);if (led_devs ==NULL) {

printk("No memory for device\n");return -ENOMEM;

}for (i = 0; i < ARRAY_SIZE(led_gpios); i++)

{

s3c_gpio_cfgpin(led_gpios[i].gpio, S3C_GPIO_OUTPUT);/*默认led全部关闭*/gpio_set_value(led_gpios[i].gpio,1);/*2. set 这里面哪些域需要设置由led-class.c的实现决定的*/led_devs[i].cdev.max_brightness=LED_FULL;

led_devs[i].cdev.brightness_set=brightness_set_4412;

led_devs[i].cdev.flags=LED_CORE_SUSPENDRESUME;

led_devs[i].cdev.brightness=LED_OFF;

led_devs[i].cdev.name=led_gpios[i].name;

led_devs[i].gpio=led_gpios[i].gpio;//led_devs[i].cdev.default_trigger = "timer";//led_devs[i].cdev.blink_delay_on = 100;//led_devs[i].cdev.blink_delay_off = 900;

/*3. led_classdev_register*/ret= led_classdev_register(NULL, &led_devs[i].cdev);if(ret) {

i--;while (i >= 0) {

led_classdev_unregister(&led_devs[i].cdev);

i--;

}

kfree(led_devs);return -EIO;

}

}return 0;

}static void leds_exit(void)

{inti;for (i = 0; i < ARRAY_SIZE(led_gpios); i++)

{

led_classdev_unregister(&led_devs[i].cdev);

}

kfree(led_devs);

}

module_init(leds_init);

module_exit(leds_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Mr.Sun");

View Code

重新编译内核启动后,会在/sys/class/leds下看到led1——led4

4.应用程序设置方法

应用程序是通过sysfs文件来控制led的。

# echo 255 > /sys/class/leds/led1/brightness 点亮

# echo 0 > /sys/class/leds/led1/brightness 熄灭

# echo timmer > /sys/class/leds/led1/trigger 此时led1就应该在以1HZ频率闪烁了。之后此目录下会多出delay_on/delay_off两个文件

配置它两个可以配置闪烁行为。

echo none > trigger 和 echo 0 > brightness 都会使led不在依附trigger。

5.也可以在驱动代码里面设置默认的trigger,让led一上电就开始闪动。

6.这个显示效果还是可以借鉴一下的,由led_trigger_show()实现的,括起来的是led目前attach的trigger,其它是系统中还存在的trigger。

shell@tiny4412:/sys/class/leds/led1 # cat trigger

none mmc0 mmc1 mmc2 [timer]

7.从这里看不但可以指定class的sysfs属性文件,还可以指定dev的!

struct class{

...struct class_attribute *class_attrs;struct device_attribute *dev_attrs;struct bin_attribute *dev_bin_attrs;

...

}

class_create()时指定的属性在每一个依此class创建的设备文件的sysfs目录中都存在。见leds-class.c中的leds_init()。

8.device_create()只是创建设备模型,并不会在/dev/下创建设备文件

如led_classdev_register中调用了device_create但是并没有/dev/下的设备文件。

led_cdev->dev = device_create(leds_class, parent, 0, led_cdev, "%s", led_cdev->name); //无论arg3是否为0测试都不会创建设备文件。

9.list_for_each_entry的使用

来自led_trigger_show():

trig: 空闲变量指针

trigger_list: 单链表的链表头

next_trig: 构成链表的next指针成员

list_for_each_entry(trig, &trigger_list, next_trig) {use trig...}

你可能感兴趣的:(android开发灯控系统app代码,Android灯光系统(1)——led_class驱动实现)