第2课第1节_Android灯光系统_led_class驱动

Android灯光系统

1.Linux的leds class驱动

  • Android 系统的灯光很多:
    电池指示灯,按键灯,键盘灯,屏幕亮度调节灯

  • 打开安卓源码 /home/topeet/Android/iTop4412_ICS_git/hardware/libhardware/include/hardware/lights.h
    可以看到有八种逻辑上的灯光
    在这里插入图片描述

  • 在Android系统中灯光的使用方式有哪些
    brightness: 0-255不同数值对应不同的亮度 或者只有亮灭 OFF-0/ON-255
    color RGB
    blink 亮nms 灭nms,可以通过定时器实现闪烁功能

  • 以前的驱动程序只有控制等的亮灭,满足不了android系统应用。比如我们要实现闪烁功能,可以自己用定时器,设置亮灭的时间来操作,比较麻烦。

  • 实际中我们也不需要从0开始写灯光系统驱动,在linux内核已经有了Led class驱动程序,它已经实现了设置brightness,和闪烁blink的功能
    源码路径 源码 drivers/leds/Led-class.c,可以找到入口函数
    在这里插入图片描述
    在入口函数中创建class,这个class有dev_attrs这个设备属性
    在这里插入图片描述
    这是一个数组里边有三个属性
    我们想设置brightness,我们可通过 这个语句设置
    echo 255 > sys/class/leds/led1/brightness
    通过这样的语句设置亮度brightness数值,最终会导致这个属性的led_brightness_store会被调用
    在这里插入图片描述
    在这个函数中,手续获得一个led_classdev,然后把buf中的字符串转化为整数state,最后调用函数led_set_brightness()
    在这里插入图片描述
    这个函数通过led_cdev中的brightness_set来设置led的亮度。
    cat sys/class/ldes/led1/max_brightness
    这个语句只能读取max_brightness,函数led_max_brightness_show就会被调用
    在这里插入图片描述

  • 怎么写驱动:

  • 1.分配led_classdev

  • 2.设置
    led_cdev->max_brightness
    led_cdev->brightness_set()
    led_cdev->flags
    led_cdev->brightness
    led_cdev->name

  • 3.注册:led_classdev_register()

  • 如果我们通过这个语句获取brightness的数值,那么这个函数就会被执行
    cat sys/class/ldes/led1/brightness
    在这里插入图片描述
    这个函数中首先得到一个led_classdev然后,返回这个结构体的成员brightness

2. 编写leds驱动程序

  • leds_4412.c
#include <linux/init.h>
#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/fs.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
//#include <mach/gpio-bank.h>
#include <mach/regs-gpio.h>
#include <asm/io.h>
#include <linux/regulator/consumer.h>
//#include "gps.h"
#include <linux/delay.h>

#include <linux/leds.h>



#define LEDS_DEBUG
#ifdef LEDS_DEBUG
#define DPRINTK(x...) printk("LEDS_CTL DEBUG:" x)
#else
#define DPRINTK(x...)
#endif

#define DRIVER_NAME "leds"

struct led_desc{
	int gpio;
	char *name;
};

static struct led_desc led_gpios[] = {
	{EXYNOS4_GPL2(0),"led1"},
	{EXYNOS4_GPK1(1),"led2"},
};

#define LED_NUM		ARRAY_SIZE(led_gpios)


struct led_classdev_4412 {
	struct led_classdev cdev;
	int gpio;
};

static void brightness_set_4412(struct led_classdev *led_cdev,
				  enum led_brightness brightness)
{
	struct led_classdev_4412 *dev = (struct led_classdev_4412 *)led_cdev;

	led_cdev->blink_brightness = brightness;
	
	if(brightness != LED_OFF)
		gpio_set_value(dev->gpio, 0);
	else
		gpio_set_value(dev->gpio, 1);
}

static struct led_classdev_4412 *led_devs;

static int __init leds_init(void)
{
	int  i,ret;
	/*1. alloc led_classdev */
	led_devs = kzalloc(sizeof(struct led_classdev_4412)*LED_NUM, GFP_KERNEL);
	if (led_devs == NULL) {
		printk("No memory for device\n");

	for (i = 0;i < LED_NUM;i++)
	{
		s3c_gpio_cfgpin(led_gpios[i].gpio, S3C_GPIO_OUTPUT);
		gpio_set_value(led_gpios[i].gpio, 1);
		/* 2. set */
		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;

		/* 3. 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;
		}
	}
}


static void __exit leds_exit(void)
{
	int i = 0;
	for (i = 0;i < LED_NUM;i++)
	{
		led_classdev_unregister(&led_devs[i]);
	}
	kfree(led_devs);	
}
module_init(leds_init);
module_exit(leds_exit);
MODULE_LICENSE("Dual BSD/GPL");
  • 将leds_4412.c上传到drivers/leds目录
  • 修改目录下drivers/ledsmakefile文件
    添加 obj-y += leds_4412.o
    在这里插入图片描述
    另外需要添加配置项,CONFIG_LEDS_CLASS CONFIG_LEDS_TRIGGERS
    trigger是用来控制led闪烁的,它需要定时器,CONFIG_LEDS_TRIGGER_TIMER
    在这里插入图片描述
  • make menuconfig 配置以上选项
    在这里插入图片描述
    在这里插入图片描述
  • 编译成功,重新烧录内核,重启itop4412开发板
    在这里插入图片描述
  • 发送一下语句,看看到开发板两个灯的亮灭
    在这里插入图片描述
  • 如何让led实现闪烁
    在这里插入图片描述
    可以看到设备led1有trigger,cat trigger
    在这里插入图片描述
    none表示当前的触发器为none,可以把trigger触发器设置为后边这三种,我们把timer设置到trigger中,看效果
    在这里插入图片描述
    可以看到led1闪烁,并且目录下出现了一些文件。
    可以设置led的闪烁亮灭时间
    在这里插入图片描述
    在这里插入图片描述
  • 分析
    echo timer > /sys/class/leds/led1/trigger
    当把timer 写到文件sys/class/leds/led1/trigger中时,led_trigger_store被调用
    在这里插入图片描述

首先trigger_name把buf中把name取出来,如果trigger等于none什么都不做返回,从triggerlist中找出相同名字的,如果相等,调用led_trigger_set(),把trigger放入到led_classdev的trigger_list链表中,
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AIOT技术栈

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值