Linux设备驱动之timer定时器与延时
2018-01-26 14:03
344 查看
理论知识
原理介绍
软件意义上的定时器是依赖硬件定时器实现的,内核在时钟中断发生后检测各个定时器是否到期,如果到期,将到期的定时器的处理函数作为软中断的下半部执行。实质上,时钟中断处理程序会唤醒TIMER_SOFTIRQ软中断,运行当前处理器上到期的所有定时器。timer定时器的重要数据结构
struct timer_list { /* * All fields that change during normal runtime grouped to the * same cacheline */ struct hlist_node entry; unsigned long expires; //定时器的到期时间(jiffies) void (*function)(unsigned long); //定时器时间溢出时的触发函数 unsigned long data; //function的传入参数 u32 flags; int slack; #ifdef CONFIG_TIMER_STATS int start_pid; void *start_site; char start_comm[16]; #endif #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map; #endif };
expires一般用户毫秒级别的定时器
微妙和纳秒级别输入高精度定时器hrtimer范围,linux中有hrtimer结构
expires = jiffies + Hz; //expires触发时间为1S expires = jiffies + 10*Hz/1000 ; //expires触发时间为10ms expires = jiffies + 100*Hz/1000; //expires触发时间为100mS
timer定时器的常用方法
定义-初始化-触发struct timer_list my_timer; //定义 void init_timer(struct timer_list *timer); //初始化 add_timer(struct timer_list * timer); //添加定时器 del_timer(struct timer_list * timer); //删除定时器 mod_timer(struct timer_list *timer, unsigned long expires); //修改定时器
需要说明的是,add_timer或者mod_timer方法往往不会在init或者probe函数中调用,此函数为打开定时器的方法。
timer定时器使用示例
改示例代码中,定义一个gpio口为输入中断,有按键按下,1S后打印log。#include <linux/kernel.h> #include <linux/module.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/delay.h> #include <linux/time.h> #include <linux/input.h> #include <linux/init.h> #include <linux/gpio.h> #include <linux/timer.h> //timer结构体和相关函数的头文件 #include <linux/jiffies.h> //jiffies和HZ的头文件 #include <asm/io.h> #include <asm/irq.h> //平台相关,gpio口的定义 #define IMX_GPIO_NR(bank, nr) (((bank) - 1) * 32 + (nr)) #define CYNO_GPIO_BEEP_NUM IMX_GPIO_NR(6,10) //定义timer定时器 struct timer_list my_timer; static struct pin_desc{ int irq; unsigned char *name; unsigned int pin; }; static struct pin_desc beep_desc = { 0, "beep_num", CYNO_GPIO_BEEP_NUM }; //定时器处理函数 void timer_function(void) { printk("%s\n", __func__); } //按键中断触发函数 static irqreturn_t beep_interrupt_handler(int irq, void *dev_id) { printk("%s\n", __func__); mod_timer(&my_timer, jiffies + 1 * HZ); //按键按下,1S后出发定时器处理函数 return IRQ_HANDLED; } //module初始化函数 static int timer_base_init(void) { int ret; printk(KERN_INFO "%s\n", __func__); if(gpio_request(beep_desc.pin ,beep_desc.name)){ printk(KERN_ERR "%s : request gpio %d error\n", __func__, beep_desc.pin); goto err_gpio_request; } gpio_direction_input(beep_desc.pin); beep_desc.irq = gpio_to_irq(beep_desc.pin); printk(KERN_INFO "%s : the irq num is %d\n", __func__, beep_desc.irq); ret = request_irq(beep_desc.irq, beep_interrupt_handler , IRQF_TRIGGER_RISING | IRQF_ONESHOT, beep_desc.name , &beep_desc); if(ret){ printk(KERN_ERR "%s : request_irq is error\n", __func__); goto err_request_irq; } printk("%s : init end\n", __func__); init_timer(&my_timer); //定时器的初始化 my_timer.function = &timer_function; //绑定定时器的触发函数 return 0; err_request_irq: free_irq(beep_desc.irq, &beep_desc); err_gpio_request: gpio_free(beep_desc.pin); return -1; } static void timer_base_exit(void) { printk("%s\n", __func__); free_irq(beep_desc.irq, &beep_desc); gpio_free(beep_desc.pin); del_timer(&my_timer); //写在模块记得删除定时器 } module_init(timer_base_init); module_exit(timer_base_exit); MODULE_AUTHOR("xiaolei"); MODULE_DESCRIPTION("timer base use"); MODULE_LICENSE("GPL");
一些常用的延时方法
sleep延时
void msleep(unsigned int millisecs); //不能被打断 void long msleep_interruptible(unsigned int millisecs); //可被打断 void ssleep(unsigned int seconds); //不可被打断
忙等待延时
也就是while(1)式延时用于短延时!!! 一般用于硬件延时,比如i2c协议等
void ndelay(unsigned long nsecs); void udelay(unsigned long usecs); void mdelay(unsigned long msecs);
相关文章推荐
- 字符设备驱动之Buttons-定时器(timer)
- linux字符设备驱动-定时器按键去抖笔记
- 【Linux开发】linux设备驱动归纳总结(七):1.时间管理与内核延时
- 深入浅出:Linux设备驱动之中断与定时器
- 【Linux设备驱动程序(第三版)】----定时器:Timer
- Linux驱动之定时器和延时
- 【Linux开发】linux设备驱动归纳总结(七):2.内核定时器
- Linux设备驱动——内核定时器
- Linux设备驱动归纳总结(七):2.内核定时器
- linux字符设备驱动-定时器按键去抖笔记
- 07-S3C2440驱动学习(一)嵌入式linux字符设备驱动-按键驱动程序之异步通知机制+原子操作+互斥信号量+阻塞与非阻塞+定时器去抖
- Linux字符设备驱动之定时器去抖动按键驱动
- Linux驱动之定时器和延时
- linux驱动之内核定时器驱动设计-- timer
- Linux设备驱动之定时与延时
- linux 驱动 -》按键 中断 request_irq 延时防抖mod_timer
- Linux驱动--定时器timer小记
- Linux设备驱动之中断与定时器
- Linux设备驱动之定时器
- Linux设备驱动编程之定时器