驱动-Linux定时-timer_list

了解内核定时相关基础知识

文章目录

  • 简要介绍
  • timer_list 特点
  • API 函数
  • 实验
    • 测试程序 - timer_mod.c
    • 编译文件-Makefile
    • 实验验证
  • 注意事项
  • 总结


简要介绍

硬件为内核提供了一个系统定时器来计算流逝的时间(即基于未来时间点的计时方式, 以当前时刻为计时开始的起点, 以未来的某一时刻为计时的终点) , 内核只有在系统定时器的帮助下才能计算和管理时间, 但是内核定时器的精度并不高, 所以不能作为高精度定时器使用。并且内核定时器的运行没有周期性, 到达计时终点后会自动关闭。 如果要实现周期性定时, 就要在定时处理函数中重新开启定时器。

Linux 内核中使用 timer_list 结构体表示内核定时器, 该结构体定义在“内核源码/include/li
nux/timer.h”文件中, 具体内容如下所示


struct timer_list {struct hlist_node   entry;unsigned long       expires;/* 定时器超时时间,单位是节拍数 */void            (*function)(struct timer_list *);/* 定时处理函数 */u32         flags;#ifdef CONFIG_LOCKDEPstruct lockdep_map  lockdep_map;
#endifANDROID_KABI_RESERVE(1);ANDROID_KABI_RESERVE(2);
};

timer_list 特点

inux 内核定时器是基于 timer_list 结构的动态定时器,具有以下特点:

  • 不是周期性的,超时后会自动失效

  • 基于内核的 jiffies 计时

  • 在中断上下文执行,因此不能睡眠

  • 精度取决于 HZ 值(通常为 1ms 或 10ms)

API 函数

函数作用
void add_timer(struct timer_list *timer)向 Linux 内核注册定时器,使用 add_timer 函数向内核注册定时器以后,定时器就会开始运行
int del_timer(struct timer_list * timer)删除一个定时器
int mod_timer(struct timer_list *timer,unsigned long expires)修改定时值,如果定时器还没有激活的话,mod_timer 函数会激活定时器

在使用add_timer()函数向 Linux 内核注册定时器之前,还需要设置定时时间,定时时间由timer_list结构体中的expires参数所确定,单位为节拍数

这里简要理解,节拍数 jiffies 和 时间之间的转换函数:

jiffies_64用于64位系统,而jiffies用于 32 位系统。为了方便开发,Linux 内核还提供了几个jiffies和ms、us、ns之间的转换函数,如下 所示:

函数作用
int jiffies_to_msecs(const unsigned long j)将 jiffies 类型的参数 j 分别转换为对应的毫秒
int jiffies_to_usecs(const unsigned long j)将 jiffies 类型的参数 j 分别转换为对应的微秒
u64 jiffies_to_nsecs(const unsigned long j)将 jiffies 类型的参数 j 分别转换为对应的纳秒
long msecs_to_jiffies(const unsigned int m)将毫秒转换为 jiffies 类型
long usecs_to_jiffies(const unsigned int u)将微秒转换为 jiffies 类型
unsigned long nsecs_to_jiffies(u64 n)将纳秒转换为 jiffies 类型

既然要定时,那么情形就是 把定时时间转换成节拍数,系统内核根据节拍数和节拍频率。内核里面只认节拍数,它对应的就是频率

例如:进行3秒钟的定时:

timer_test.expires = jiffies_64 +msecs_to_jiffies(3000)

实验

