内核定时器的使用

内核定时器

(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");
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Linux内核定时器内核用于在未来某个时间点或者特定时间段内调度执行某个函数的一种机制。它是一个软定时器,最终依赖于CPU的硬件定时器实现。对于Linux内核来说,它依赖于系统时钟节拍。内核定时器的处理函数在软中断中执行。它有几个特点:依赖于系统时钟节拍、只执行一次,超时后即退出。如果需要周期性的定时器,需要在超时处理函数中重新开启定时器。在Linux内核编程中常常会使用定时器,例如在驱动程序中使用定时器解决按键消抖、延时等待硬件就绪等问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [【Linux驱动编程】如何使用内核定时器](https://blog.csdn.net/qq_20553613/article/details/106028620)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [【嵌入式Linux驱动开发】十四、了解Linux内核定时器使用流程,实现LED闪烁](https://download.csdn.net/download/weixin_38664427/14883898)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Enosji

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

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

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

打赏作者

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

抵扣说明:

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

余额充值