实现一个简单的定时器驱动代码

屏亮无操作,按键灯5s 后自动熄灭
实现场景:
1)按下按键后检测到按键中断,在中断函数中点亮按键灯并且启动定时器定时五秒,时间到关闭按键灯。
2)当点亮屏幕后,点亮按键灯并且启动定时器定时五秒,时间到关闭按键灯。
@ \kernel\drivers\input\keyboard\aw9523.c

#include <linux/jiffies.h>//jiffies调用头文件
#include <linux/timer.h> //timer_list结构体

u32 bl_level_bakup = 0; // 备份bl_level (当前屏幕背光的亮度值),用于点亮按键灯的亮度,bl_level是一个局部变量
static bool is_btn_leds_timer_onoff = false; // 定时器开 flag

static struct timer_list btn_leds_ms_timer; //定义timer_list结构体
static void btn_leds_ms_timer_func_handler(unsigned long a); //声时定时器函数
void aw9523_buttonleds_set_timer_on(u32 bl_level); //*********************

void aw9523_key_work()
{
    // 在按键处理函数中 调用封装好的代码
    //*********************
    aw9523_buttonleds_set_timer_on(bl_level_bakup)   //同理,panel.c 中也直接调用这个 
}

@ 点亮按键灯并且启动定时器定时五秒,时间到关闭按键灯。
void aw9523_buttonleds_set_timer_on(u32 bl_level)
{
	if(bl_level == 0){    //*********************
		// 判断当前定时器是否开启了
		if (is_btn_leds_timer_onoff == true){
			del_timer(&btn_leds_ms_timer);  // 移除定时器
		}
		//如果是灭屏,则不启动定时器,直接关灯
		aw9523_buttonleds_set(bl_level);    
		
	}else{
		// 如果是亮屏状态
		//cancel timer 如果定时器已经开启过了,说明此时按键灯已经是开启状态,则清除定时器
		if (is_btn_leds_timer_onoff == true)
		{
	        printk("hyl_timer [%s][%d] --start to restart timer-- ----- 333333-----\n",__func__,__LINE__);
			//如果之前已经有按过,则删定时器,并重新启动定时器
	        mod_timer(&btn_leds_ms_timer, jiffies+msecs_to_jiffies(1000 * 5));
		}
		else
		{
	        printk("hyl_timer [%s][%d] --start timer------- 222222----- \n",__func__,__LINE__);
			// 如果定时器没有开启过,则说明按键灯没有开启过,则开启按键背光
			// light up button leds   hyl_leds +++
	        // ------------此处先注释,看看log--------log 正常 后开启
	
	        // 定义定时器中断时间: 5s 后进入中断                   
	        btn_leds_ms_timer.expires = jiffies + msecs_to_jiffies(1000 * 5);  
	        // 绑定定时器的计时到达时候的操作函数
	        btn_leds_ms_timer.function = btn_leds_ms_timer_func_handler;            
	        // 启动定时器
	        add_timer(&btn_leds_ms_timer);   //增加注册定时器,使定时器生效
		}
		aw9523_buttonleds_set(bl_level);     //*********************
		is_btn_leds_timer_onoff = true;
	}
}

// 定时器函数代码,定义定时器处理函数
static void btn_leds_ms_timer_func_handler(unsigned long a)
{
    printk("hyl_timer [%s][%d] --timer end ,start turn off leds ----- 4444------- \n",__func__,__LINE__);

	// close button leds
    // ------------此处先注释,看看log--------log 正常 后开启
	//aw9523_buttonleds_set(0); 
	// 清楚定时器开关标志位
	is_btn_leds_timer_onoff = false;  
}
static int aw9523_probe(struct i2c_client *client, const struct i2c_device_id *id)
{

    // 初始化定时器
    init_timer(&btn_leds_ms_timer);      
    // 定义定时器中断时间: 5s 后进入中断                   
    btn_leds_ms_timer.expires = jiffies + msecs_to_jiffies(1000 * 5);  
    // 绑定定时器的计时到达时候的操作函数
    btn_leds_ms_timer.function = btn_leds_ms_timer_func_handler;            

    printk("hyl_timer [%s][%d] add timer success ----- 111111-----\n",__func__,__LINE__);

    // 此时不启动定时器
    // add_timer(&btn_leds_ms_timer);                           //增加注册定时器,使定时器生效
}
static int aw9523_release(struct i2c_client *client, const struct i2c_device_id *id)
{
    // 删除化定时器
    del_timer(&btn_leds_ms_timer);
}

增加工作队列:

#include <linux/workqueue.h>
// 工作队列定义
static struct work_struct leds_work;
//---> 把这个函数的代码还原
void aw9523_buttonleds_set_timer_on(void)
{
	if(btn_leds_timer_onoff == true)
	{
		printk("---hyl---timer[%s][%d]--33333-start to restart timer\n",__func__,__LINE__);
		mod_timer(&btn_leds_ms_timer,jiffies+msecs_to_jiffies(1000*5));
	}
	else
	{
		printk("---hyl---timer[%s][%d]--------22222----------start timer\n",__func__,__LINE__);
		aw9523_buttonleds_set(0);
		btn_leds_ms_timer.expires = jiffies + msecs_to_jiffies(1000*5);
		btn_leds_ms_timer.function = btn_leds_ms_timer_func_handler;
		add_timer(&btn_leds_ms_timer);
	}
	btn_leds_timer_onoff = true;
} 
// 工作队列运行函数 ,将之前定时器函数中的工作 ,全搬过来,在工作队列中, 关闭灯
static void leds_work_handler(struct work_struct *data)
{
    printk("hyl_timer [%s][%d] --timer end ,start turn off leds ----- 5555------- \n",__func__,__LINE__);
	aw9523_buttonleds_set(0);  // close button leds
	
	// 清除定时器开关标志位
	is_btn_leds_timer_onoff = false; 
}
// 定义定时器处理函数  , 定时器时间到达后只负表 让CPU调度leds_work_handler()
static void btn_leds_ms_timer_func_handler(void)
{
    printk("hyl_timer [%s][%d] --timer end ,start turn off leds ----- 4444------- \n",__func__,__LINE__);
	schedule_work(&leds_work); // 让CPU 调度工作队列, cpu 会创建线程执行leds_work_handler()这个函数
}
void probe (){
	// 这个代码,在初始化定时器后面增加
	INIT_WORK(&leds_work, leds_work_handler);  //初始化工作队列,绑定  leds_work_handler() 这个函数
}

增加proc 调试节点:

#include <linux/proc_fs.h>

void xxxxx_aaa(void)
{
   printk("hyl_timer [%s][%d] ---- \n",__func__,__LINE__);
   //打开背光
   //启动 5s 定时器
   ms_timer.expires=jiffies+msecs_to_jiffies(1000 * 5);
   ms_timer.function=ms_timer_handler;
   add_timer(&ms_timer);
}
static ssize_t igh_gfar_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *f_pos)
{
    xxxxx_aaa();  // 此处加上 ,打开背光,启动 5s 定时器
	return count;
}
struct proc_dir_entry *leds_proc_dir = NULL;
static int32_t xxx_probe(void)
{
	struct proc_dir_entry* leds_file;
    leds_proc_dir = proc_mkdir("leds_back", NULL);
	leds_file = proc_create("leds_onoff", 0777, leds_proc_dir, &leds_proc_fops);
	
}	
static xxxx_release(void){

    del_timer(&ms_timer);
	remove_proc_entry("leds_onoff", leds_proc_dir);
	remove_proc_entry("leds_back", NULL);
发布了93 篇原创文章 · 获赞 10 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/jinron10/article/details/104690648