Linux设备驱动程序 之 内核定时器
综述
如果需要在将来的某个时间点调度执行某个动作,同时在该时间点到达之前不会阻塞当前进程,则可以使用内核定时器;
内核定时器是一个数据结构,它告诉内核在用户定义的时间点使用用户定义的参数来执行一个用户定义的函数;
被调度运行的函数几乎肯定不会再注册这些函数的进程正在执行时运行,相反,这些函数会异步的运行;当定时器运行时,调度该定时器的进程可能正在休眠或在其他处理器上执行,或已经退出;
内核定时器常常是作为“软中断”的结果而运行的;在这种原子性上下文中运行时,代码会受到很多限制;
许多动作需要在进程上下文中才能执行,如果处于进程上下文之外,则必须遵守以下规则:
1. 不允许访问用户空间;因为没有进程上下文,无法将任何特定进程与用户空间关联起来;
2. current指针在原子模式下是没有任何意义的;也是不可用的,因为相关代码和被中断的进程没有任何关联;
3. 不能执行休眠或者调度;原子代码不可以调用shcedule或者wait_event,也不能调用任何可能引起休眠的函数;例如,调用kmalloc(…,GFP_KERNEL)就不符合本规则;信号量也不能用,因为可能引起休眠;
内核可以通过调用函数in_interrupt()来判断自己是否正运行于中断上下文,该函数无需参数,如果处理器运行在中断上下文,则返回非0值,无论是硬件中断还是软件中断;
和in_interrupt()相关的函数是in_atomic(),当函数返回非0值时,调度不被允,即处于原子上下文,包括硬件和软件中断上下文以及拥有自旋锁的任何时间点,在后一种情况下,current可能是可用的,但是禁止访问用户空间,因为会导致调度的发生;在使用in_interrupt()的时间点,都应该考虑是否真正的该使用的是in_atomic();
内核定时器的另一个重要特征是,任务可以将自己注册以后再稍后的时间重新运行,这种可能性是因为timer_list结构会在运行之前从活动定时器链表中移走,这样就可以立即链入其他链表;
在SMP系统中,定时器函数会由注册它的同一CPU执行,这样可以尽可能的获得缓存的局域性;因此,一个注册自己的定时器始终会在同一CPU上运行;
即使在单处理器系统上,定时器也会是竞态的潜在来源;这是由其异步执行的特点直接导致的;因此,任何通过定时器函数访问的数据结构都应该针对并发访问进行保护;
定时器API
内核为驱动程序提供了一组用来声明、注册和删除定时器的函数,下面为部分摘取:
struct timer_list {
/*
* All fields that change during normal runtime grouped to the
* same cacheline
*/
struct hlist_node entry;
unsigned long expires; /* 超时时间 */
void (*function)(unsigned long); /* 超时回调 */
unsigned long data; /* 回调参数 */
u32 flags; /* 标志 */
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
};
/* 静态定义初始化 */
#define DEFINE_TIMER(_name, _function, _expires, _data) /* 只初始化,初始化之后再设置结构的回调,超时等 */
#define init_timer(timer) /* 初始化,设置回调,未设置超时 */
#define setup_timer(timer, fn, data) /* 添加定时器,开始工作 */
void add_timer(struct timer_list *timer) /* 未超时之前,可修改定时器的超时时间 */
int mod_timer(struct timer_list *timer, unsigned long expires) /* 删除定时器 */
int del_timer(struct timer_list * timer)
Linux设备驱动程序 之 内核定时器的更多相关文章
- Linux设备驱动程序 之 内核符号表
insmod使用公共内核符号表来解析模块中未定义的符号.功能内核符号表中包含了所有全局内核项(函数和变量)的地址,这是实现模块化驱动程序所必须的.当模块装载到内核后,它所导出的任何符号都会变成内核符号 ...
- 嵌入式Linux设备驱动程序:编写内核设备驱动程序
嵌入式Linux设备驱动程序:编写内核设备驱动程序 Embedded Linux device drivers: Writing a kernel device driver 编写内核设备驱动程序 最 ...
- linux设备驱动程序该添加哪些头文件以及驱动常用头文件介绍(转)
原文链接:http://blog.chinaunix.net/uid-22609852-id-3506475.html 驱动常用头文件介绍 #include <linux/***.h> 是 ...
- Linux设备驱动程序学习----2.内核模块与应用程序的对比
内核模块与应用程序的对比 更多内容请参考Linux设备驱动程序学习----目录 1. 内核模块与应用程序的对比 内核模块和应用程序之间的不同之处: 大多数中小规模的应用程序是从头到尾执行单个任务,而模 ...
- 嵌入式Linux设备驱动程序:用户空间中的设备驱动程序
嵌入式Linux设备驱动程序:用户空间中的设备驱动程序 Embedded Linux device drivers: Device drivers in user space Interfacing ...
- 【转】linux设备驱动程序中的阻塞机制
原文网址:http://www.cnblogs.com/geneil/archive/2011/12/04/2275272.html 阻塞与非阻塞是设备访问的两种方式.在写阻塞与非阻塞的驱动程序时,经 ...
- 如何编写Linux设备驱动程序
一.Linux device driver 的概念 系统调用是操作系统内核和应用程序之间的接口,设备驱动程序是操作系统内核和机器硬件之间的接口.设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看 ...
- Linux设备驱动程序 第三版 读书笔记(一)
Linux设备驱动程序 第三版 读书笔记(一) Bob Zhang 2017.08.25 编写基本的Hello World模块 #include <linux/init.h> #inclu ...
- Linux设备驱动程序学习之分配内存
内核为设备驱动提供了一个统一的内存管理接口,所以模块无需涉及分段和分页等问题. 我已经在第一个scull模块中使用了 kmalloc 和 kfree 来分配和释放内存空间. kmalloc 函数内幕 ...
随机推荐
- spring将service添加事务管理,在applicationContext.xml文件中的设置
在applicationContext.xml文件中的设置为: <beans> <bean id="sessionFactory" class="org ...
- 2.Storm集群部署及单词统计案例
1.集群部署的基本流程 2.集群部署的基础环境准备 3.Storm集群部署 4.Storm集群的进程及日志熟悉 5.Storm集群的常用操作命令 6.Storm源码下载及目录熟悉 7.Storm 单词 ...
- iptables详解说明
Iptabels是与Linux内核集成的包过滤防火墙系统,几乎所有的linux发行版本都会包含Iptables的功能.如果 Linux 系统连接到因特网或 LAN.服务器或连接 LAN 和因特网的代理 ...
- Python——DataFrame转list(包含两种)
import pandas as pd df = pd.DataFrame({'a':[1,3,5,7,4,5,6,4,7,8,9], 'b':[3,5,6,2,4,6,7,8,7,8,9]}) df ...
- spring实例化一:InstantiationStrategy
DefaultListableBeanFactory对bean的管理工厂,包括bean的生成,从class到bean的实例化.spring特为这个实例化过程,定义了接口Instantiat ...
- JavaScript001,鼠标点击改变文字或图片
<h3>我的第一个Javascript</h3> <p id="demo1">1.点击按钮,改变内容!</p> <!-- 设置 ...
- 从项目开始的Java开发学习
积累了一些项目中见到的代码,希望见一次之后自己也能写出来. 一.通过cxf JaxWsDynamicClientFactory进行WebService 客户端调用 代码:在项目中从非项目内的接口获取数 ...
- K3CLOUD 常用数据表
二.K3 Cloud 开发插件<K3 Cloud 常用数据表整理>一.数据库查询常用表 按 Ctrl+C 复制代码 按 Ctrl+C 复制代码 通过表T_META_OBJECTTYPE的F ...
- win10笔记本连接wifi出现:您的计算机配置似乎是正确的,但该配置或资源(DNS服务器)检测到有响应
问题上图: 一直以来连接网线使用,很少使用WiFi了,在网线不好使的时候使用wifi发现并不怎么好用,甚至上不了网页,但是那时候也不怎么在意,不过一会网线就好使了所以也没处理,直到今天,因为接下来好多 ...
- Java8-Lock-No.01
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util ...