特点
1. 能够周期性给CPU发送中断信号
2. 周期或频率可以通过软件编程进行设置
硬件定时器在Linux 内核中的更新中断处理函数
具体干啥了呢?
1. 最关键的是维护了一个全局变量的值 jiffies / jiffies_64
2. 更新墙上时间
3. 检查进程是键盘是否用完,决定是否实施调度
4. 检查是否有超时的软件定时器,如果有,将执行对应的软件超时中断处理函数
5. 统计系统的资源信息等
jiffies_64 & HZ
Linux 内核采用一个全局变量 jiffies_64 记录硬件计时器的中断次数。
类型 jiffies_64,unsigned long long。
HZ: 表示CPU一秒钟响应多少次中断。不同平台可能不大一样。
具体的写一个demo,试验一下
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
MODULE_DESCRIPTION("Frocheng: Driver for DEMO!");
MODULE_AUTHOR("Frodo Cheng");
MODULE_LICENSE("GPL");
MODULE_VERSION("V0.0.1");
#define HELLO_TIMEOUT_SEC (1ULL * HZ)
static unsigned long long timeout;
static int __init hello_init(void)
{
timeout = get_jiffies_64() + 10 * HELLO_TIMEOUT_SEC;
printk("===[frocheng]===[%s]===[%s]===[%d]===[Hello !]===\n",__FILE__, __func__, __LINE__);
return 0;
}
static void __exit hello_exit(void)
{
// timeout >= get_jiffies_64()
// time_is_after_jiffies64(timeout)
if (time_after64(timeout, get_jiffies_64()))
{
printk("===[frocheng]=== In Time ===\n");
}
else
{
printk("===[frocheng]=== Time Out ===\n");
}
printk("===[frocheng]===[%s]===[%s]===[%d]===[Bye bye...]===\n",__FILE__, __func__, __LINE__);
}
module_init(hello_init);
module_exit(hello_exit);
注意获取以及比较的方式:
第一, 最好不要直接是用 jiffies_64 变量,而是采用 get_jiffies_64() 函数。
第二, 比较方式 time_after64() 或者 time_is_after/befor_jiffies64()