0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux内核定时器

嵌入式技术 来源:嵌入式技术 作者:嵌入式技术 2022-09-22 08:56 次阅读

Linux内核定时器

在Linux内核中,也可以通过定时器来完成定时功能。但和单片机不同的是,Linux内核定时器是一种基于未来时间点的计时方式,它以当前时刻为启动的时间点,以未来的某一时刻为终止点,类似于我们的闹钟。
当内核定时器定时时间到达时,会进入用户指定的函数,相当于软中断。内核定时器完成注册启动后,仅执行一次后就不会重复执行(即超时候会自动关闭),若需要重复执行则需要手动再次启动(即修改超时时间)。
Linux内核定时器相关函数位置:include/linux/timer.h

1.相关结构体

  在使用内核定时器时,我们需要关心的相关结构体及其成员:

struct timer_list {
struct list_head entry;
unsigned long expires; /* 定时器时钟节拍*/
struct tvec_base *base;
void (*function)(unsigned long); /*定时器工作函数 */
unsigned long data; /*传给定时器工作函数的参数 */
};

 在Linux内核中,有一个全局变量jiffies用来记录时钟节拍,每当时钟中断触发一次,jiffies就会+1。因此jiffies变量记录了系统从启动开始时钟中断触发的次数。我们由此可以利用jiffies来计算驱动程序运行时长。jiffies每秒增加HZ次,因此jiffies+1的时长有HZ决定。当HZ=100时,jiffies+1的时长则为10ms。在Linux3.5的内核中HZ值默认为200,即jiffies+1的时长则为5ms。

poYBAGMrEGeAUwfeAANFKZpj6zU873.png#pic_center

2.相关函数

2.1 定时器初始化init_timer()

#define init_timer(timer)
函数功能: 初始化定时
形参: 定时器结构体

2.2 启动定时器add_timer()

void add_timer(struct timer_list *timer)
函数功能: 启动定时器
形参: 定时器结构体

2.3 修改定时时间mod_timer()

int mod_timer(struct timer_list *timer, unsigned long expires)
函数功能: 修改定时器时间
形参: timer – 定时器结构体
   expires --定时时间( 以时钟节拍填入)

  注意:expires 填写是基于jiffies+延时时间

2.4毫秒转为时钟节拍 msecs_to_jiffies()

unsigned long msecs_to_jiffies(const unsigned int m)
函数功能: 将毫秒时间转换为时钟节拍数
形参: m – 毫秒时间
返回值: – 返回节拍数

2.5微秒转为时钟节拍 usecs_to_jiffies()

unsigned long usecs_to_jiffies(const unsigned int u)
函数功能: 将微秒时间转换为时钟节拍数
形参: m – 位秒时间
返回值: – 返回节拍数

2.6关闭定时器

int del_timer(struct timer_list *timer)
函数功能:关闭定时器(停用一个定时器)
 define del_timer_sync(t)
函数功能:关闭定时器(停用一个定时器),多处理器使用。如果编内核时不支持 SMP(多处理器), del_timer_sync()和 del_timer()等价

2.7 获取jiffies时间

#include 
u64 get_jiffies_64(void)
函数功能: 获取jiffies时间
返回值: 返回时钟节拍jiffies

2.8 获取内核高精度时间

ktime_t ktime_get(void)
函数功能: 获取内核高精度时间
返回值: ktime_t – 共用体类型
union ktime {
	s64	tv64;
	#if BITS_PER_LONG != 64 && !defined(CONFIG_KTIME_SCALAR)
		struct
		 {
			# ifdef __BIG_ENDIAN
			s32	sec, nsec;
			# else
			s32	nsec, sec;
			# endif
		} tv;
	#endif
};

2.9 时间转换函数

s64 ktime_to_ms(const ktime_t kt) /* 将获取的系统时钟转换为ms单位*/
s64 ktime_to_us(const ktime_t kt) /* 将获取的系统时钟转换为us单位*/
/将获取的时间转换为时钟结构体/
struct timeval ktime_to_timeval(const ktime_t kt)
struct timespec ktime_to_timespec(const ktime_t kt)

3.内核定时器示例

  内核定时器使用步骤:

  1. 初始化内核定时器init_timer,设置超时时间,编写内核定时工作函数;
  2. 启动定时器add_timer;
  3. 若需要重复定时,则需要在定时器工作函数中修改超时时间mod_timer
#include 
#include 
#include 
#include 
#include 
struct timer_list timer;
/*定时器工作函数*/
void timer_work(unsigned long data)
{
	ktime_t time1;
	printk("定时器时间到!data=%ld,",data);
	time1=ktime_get();
	printk("定时时间:%llu \n",ktime_to_ms(time1));
	mod_timer(&timer,jiffies+msecs_to_jiffies(2000));/*修改定时时间*/
}
static int __init wbyq_timer_init(void)
{
	timer.expires=jiffies+msecs_to_jiffies(1000);/*定时时间*/
	timer.function=timer_work;/*定时器工作函数*/
	timer.data=666;/*传给定时器工作函数参数,选填*/
	init_timer(&timer);/*初始化定时器*/
	add_timer(&timer);/*启动定时器*/
	return 0;
	
}
/*驱动释放*/
static void __exit wbyq_timer_cleanup(void)
{
	del_timer_sync(&timer);//关闭定时器
    printk("驱动出口,驱动注销成功\n");
}
module_init(wbyq_timer_init);//驱动入口函数
module_exit(wbyq_timer_cleanup);//驱动出口函数

