1、定时器

之前说过两类跟时间相关的内核结构。

1、延时:通过忙等待或者睡眠机制实现延时。

2、tasklet和工作队列,通过某种机制使工作推后运行,但不知道运行的详细时间。

接下来要介绍的定时器,可以使工作在指定的时间点上运行。并且不须要使用忙等待这类的延时方法。

通过定义一个定时器,告之内核在哪个时间须要运行什么函数就行了。等时间一到,内核会就运行指定的函数。

2、使用定时器

定时器的使用非常easy,仅仅须要三部:

1、定义定时器结构体timer_list。

2、设置超时时间,定义定时器处理函数和传參。

3、激活定时器

代码

#include <linux/module.h>
#include <linux/init.h> #include <linux/sched.h>
#include <linux/timer.h> #if 0 //定义并初始化定时器结构体timer_list。
/*include/linux/timer.h*/
struct timer_list {
struct list_head entry;
unsigned long expires; //设置在运行定时器处理函数的时间 void (*function)(unsigned long); //定时器处理函数
unsigned long data; //处理函数的传參 struct tvec_base *base; #ifdef CONFIG_TIMER_STATS
void *start_site;
char start_comm[16];
int start_pid;
#endif };
#endif struct timer_list my_timer; //1.定义定时器结构体timer_list void timer_func(unsigned long data) //2.定义定时器处理函数
{
printk("time out![%d] [%s]\n", (int)data, current->comm); //打印当前进程
} static int __init test_init(void) //模块初始化函数
{
init_timer(&my_timer); //1.初始化timer_list结构 my_timer.expires = jiffies + 5*HZ; //2.设定定时器处理函数触发时间为5秒
my_timer.function = timer_func; //2.给结构体指定定时器处理函数
my_timer.data = (unsigned long)99; //2.设定定时器处理函数的传參 add_timer(&my_timer); //3.激活定时器
printk("hello timer,current->comm[%s]\n", current->comm);
return 0;
} static void __exit test_exit(void) //模块卸载函数
{
printk("good bye timer\n");
}

三、定时器的删除和改动

上面说了。激活定时器后仅仅能运行一遍。假设要实现隔指定时间又反复运行,那就要改动一下代码。

在定时器处理函数中加上两条代码:

my_timer.expires = jiffies + 2*HZ; //又一次设定时间,在两秒后再运行

add_timer(&my_timer); //再次激活定时器

这种话,每一个2秒就会再次运行定时器处理函数。

这两条代码也相当与一下的函数:

mod_timer(&my_timer, jiffies + 2*HZ);

/*kernel/timer.c*/

int mod_timer(struct timer_list *timer, unsigned long expires)

这是改变定时器超时时间的函数,假设在指定的定时器(timer)没超时前调用,超时时间会更新为新的新的超时时间(expires)。假设在定时器超时后调用。那就相当于又一次指定超时时间并再次激活定时器。

假设想在定时器没有超时前取消定时器,能够调用下面函数:

/*kernel/timer.c*/

int del_timer(struct timer_list *timer)

该函数用来删除还没超时的定时器。


Linux 驱动之内核定时器的更多相关文章

  1. Linux驱动之内核自带的S3C2440的LCD驱动分析

    先来看一下应用程序是怎么操作屏幕的:Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里提供的中断调用来实现直接写屏,Linux抽象出FrameBuffer这个设备来供用户 ...

  2. 【Linux驱动】内核等待队列

    在Linux中, 一个等待队列由一个"等待队列头"来管理,等待队列是双向链表结构. 应用场合:将等待同一资源的进程挂在同一个等待队列中. 数据结构 在include/linux/w ...

  3. Linux驱动:内核等待队列

    在Linux中, 一个等待队列由一个"等待队列头"来管理,等待队列是双向链表结构. 应用场合:将等待同一资源的进程挂在同一个等待队列中. 数据结构 在include/linux/w ...

  4. Linux驱动之内核加载模块过程分析

    Linux内核支持动态的加载模块运行:比如insmod first_drv.ko,这样就可以将模块加载到内核所在空间供应用程序调用.现在简单描述下insmod first_drv.ko的过程 1.in ...

  5. linux驱动之内核多线程(四)

    本文摘自 http://www.cnblogs.com/zhuyp1015/archive/2012/06/13/2548494.html 自己创建的内核线程,当把模块加载到内核之后,可以通过:ps ...

  6. linux驱动之内核多线程(二)

    本文摘自http://www.cnblogs.com/zhuyp1015/archive/2012/06/11/2545702.html 内核多线程是在项目中使用到,自己也不熟悉,遇到一个很囧的问题, ...

  7. linux驱动之内核多线程(一)

    本文摘自http://www.cnblogs.com/zhuyp1015/archive/2012/06/11/2545624.html Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进 ...

  8. linux驱动之内核多线程(三)

    本文摘自 http://www.cnblogs.com/zhuyp1015/archive/2012/06/13/2548458.html 接上 一篇文章 ,这里介绍另一种线程间通信的方式:compl ...

  9. 编写linux驱动所用到的头文件(转)

    转自:http://blog.csdn.net/lufeiop02/article/details/6448497 关于linux驱动(应用)程序头文件使用 收藏 驱动程序: #include < ...

随机推荐

  1. MVC实现有关时间的进度条,使用jQuery ui的progressbar

    在电商网站中,有时候通过进度条来直观地显示用户是否到期以及用户当前的状态. 设计这样的一个Model. public class User { public int Id { get; set; } ...

  2. Cesium 坐标系转换

    cesium中常用的坐标有两种WGS84地理坐标系和笛卡尔空间坐标系(世界坐标).我们平时常用的以经纬度来指明一个地点就是用的WGS84坐标,笛卡尔空间坐标系常用来做一些空间位置变换如平移旋转缩放等等 ...

  3. 【docker】centOS7上部署的mysql和spring boot服务,要求,mysql的时间、java程序服务的时间和宿主机的时间完全保持一致【修改mysql时区,临时和永久】【修改spring boot配置文件时区】【修改docker启动spring boot实例程序时区】

    要求:centOS7上部署的mysql和spring boot服务,要求,mysql的时间.java程序服务的时间和宿主机的时间完全保持一致: ============================ ...

  4. Windows 8 Metro 应用开发入门(一):开发环境介绍

    摘 要 Windows8已经发布,随之而来的基于WinRT的Metro应用也正向我们走来,正像它所宣传的:光滑.快.现代.看习惯了玻璃.立体风格的应用,或许Metro的简洁能给你留下不一样的体验.Vi ...

  5. 如何在tomcat启动时自动加载一个类

    有时候在开发web应用的时候,需要tomcat启动后自动加载一个用户的类,执行一些初始化方法,如从数据库中加载业务字典到内存中,因此需要在tomcat启动时就自动加载一个类,或运行一个类的方法. 可以 ...

  6. java中需要用equals来判断两个字符串值是否相等

    在C++中,两个字符串比较的代码可以为: (string1==string2) 但在java中,这个代码即使在两个字符串完全相同的情况下也会返回false Java中必须使用string1.equal ...

  7. [转]我花了一个五一终于搞懂了OpenLDAP

    轻型目录访问协议(英文:Lightweight Directory Access Protocol,缩写:LDAP)是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的 ...

  8. go的基结构体如何使用派生结构体的方法

    将派生类的方法声明为接口嵌入到基结构体中,派生结构体声明该接口为自身.

  9. 依赖注入 DI 控制反转 IOC MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  10. OkHttp 官方Wiki之【使用案例】

    原文位置:https://github.com/square/okhttp/wiki/Recipes Recipes 食谱/知识点清单 We've written some recipes that ...