内核定时器的使用

内核定时器

(1)内核是给应用层提供接口的,一般延时都是由用户来完成的。所以在内核中不会使用延时函数,都是用内核定时器来完成

struct timer_list {
		unsigned long expires;
		//定时的时间
		void (*function)(struct timer_list *);
		//定时器处理函数
	};

	1.分配对象
		struct timer_list mytimer;
		
	2.对象初始化
		jiffies:时钟节拍数,在内核启动的时候,这个
			值随着系统的运行一直在增加。
			CONFIG_HZ=100 ---->  0.01s = 10ms 	
		void mytimer_function(struct timer_list *)
		{
			
			
		}
		mytimer.expires = jiffies + HZ; //HZ代表定义1s钟
		timer_setup(&mytimer, mytimer_function, 0);
		
		注:最后一个参数是flags:这个flags是和定时器运行在
			那个cpu上相关的一个标志位,默认填充0即可。
			timer->flags = flags | raw_smp_processor_id();

		3.注册
		void add_timer(struct timer_list *timer)
		//将timer_list放入内核链表,并开启内核定时
		//定时器只会启动一次
		
		int mod_timer(struct timer_list *timer, 
			unsigned long expires)
		//再次启动定时器
	4.注销定时
		int del_timer(struct timer_list *timer)
----------------------------------------------------	

代码实例

#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/timer.h>
/*
fsled{
	 compatible = "fsmp1a,fsled";
	 core_led = <&gpioz 5 0>,<&gpioz 6 0>,<&gpioz 7 0>;
	 extend_led =<&gpioe 10 0>,<&gpiof 10 0>,<&gpioe 8 0>;
 }; 			 
*/

int core_led[3] = {0};
int extend_led[3] = {0};
struct timer_list mytimer;


struct device_node *fsled;
int get_fsled_node(void)
{
	fsled = of_find_node_by_path("/fsled");
	if(fsled == NULL){
		printk("get fsled node error\n");
		return -ENODEV;
	}
	return 0;
}
int fsled_all_init(void)
{
	int i,ret;
	for(i=0;i<ARRAY_SIZE(core_led);i++){
		core_led[i] = of_get_named_gpio(fsled,"core_led",i);
		if(core_led[i] < 0){
			printk("get node gpio error\n");
			return core_led[i];
		}
		extend_led[i] = of_get_named_gpio(fsled,"extend_led",i);
		if(extend_led[i] < 0){
			printk("get node gpio error\n");
			return extend_led[i];
		}
		printk("core_led[%d] = %d,extend_led[%d] = %d\n",
			i,core_led[i],i,extend_led[i]);

		ret = gpio_request(core_led[i] ,NULL);
		if(ret){
			printk("gpio %d request error\n",core_led[i]);
			return ret;
		}
		gpio_direction_output(core_led[i],1);
		
		ret = gpio_request(extend_led[i] ,NULL);
			if(ret){
				printk("gpio %d request error\n",extend_led[i]);
				return ret;
		}

		gpio_direction_output(extend_led[i],1);
		
	}

	return 0;
}
void mytimer_function(struct timer_list *timer)
{
	//set led
	int i;
	for(i=0;i<ARRAY_SIZE(core_led);i++){
		gpio_set_value(core_led[i],!gpio_get_value(core_led[i]));
		gpio_set_value(extend_led[i],!gpio_get_value(extend_led[i]));
	}
	
    //再次启动计时器,再次启动不能调用add_timer 得用mod_timer
	mod_timer(&mytimer,jiffies + HZ);
}

static int __init fsled_init(void)
{
	int ret;

	if((ret = get_fsled_node())<0){
		return ret;
	}
	if((ret = fsled_all_init())<0){
		return ret;
	}
	//初始化计时器
	mytimer.expires = jiffies + HZ;
	timer_setup(&mytimer,mytimer_function,0);
    //启动计时器
	add_timer(&mytimer);
	
	return 0;
}
static void __exit fsled_exit(void)
{
	int i;
	del_timer(&mytimer);

	for(i=0;i<ARRAY_SIZE(core_led);i++){
		gpio_free(core_led[i]);
		gpio_set_value(core_led[i],0);
		gpio_free(extend_led[i]);
		gpio_set_value(extend_led[i],0);
	}
}
module_init(fsled_init);
module_exit(fsled_exit);
MODULE_LICENSE("GPL");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Enosji

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

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

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

打赏作者

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

抵扣说明:

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

余额充值