linux驱动开发--内核定时器

简介: <p>1、内核定时器</p> <p>时钟中断:由系统的定时硬件以周期性的时间间隔发生,这个间隔(也就是频率)由内核根据常数HZ来确定。<br> HZ常数:她是一个与体系结构无关的常数,可以配置50-1200之间,可以在内核中配置<br> tick:她是HZ的倒数,也就是每发生一次硬件定时器中断的事件间隔。如HZ为200,tick为5毫秒。<br> jiffies核心变数:它是lin

1、内核定时器

时钟中断:由系统的定时硬件以周期性的时间间隔发生,这个间隔(也就是频率)由内核根据常数HZ来确定。
HZ常数:她是一个与体系结构无关的常数,可以配置50-1200之间,可以在内核中配置
tick:她是HZ的倒数,也就是每发生一次硬件定时器中断的事件间隔。如HZ为200,tick为5毫秒。
jiffies核心变数:它是linux核心变数(32位变数,unsigned long),它被用记录自开机以来,已经过多少个tick。每发生一次硬件定时器中断,jiffies变数会被加1。

定时器的作用:
内核定时器由用户控制某个函数(定时器函数)来特定的在未来某个时刻执行。
内核定时器注册的处理函数只执行一次(不是循环执行的)。

内核定时器定义:
在<linux/timer.h>中定义

struct timer_list
{
	struct list_head entry;//内核使用
	unsigned long expires;//超时时间jiffies的值
	void (*function)(unsigned long);//超时处理函数
	unsigned long data;//内核调用超时处理函数时传递给它的参数
	struct tvec_base *base;//内核使用
};

内核定时器操作:
静态初始化
TIMER_INITIALIZER(_function, _expires, _data)
_function:定时器处理函数
_expires:定时器超时jiffies值
_data:传递给定时器处理函数的参数

定义定时器
DEFINE_TIMER(_name, _function, _expires, _data);
_name:待定义的内核定时器变量名称
_function:定时器处理函数
_expires:定时器超时jiffies值
_data:传递给定时器处理函数的参数

动态初始化
void init_timer(struct timer_list *timer);
timer:待初始化的内核定时器
添加定时器
void add_timer(struct timer_list *timer);
timer:待初始化的内核定时器
删除定时器
该函数是在定时器超时前将定时器删除
实际上,在定时器超时后,系统会自动将其删除
void del_timer(struct timer_list *timer);
timer:待初始化的内核定时器

修改定时器
该函数实际相当于del_timer(), timer->expires=expires, add_timer()三个步骤
int mod_timer(struct timer_list *timer, unsigned long expires);
timer:待修改的内核定时器
expires:待修改内核定时器的新超时值
返回:返回0表示定时器处于不活动状态,返回1表示定时器处于活动状态

2、实例代码:

/**
*Copyright (c) 2013.TianYuan
*All rights reserved.
*
*文件名称: kerneltimer.c
*文件标识: 内核定时器 
*
*当前版本:1.0
*作者:wuyq 
*
*取代版本:xxx
*原作者:xxx
*完成日期:2013-11-25
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/timer.h>

MODULE_LICENSE("GPL");

/*定时器变量*/
struct timer_list bigdog_timer;

#define BARK_TIMER	5/*定时器时间间隔*/
#define BARK_COUNTS	10/*次数*/
void bigdog_timer_handler(unsigned long data)
{
	/*记录该函数被调用的次数*/
	static int bark_count = 0;
	
	printk("wangwang~~~~~~~~~%ld!\n", data);
	if(bark_count < BARK_COUNTS){
		bigdog_timer.expires = jiffies+HZ*BARK_TIMER;
		bigdog_timer.data++;
		add_timer(&bigdog_timer);
		
		bark_count++;
	}
}

int __init kerneltimer_init(void)
{
	/*初始化定时器变量*/
	init_timer(&bigdog_timer);
	bigdog_timer.expires = jiffies+HZ*BARK_TIMER;//超时时间.安装模块时间之后5秒
	bigdog_timer.function = bigdog_timer_handler;//处理函数;函数指针:void (*fun)(unsigned long)
	bigdog_timer.data = 100;
	
	/*添加定时器到内核中去*/
	add_timer(&bigdog_timer);
	printk("add_timer() Done!\n");
	
	return 0;
}