MODULE_LICENSE("GPL");//驱动注册协议
MODULE_AUTHOR("it_ashui");
MODULE_DESCRIPTION("Exynos4 timer Driver");
pYYBAGMrEGiANQMXAAEDRiQZ9h4278.png#pic_center  

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内核
    +关注

    关注

    3

    文章

    1372

    浏览量

    40276
  • Linux
    +关注

    关注

    87

    文章

    11292

    浏览量

    209323
  • 定时器
    +关注

    关注

    23

    文章

    3246

    浏览量

    114719
收藏 人收藏

    评论

    相关推荐

    Linux驱动开发-内核定时器

    内核定时器内核用来控制在未来某个时间点(基于jiffies(节拍总数))调度执行某个函数的一种机制,相关函数位于 和 kernel/timer.c 文件
    的头像 发表于 09-17 15:06 1465次阅读

    芯灵思SinlinxA33开发板Linux内核定时器编程

    Linux 内核定时器内核用来控制在未来某个时间点(基于jiffies)调度执行某个函数的一种机制,其实现位于和 kernel/timer.c 文件中。内核定时器的数据结构struc
    发表于 02-14 14:55

    「正点原子Linux连载」第五十章Linux内核定时器实验

    1)实验平台:正点原子Linux开发板2)摘自《正点原子I.MX6U嵌入式Linux驱动开发指南》关注官方微信号公众号,获取更多资料:正点原子第五十章Linux内核定时器实验
    发表于 03-20 11:22

    「正点原子Linux连载」第五十章Linux内核定时器实验

    ,获取更多资料:正点原子第五十章Linux内核定时器实验定时器是我们最常用到的功能,一般用来完成定时功能,本章我们就来学习一下Linux
    发表于 03-20 11:22

    【正点原子FPGA连载】第三十二章Linux内核定时器实验-领航者ZYNQ之linux开发指南

    原子公众号,获取最新资料第三十二章Linux内核定时器实验定时器是我们最常用到的功能,一般用来完成定时功能,本章我们就来学习一下Linux
    发表于 09-20 16:57

    STM32设置内核定时器延时

    STM32设置内核定时器延时
    发表于 08-10 06:30

    ARM Cortex-M0+内核定时器

    慕课苏州大学.嵌入式开发及应用.第三章.基本模块.ARM Cortex-M0+内核定时器 (Systic0 目录3 基本模块3.1 ARM Cortex-M0+内核定时器 (Systic3.1.1
    发表于 11-08 06:36

    Linux内核定时器的相关资料分享

       致敬英雄!一、Linux内核定时器初探1、图形界面配置系统节拍率  中断周期性产生的频率就是系统频率,也叫做节拍率(tick rate),单位是 Hz。系统节拍率是可以设置的,在编
    发表于 12-16 07:37

    Linux内核定时器的相关资料分享

    文章目录Linux内核定时器概念Linux内核定时器基础知识Linux内核定时器相关函数时间转换
    发表于 12-20 08:05

    Win32s下内核定时器的使用

    本文介绍了一种Win32s 环境下的内核定时器的用法。该定时器相比常用的多媒体定时器有两个优点:1,消耗资源更少。2,无需消息队列。在操作系统负载很重的情况下,该定时器
    发表于 06-15 10:00 32次下载

    LINUX内核定时器(高精度&低精度)

    linux内核2.6.16开始引入了高精度定时器,达到ns级别。自此,内核拥有两套并行计时,低精度和高精度。如果高精度没有开启,即使使用
    发表于 05-13 09:41 4142次阅读

    Linux内核定时器的详细资料概述

    前面我们对按键驱动的开发已经基本完成了,但是当你对按键多次按下的时候,你会发现打印的返回值是不正确的,这是什么原因呢?学过51单片机的同学你们都应该知道按键容易产生抖动,俗称“消抖”,我以前的处理办法是设置一个延时10ms,现在我们的按键也是需要延时的,当过了10ms我们在去读这个按键值。
    发表于 04-23 18:29 2次下载
    <b class='flag-5'>Linux</b><b class='flag-5'>内核定时器</b>的详细资料概述

    Linux内核定制方法

    Linux内核定制方法说明。
    发表于 03-25 11:25 9次下载

    慕课嵌入式开发及应用(第三章.ARM Cortex-M0+内核定时器 (Systic)

    慕课苏州大学.嵌入式开发及应用.第三章.基本模块.ARM Cortex-M0+内核定时器 (Systic0 目录3 基本模块3.1 ARM Cortex-M0+内核定时器 (Systic3.1.1
    发表于 11-03 14:51 13次下载
    慕课嵌入式开发及应用(第三章.ARM Cortex-M0+<b class='flag-5'>内核定时器</b> (Systic)

    Linux内核时钟系统和定时器实现

    Linux内核时钟系统和定时器实现 Linux 2.6.16之前,内核只支持低精度时钟,内核定时器
    的头像 发表于 11-09 09:12 1461次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b>时钟系统和<b class='flag-5'>定时器</b>实现