Linux驱动中断与时间篇——高精度定时器hrtimer

简介: Linux驱动中断与时间篇——高精度定时器hrtimer

前言

低分辨率定时器是用jiffies来定时的,所以会受到HZ影响,如果HZ200,代表每秒种产生200次中断,那一个jiffies就需要5毫秒,所以精度为5毫秒。

如果精度需要达到纳秒级别,则需要使用高精度定时器hrtimer

相关接口

高分辨率定时器(hrtimer)以ktime_t来定义时间,精度可以达到纳秒级别ktime_t定义如下:

typedef s64 ktime_t;

可以用ktime_set来初始化一个ktime对象,常用方法如下:

ktime_t t = ktime_set(secs, nsecs);

高分辨率hrtimer结构体定义如下:

struct hrtimer {  
    struct timerqueue_node      node;  
    ktime_t             _softexpires;  
    enum hrtimer_restart        (*function)(struct hrtimer *);  
    struct hrtimer_clock_base   *base;  
    unsigned long           state;  
        ......  
};  
enum hrtimer_restart {  
    HRTIMER_NORESTART,  /* Timer is not restarted */  
    HRTIMER_RESTART,    /* Timer must be restarted */  
};

struct hrtimer结构体中最主要的成员就是回调函数function,回调函数的返回值可以为HRTIMER_NORESTARTHRTIMER_RESTARTHRTIMER_NORESTART代表不需要重启定时器,HRTIMER_RESTART代表需要重启定时器。

最常用的接口如下:

hrtimer_init(struct hrtimer *timer, clockid_t clock_id , enum hrtimer_mode mode)
hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
hrtimer_forward_now(struct hrtimer *timer,ktime_t interval)
hrtimer_cancel(struct hrtimer *timer)

hrtimer_init:初始化 struct hrtimer 结构对象。 clockid_t 是时钟的类型, 种类很多,常见的有四种:

  • CLOCK_REALTIME:系统实时时间。
  • CLOCK_MONOTONIC:从系统启动时开始计时,自系统开机以来的单调递增时间
  • CLOCK_PROCESS_CPUTIME_ID:本进程到当前代码系统CPU花费的时间,包含该进程下的所有线程。
  • CLOCK_THREAD_CPUTIME_ID:本线程到当前代码系统CPU花费的时间。

mode 是时间的模式,可以是 HRTIMER_MODE_ABS, 表示绝对时间, 也可以是 HRTIMER_MODE_REL, 表 示相对时间。hrtimer_start:启动定时器。 tim 是设定的到期时间, modehrtimer_init中的 mode参数含义相同。hrtimer_forward_now: 修改到期时间为从现在开始之后的 interval 时间。hrtimer_cancel:取消定时器。

使用示例

单次定时

加载驱动一秒后输出“hrtimer handler”:

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ktime.h>
#include <linux/hrtimer.h>
static struct hrtimer timer;
static enum hrtimer_restart timer_handler(struct hrtimer *timer )
{
 printk("hrtimer handler\n");
    return HRTIMER_NORESTART;
}
static int __init my_init(void) 
{
    ktime_t tim;
    hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    timer.function = timer_handler;
    tim = ktime_set(1,0); //1s
    hrtimer_start(&timer,tim,HRTIMER_MODE_REL);
    return 0;
}
static void __exit my_exit(void)
{
 printk("%s enter\n", __func__);
 hrtimer_cancel(&timer);
}
module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL");

循环定时

循环定时可以在回调函数中调用hrtimer_forward_now()重新设置定时时间,然后将返回值设置为HRTIMER_RESTART代表重启定时器,就可以做到循环定时的效果。

每隔一秒输出“hrtimer handler”:

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ktime.h>
#include <linux/hrtimer.h>
static struct hrtimer timer;
static enum hrtimer_restart timer_handler(struct hrtimer *timer )
{
    printk("hrtimer handler\n");
    hrtimer_forward_now(timer, ktime_set(1,0));//重新设置定时时间
    return HRTIMER_RESTART;//重启定时器
}
static int __init my_init(void) 
{
    ktime_t tim;
    hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    timer.function = timer_handler;
    tim = ktime_set(1,0); //1 s
    hrtimer_start(&timer,tim,HRTIMER_MODE_REL);
    return 0;
}
static void __exit my_exit(void)
{
    printk("%s enter\n", __func__);
    hrtimer_cancel(&timer);
}
module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL");

end

往期推荐

入职Linux驱动工程师后,我才知道的真相......

机遇:我是如何走向Linux驱动的...

当我用几道题考了一遍做Linux驱动的同事......

“不是所有的驱动岗,都值得你去”

Linux驱动面试高频考点

相关文章
|
1月前
|
Linux API 调度
Linux系统驱动跟裸机驱动的区别
Linux系统驱动跟裸机驱动的区别
29 0
|
1月前
|
Linux C语言 SoC
嵌入式linux总线设备驱动模型分析
嵌入式linux总线设备驱动模型分析
32 1
|
1月前
|
存储 缓存 Linux
【Shell 命令集合 磁盘维护 】Linux 设置和查看硬盘驱动器参数 hdparm命令使用教程
【Shell 命令集合 磁盘维护 】Linux 设置和查看硬盘驱动器参数 hdparm命令使用教程
36 0
|
12天前
|
Linux Go
Linux命令Top 100驱动人生! 面试必备
探索Linux命令不再迷茫!本文分10部分详解20个基础命令,带你由浅入深掌握文件、目录管理和文本处理。 [1]: <https://cloud.tencent.com/developer/article/2396114> [2]: <https://pan.quark.cn/s/865a0bbd5720> [3]: <https://yv4kfv1n3j.feishu.cn/docx/MRyxdaqz8ow5RjxyL1ucrvOYnnH>
64 0
|
25天前
|
Linux
Linux驱动运行灯 Heartbeat
Linux驱动运行灯 Heartbeat
12 0
|
1月前
|
监控 Linux 编译器
Linux C++ 定时器任务接口深度解析: 从理论到实践
Linux C++ 定时器任务接口深度解析: 从理论到实践
70 2
|
1月前
|
Linux
Linux内核中USB设备驱动实现
Linux内核中USB设备驱动实现
25 0
|
6天前
|
机器学习/深度学习 缓存 监控
linux查看CPU、内存、网络、磁盘IO命令
`Linux`系统中,使用`top`命令查看CPU状态,要查看CPU详细信息,可利用`cat /proc/cpuinfo`相关命令。`free`命令用于查看内存使用情况。网络相关命令包括`ifconfig`(查看网卡状态)、`ifdown/ifup`(禁用/启用网卡)、`netstat`(列出网络连接,如`-tuln`组合)以及`nslookup`、`ping`、`telnet`、`traceroute`等。磁盘IO方面,`iostat`(如`-k -p ALL`)显示磁盘IO统计,`iotop`(如`-o -d 1`)则用于查看磁盘IO瓶颈。
|
3天前
|
监控 Linux Windows
50个必知的Linux命令技巧,你都掌握了吗?(下)
50个必知的Linux命令技巧,你都掌握了吗?(下)