内核定时器

二. Linux 内核定时器基础知识

Linux 内 核 使 用 timer_list 结 构 体表示内核定时器 ,timer_list定义在文件 include/linux/timer.h 中,定义如下:

struct timer_list { struct list_head entry;unsigned long expires; /* 定时器超时时间,不是时长,单位是节拍数 */struct tvec_base *base;void (*function)(unsigned long); /* 定时处理函数 */unsigned long data; /* 要传递给 function 函数的参数 */ int slack;
};

在这个结构体中,有几个参数需要重点关注。 一是 expires 到期时间,单位是节拍数。 等于定时的当前的时钟节拍计数(存储在系统的全局变量 jiffies)+定时时长对应的时钟节拍数量。

那么怎么把时间转换成节拍数量呢?

示例:从现在开始定时 1 秒:内核中有一个宏 HZ, 表示一秒对应的时钟节拍数,那么就可以通过这个宏来把时间转换成节拍数。 所以,定时 1 秒就是:expires = jiffies + 1*HZ 。 HZ 的值是可以设置的,也就是说一秒对应的时钟拍数是可以设置的,Linux 内核会使用CONFIG_HZ 来设置系统时钟 。

打 开 文 件 include/asm generic/param.h , 有如下内容:

# undef HZ
# define HZ CONFIG_HZ
# define USER_HZ 100宏

HZ 就是 CONFIG_HZ,因此 HZ=100,表示一秒的节拍数是 100 , 在编译 Linux 内核的时候可以通过图形化界面设置系统节拍率,按照如下路径打开配置界面。通过上图可以发现可选的系统节拍率为 100Hz 、 200Hz 、 250Hz 、 300Hz 、 500Hz 和 1000Hz 。 默认是 100Hz 。

第二个需要关心的参数是 function 超时处理函数,这个并不是硬件中断服务程序。 原型:void function(unsigned long data);

第三个参数是 data 传递给超时处理函数的参数,可以把一个变量的地址转换成 unsigned long 。

三、Linux 内核定时器相关操作函数

1、时间转换函数

<1>ms 转换为时钟节拍函数

 unsigned long msecs_to_jiffies(const unsigned int m)

<2>us 转换为时钟节拍函数

 unsigned long usecs_to_jiffies(const unsigned int u)

举例:

<1> 定时10ms

计算: jiffies +msecs_to_jiffies(10)

<2> 定时10us

计算: jiffies +usecs_to_jiffies(10)

<2> 宏 DEFINE_TIMER

原型: #define DEFINE_TIMER(_name, _function, _expires, _data)

作用:静态定义结构体变量并且初始化初始化 function, expires, data 成员。

参数: _name 变量名;

_function 超时处理函数 ;

_data 传递给超时处理函数的参数 _expires 到点时间,一般在启动定时前需要重新初始化。

<3>add_timer 函数

原型: void add_timer(struct timer_list *timer)

作用: add_timer函数用于向Linux 内核注册定时器,使用 add_timer 函数向内核注册定时器以后,定时器就会开始运行

参数:
timer : 要注册的定时器。

<4>del_timer 函数

原型: int del_timer(struct timer_list * timer)

作用: del_timer 函数用于删除一个定时器,不管定时器有没有被激活,都可以使用此函数删除。 在多处理器系统上,定时器可能会在其他的处理器上运行,因此在调用 del_timer 函数 删除定时器之前要先等待其他处理器的定时处理器函数退出

timer : 要删除的定时器。

返回值: 0 , 定时器还没被激活; 1 , 定时器已经激活。

<5>mod_timer 函数

函数原型: int mod_timer(struct timer_list *timer, unsigned long expires)

作用: mod_timer 函数用于修改定时值,如果定时器还没有激活的话, mod_timer 函数会 激活定时器!

参数:
timer : 要修改超时时间 ( 定时值 ) 的定时器。
expires : 修改后的超时时间。

返回值:
0 , 调用 mod_timer 函数前定时器未被激活;
1 , 调用 mod_timer 函数前定时器已被激活。

实践课

每隔1s,打印一句话。

定时器初始化:

#include <linux/timer.h>DEFINE_TIMER(test_timer,timer_function,0,0);static int hello_init(void)
{printk("hello world\n");test_timer.expires = jiffies + 1*HZ;//jiffies相当于手机的当前时刻!!!add_timer(&test_timer);//启动定时器return 0;
}

超时处理函数,让超时之后继续加载:

static void timer_function(unsigned long data)
{printk("This is timer function\n");//重新开启定时器mod_timer(&test_timer,jiffies + 1*HZ);
}

按键消抖

#include <linux/timer.h>DEFINE_TIMER(test_timer,timer_function,0,0);static void timer_function(unsigned long data)
{//超时时间处理函数
}

中断处理函数:

irq_handler_t test_key(int irq, void *args)//中断处理函数
{test_timer.expires = jiffies + msecs_to_jiffies(20) ;//jiffies相当于手机的当前时刻!!!add_timer(&test_timer);//启动定时器return IRQ_HANDLED;
}