void __exit kerneltimer_exit(void)
{
	/*从内核中删除指定的定时器*/
	del_timer(&bigdog_timer);
	printk("del_timer() done!\n");
}

module_init(kerneltimer_init);
module_exit(kerneltimer_exit);

KERNELDIR ?=/root/Desktop/work/ldd3/linux-2.6.31_TX2440A
PWD := $(shell pwd)
obj-m += kerneltimer.o

default:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
	@rm -f *.o *.ord* *.sy* *.mod.* *.ko



目录
相关文章
|
7天前
|
安全 Linux 编译器
探索Linux内核的奥秘:从零构建操作系统####
本文旨在通过深入浅出的方式,带领读者踏上一段从零开始构建简化版Linux操作系统的旅程。我们将避开复杂的技术细节,以通俗易懂的语言,逐步揭开Linux内核的神秘面纱,探讨其工作原理、核心组件及如何通过实践加深理解。这既是一次对操作系统原理的深刻洞察,也是一场激发创新思维与实践能力的冒险。 ####
|
9天前
|
网络协议 Linux 调度
深入探索Linux操作系统的心脏:内核与系统调用####
本文旨在揭开Linux操作系统中最为核心的部分——内核与系统调用的神秘面纱,通过生动形象的语言和比喻,让读者仿佛踏上了一段奇妙的旅程,从宏观到微观,逐步深入了解这两个关键组件如何协同工作,支撑起整个操作系统的运行。不同于传统的技术解析,本文将以故事化的方式,带领读者领略Linux内核的精妙设计与系统调用的魅力所在,即便是对技术细节不甚了解的读者也能轻松享受这次知识之旅。 ####
|
6天前
|
缓存 算法 安全
深入理解Linux操作系统的心脏:内核与系统调用####
【10月更文挑战第20天】 本文将带你探索Linux操作系统的核心——其强大的内核和高效的系统调用机制。通过深入浅出的解释,我们将揭示这些技术是如何协同工作以支撑起整个系统的运行,同时也会触及一些常见的误解和背后的哲学思想。无论你是开发者、系统管理员还是普通用户,了解这些基础知识都将有助于你更好地利用Linux的强大功能。 ####
13 1
|
6天前
|
缓存 编解码 监控
深入探索Linux内核调度机制的奥秘###
【10月更文挑战第19天】 本文旨在以通俗易懂的语言,深入浅出地剖析Linux操作系统内核中的进程调度机制,揭示其背后的设计哲学与实现策略。我们将从基础概念入手,逐步揭开Linux调度策略的神秘面纱,探讨其如何高效、公平地管理系统资源,以及这些机制对系统性能和用户体验的影响。通过本文,您将获得关于Linux调度机制的全新视角,理解其在日常计算中扮演的关键角色。 ###
26 1
|
13天前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
54 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
14天前
|
网络协议 Linux 芯片
Linux 内核 6.11 RC6 发布!
【10月更文挑战第12天】
77 0
Linux 内核 6.11 RC6 发布!
|
2月前
|
存储 安全 Linux
探索Linux操作系统的心脏:内核
在这篇文章中,我们将深入探讨Linux操作系统的核心—内核。通过简单易懂的语言和比喻,我们会发现内核是如何像心脏一样为系统提供动力,处理数据,并保持一切顺畅运行。从文件系统的管理到进程调度,再到设备驱动,我们将一探究竟,看看内核是怎样支撑起整个操作系统的大厦。无论你是计算机新手还是资深用户,这篇文章都将带你领略Linux内核的魅力,让你对这台复杂机器的内部运作有一个清晰的认识。
71 3
|
2月前
|
网络协议 Ubuntu Linux
用Qemu模拟vexpress-a9 (三)--- 实现用u-boot引导Linux内核
用Qemu模拟vexpress-a9 (三)--- 实现用u-boot引导Linux内核
|
2月前
|
Linux
用clang编译Linux内核
用clang编译Linux内核
|
2月前
|
Linux API 调度
关于在Linux内核中使用不同延迟/休眠机制 【ChatGPT】
关于在Linux内核中使用不同延迟/休眠机制 【ChatGPT】