测试程序 - timer_mod.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/timer.h>static void function_test(struct timer_list  *t);//定义function_test定时功能的函数
DEFINE_TIMER(timer_test,function_test);static void function_test(struct timer_list *t){printk(" this is function test \n");mod_timer(&timer_test,jiffies_64+msecs_to_jiffies(5000));  使用mod_timer函数将定时时间设置为五秒后}static int __init time_module_init(void) //驱动入口函数
{timer_test.expires = jiffies_64 + msecs_to_jiffies(5000);//将定时时间设置为五秒后add_timer(&timer_test);//添加一个定时器return 0;}
static void __exit time_module_exit(void) //驱动出口函数
{del_timer(&timer_test);//删除一个定时器printk("module exit \n");}
module_init(time_module_init);
module_exit(time_module_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("wang fang chen");

源码分析

  • 这里用到了定时器timer_list 的三个api 函数:
    定义定时器:DEFINE_TIMER(timer_test,function_test); 参数为定时器名称和回调方法
    添加定时器:add_timer(&timer_test);
    修改定时器:mod_timer(&timer_test,jiffies_64+msecs_to_jiffies(5000));
    删除定时器:del_timer(&timer_test);

    **注意点:**定时器的名称并不是作为变量定义的,作为方法参数定义了的 DEFINE_TIMER的方法参数。
    回调函数 function_test 是先定义,然后实现 。

编译文件-Makefile

#!/bin/bash
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
obj-m += timer_mod.o
KDIR :=/home/wfc123/Linux/rk356x_linux/kernel
PWD ?= $(shell pwd)
all:make -C $(KDIR) M=$(PWD) modulesclean:make -C $(KDIR) M=$(PWD) clean

实验验证

加载驱动看打印信息
在这里插入图片描述

注意事项

  • 定时器精度:内核定时器的精度受 HZ 值影响,不适合需要高精度的场合

  • 执行上下文:回调函数在中断上下文执行,不能调用可能睡眠的函数

  • 多核处理:del_timer() 可能在 SMP 系统上返回后定时器仍在运行,使用 del_timer_sync() 更安全

  • 竞争条件:确保在模块退出时删除所有定时器

总结

这里了解的是内核的一个定时器timer_list 的使用。 了解基本知识即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/81710.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络概要

⽹络相关基础知识 协议 两设备之间使⽤光电信号传输信息数据 要想传递不同信息 那么⼆者ᳵ就需要约定好的数据格式 层 封装 继承 多态是计算机的性质 它们⽀持了软硬件分层的实现 同层协议可以ᳵ接通信 同层协议ᳵ不直接通信 是各⾃调⽤下层提供的结构能⼒完成通信 分层…

QT 使用QPdfWriter和QPainter绘制PDF文件

QT如何生产pdf文件&#xff0c;网上有许多文章介绍&#xff0c;我也是看了网上的文章&#xff0c;看他们的代码&#xff0c;自己琢磨琢磨&#xff0c;才有了本编博客&#xff1b; 其他什么就不详细说了&#xff0c;本篇博客介绍的QPdfWriter和QPainter绘制PDF文件&#xff1b;…

企业标准信息公共服务平台已开放标准通编辑器访问入口

标准通 数字化标准编辑器 专业、高效、便捷 企业标准信息公共服务平台 近日&#xff0c;企业标准信息公共服务平台已开放标准通编辑器访问入口&#xff0c;可进入官网指定版块使用&#xff01; 核心功能亮点 解决企业痛点 传统标准编制&#xff0c;需反复核对格式、逐条…

【Hadoop】--HA高可用搭建--3.2.2

修改环境配置文件 hadoop-env.sh # 在文件末尾添加以下内容&#xff1a; # java_home记得修改 export JAVA_HOME/usr/java/jdk1.8.0xxxx export HDFS_NAMENODE_USERroot export HDFS_DATANODE_USERroot export HDFS_ZKFC_USERroot export HDFS_JOURNALNODE_USERroot export YA…

【skywalking】index“:“skywalking_metrics-all“},“status“:404}

skywalking 启动报错 java.lang.RuntimeException: {"error":{"root_cause":[{"type":"index_not_found_exception","reason":"no such index [skywalking_metrics-all]","resource.t ype":"inde…

【Android】从垂直同步到屏幕刷新机制(一)

【Android】从垂直同步到屏幕刷新机制 本文参考以及部分图片来源&#xff1a; 垂直同步_小科普&#xff1a;“垂直同步”究竟是什么&#xff1f;-CSDN博客 “终于懂了” 系列&#xff1a;Android屏幕刷新机制—VSync、Choreographer 全面理解&#xff01;-腾讯云开发者社区-腾讯…

ACL完全解析:从权限管理到网络安全的核心防线

访问控制列表&#xff08;ACL&#xff09;是一种用于管理资源访问权限的核心安全机制&#xff0c;广泛应用于操作系统和网络设备中。以下是对ACL的详细解析&#xff1a; 1. 基本概念 定义&#xff1a;ACL是由多个访问控制条目&#xff08;ACE&#xff09;组成的列表&#xff0…

代码审计-php框架开发,实战tp项目,打击微交易,源码获取,扩大战果

实战&#xff0c;不安全写法引发的注入 这个bc靶场源码没有&#xff0c;看老师演示 打开很明显的tp框架源码 拿到tp框架之后第一步&#xff0c;搜索版本信息5.0.5 两个思路 1.代码的不安全写法 2.版本自身存在的漏洞 全局搜索where看看也没有不安全的 哎&#xff1f;&…

大模型的实践应用43-基于Qwen3(32B)+LangChain框架+MCP+RAG+传统算法的旅游行程规划系统

大家好,我是微学AI,今天给大家介绍一下大模型的实践应用43-基于Qwen3(32B)+LangChain框架+MCP+RAG+传统算法的旅游行程规划系统。本报告将阐述基于大模型Qwen3(32B)、LangChain框架、MCP协议、RAG技术以及传统算法构建的智能旅游行程规划系统。该系统通过整合多种技术优势,实…

Jsoup库和Apache HttpClient库有什么区别?

Jsoup 和 Apache HttpClient 是两个功能不同的库&#xff0c;它们在 Java 开发中被广泛使用&#xff0c;但用途和功能有明显的区别&#xff1a; Jsoup 用途&#xff1a;Jsoup 是一个用于解析 HTML 文档的库。它提供了非常方便的方法来抓取和解析网页内容&#xff0c;提取和操作…

腾讯云存储原理

我们来详细展开你提到的两个核心结构概念&#xff1a; 一、“基于分布式文件系统 对象存储技术” 是什么&#xff1f; 1. 分布式文件系统&#xff08;DFS&#xff09;基础 分布式文件系统是一种支持将数据分布在多个存储节点上、并对上层用户透明的文件系统。腾讯云COS虽然是…

python fastapi + react, 写一个图片 app

1. 起因&#xff0c; 目的: 上厕所的时候&#xff0c;想用手机查看电脑上的图片&#xff0c;但是又不想点击下载。此app 应运而生。 2. 先看效果 单击图片&#xff0c;能放大图片 3. 过程: 过程很枯燥。有时候&#xff0c; 有一堆新的想法。 但是做起来太麻烦&#xff0c;…

Kubernetes控制平面组件:Kubelet详解(五):切换docker运行时为containerd

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…

QT6 源(111):阅读与注释菜单栏 QMenuBar,进行属性与成员函数测试,信号与槽函数测试,并给出源码

&#xff08;1&#xff09; &#xff08;2&#xff09; &#xff08;3&#xff09; &#xff08;4&#xff09; &#xff08;5&#xff09; &#xff08;6&#xff09; &#xff08;7&#xff09;以下源代码来自于头文件 qmenubar . h &#xff1a; #ifndef QMENUBAR_H #defi…

Leetcode 3552. Grid Teleportation Traversal

Leetcode 3552. Grid Teleportation Traversal 1. 解题思路2. 代码实现 题目链接&#xff1a;3552. Grid Teleportation Traversal 1. 解题思路 这一题的话核心就是一个广度优先遍历&#xff0c;我们只需要从原点开始&#xff0c;一点点考察其所能到达的位置&#xff0c;直至…

2023CCPC河南省赛暨河南邀请赛个人补题ABEFGHK

Dashboard - 2023 CCPC Henan Provincial Collegiate Programming Contest - Codeforces 过题难度&#xff1a;A H F G B K E 铜奖&#xff1a; 2 339 银奖&#xff1a; 3 318 金奖&#xff1a; 5 523 A: 直接模拟 // Code Start Here int t;cin >> t;while(t-…

如何用Python批量解压ZIP文件?快速解决方案

如何用Python批量解压ZIP文件&#xff1f;快速解决方案 文章目录 **如何用Python批量解压ZIP文件&#xff1f;快速解决方案**代码结果详细解释 话不多说&#xff0c;先上干货&#xff01;&#xff01;&#xff01; 代码 import os import zipfiledef unzip_file(dir_path: str…

Spring Boot 的高级特性与经典的设计模式应用

目录 1. 设计模式在 Spring Boot 中的应用 1.1 单例模式&#xff1a;Bean 管理与全局实例 1.1.1 Spring 中的单例 Bean 1.1.2 自定义单例实现 1.1.3 单例模式的优势 1.2 工厂模式&#xff1a;动态创建 Bean 1.2.1 Spring 的工厂方法 1.2.2 自定义工厂类 1.2.3 工厂模式…

在Excel中使用函数公式时,常见错误对应不同的典型问题

在Excel中使用函数公式时&#xff0c;常见错误对应不同的典型问题 1. #DIV/0!&#xff08;除以零错误&#xff09;2. #N/A&#xff08;值不可用&#xff09;3. #NAME?&#xff08;名称错误&#xff09;4. #NULL!&#xff08;空交集错误&#xff09;5. #NUM!&#xff08;数值错…

【cursor疑惑】cursor续杯后使用agent对话时,提示“需要pro或商业订阅的用户才能使用“

背景 cursor的pro会员体验过期了&#xff0c;想再次体验deepseek、Claude等agent对话提示:“免费版本不可以使用agent对话功能(英文忘记截图了&#xff0c;大意是这样)”。 处理方法 Step-1&#xff1a;再次续杯cursor的pro会员14天体验 详情&#xff0c;见&#xff1a;【c…