迅为嵌入式linux驱动开发笔记(八)—内核定时器相关推荐

  1. 迅为嵌入式linux驱动开发笔记(十一)—触摸屏驱动

    总结篇 这一小节内容是对之前学习的十节课进行总复习,综合性非常强,完成触摸屏驱动需要学会如下知识: 1.驱动开发原理 第一节 2.platform平台总线模型 第三节 3.设备树 第四节 4.gpio ...

  2. 嵌入式Linux驱动开发笔记(未完待续。。。)

    零.嵌入式Linux驱动编程思想 1.面向对象(把一个事件抽象成一个结构体) 2.分层 3.分离 一.Git仓库用法 1.linu终端输入下面命令安装 git clone https://e.codi ...

  3. 嵌入式linux驱动开发实战教程,嵌入式Linux驱动开发实战视频教程

    嵌入式Linux驱动开发实战教程(内核驱动.看门狗技术.触摸屏.视频采集系统) 适合人群:高级 课时数量:109课时 用到技术:嵌入式 Linux 涉及项目:驱动开发.看门狗技术.触摸屏.视频采集 咨 ...

  4. 【嵌入式Linux】嵌入式Linux驱动开发基础知识之Pinctrl子系统和GPIO子系统的使用

    文章目录 前言 1.Pinctrl子系统 1.1.为什么有Pinctrl子系统 1.2.重要的概念 1.3.代码中怎么引用pinctrl 2.GPIO子系统 2.1.为什么有GPIO子系统 2.2.在 ...

  5. 【嵌入式Linux】嵌入式Linux驱动开发基础知识之按键驱动框架

    文章目录 前言 1.APP怎么读取按键值 1.1.查询方式 1.2.休眠-唤醒方式 1.3.poll方式 1.3.异步通知方式 1.5. 驱动程序提供能力,不提供策略 2.按键驱动程序框架--查询方式 ...

  6. 【嵌入式Linux】嵌入式Linux驱动开发基础知识之LED模板驱动程序的改造:设备树

    文章目录 前言 1.驱动的三种编写方法 2.怎么使用设备树写驱动程序 2.1.设备树节点要与platform_driver能匹配 2.2.修改platform_driver的源码 3.实验和调试技巧 ...

  7. 【嵌入式Linux】嵌入式Linux驱动开发基础知识之设备树模型

    文章目录 前言 1.设备树的作用 2.设备树的语法 2.1.设备树的逻辑图和dts文件.dtb文件 2.1.1.1Devicetree格式 1DTS文件的格式 node的格式 properties的格 ...

  8. 【嵌入式Linux】嵌入式Linux驱动开发基础知识之总线设备驱动模型

    文章目录 前言 1.驱动编写的三种方法 1.1.传统写法 1.2.总线驱动模型 1.3.设备树驱动模型 2.Linux实现分离:Bus/Dev/Drv模型 2.1.Bus/Dev/Drv模型 2.2. ...

  9. 【嵌入式Linux】嵌入式Linux驱动开发基础知识之驱动设计的思想:面向对象/分层/分离

    文章目录 前言 1.分离设计 驱动程序分析---程序分层 通用驱动程序---面向对象 个性化驱动程序---分离 APP 程序分析 前言 韦东山嵌入式Linux驱动开发基础知识学习笔记 文章中大多内容来 ...

最新文章

  1. 可持久化数据结构讲解
  2. java数据结构至对称矩阵压缩存储
  3. OpenCV转换PyTorch分类模型并使用OpenCV C ++启动
  4. python异常值检测_python – 使用RPCA的异常值
  5. ANSYS——查看某一截面的云图分布(也叫做切片图)
  6. 张正友相机标定Opencv实现以及标定流程标定结果评价图像矫正流程解析(附标定程序和棋盘图)
  7. 【资源】史上最全数据集汇总
  8. 书里书外丨大咖论“赛”:阿里云天池 TOP 选手不得不说的那些事儿
  9. JS Map与JSON转换
  10. Python - OpenCV 图像二值化处理
  11. w3school学习笔记2(MySQL)
  12. word内容被锁定无法进行修改的解决办法
  13. vmdk to vhdx 虚拟磁盘格式转换qemu-img
  14. 计算机视觉中的多视图几何<Part0—基础知识:射影几何、变换和估计>(3)
  15. 计算机课word反思,教学反思Word文档
  16. 手把手教你接入微信开放平台,实现网站拉起微信账号登录,从0开始详细记录
  17. 招募中|一个小时变身AI应用部署专家,NVIDIA专场公开课 端云边缘协作
  18. matlab多元回归模型分析,matlab多元回归工具箱 Excel数据分析工具进行多元回归分析.doc...
  19. 电子计算机音乐 faded,Faded - Alan Walker 73.6M [FLAC格式]
  20. 我的编程奋斗历程[四部曲之二]-毕业初期篇

热门文章

  1. 产品摆个龙门阵——用户运营基础方法论
  2. Bash编程016——用户与组(二)
  3. 以前接触的两个App中总结的知识
  4. Ubuntu下vim设置tab键为4个空格
  5. 025-2018-1011 re模块
  6. Python 热门开源项目Top10
  7. 计算机网络基础【1】
  8. Linux永久修改主机名
  9. DEJA_VU3D - Cesium功能集 之 090-台风过境实时动画
  10. private方法可以被代理吗?