Android深度探索:HAL与驱动开发学习笔记--时间管理
2017-09-29 09:11
561 查看
这里跟我们经常用到就是jiffies,时钟节拍。
jiffies是记录着从电脑开机到现在总共的时钟中断次数。在linux内核中jiffies取决于系统的频率,单位是Hz,这里不得不说一下频率的单位,1MHz=1000,000Hz(6个零),1KHz=1000Hz(3个零)频率是周期的倒数,一般是一秒钟中断产生的次数,所以,假如我们需要知道系统的精确的时间单位时,需要换算了,假如我们系统的频率是200Mhz,那么一次中断的间隔是1秒/200,000,000Hz=0.000 000
005秒看一下上面我们的时间单位,对照一下小数点后面是9个零,所以理论上我们系统的精确度是5纳秒。LINUX系统时钟频率是一个常数HZ来决定的,通常HZ=100,那么他的精度度就是10ms(毫秒)。也就是说每10ms一次中断。所以一般来说Linux的精确度是10毫秒。
在Linux 2.6 中,系统时钟每 1 毫秒中断一次(时钟频率,用 HZ 宏表示,定义为 1000,即每秒中断1000 次,2.4中定义为 100,很多应用程序也仍然沿用 100 的时钟频率),这个时间单位称为一个jiffie
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
工作队列通过定时器超时函数自动调度工作
jiffies是记录着从电脑开机到现在总共的时钟中断次数。在linux内核中jiffies取决于系统的频率,单位是Hz,这里不得不说一下频率的单位,1MHz=1000,000Hz(6个零),1KHz=1000Hz(3个零)频率是周期的倒数,一般是一秒钟中断产生的次数,所以,假如我们需要知道系统的精确的时间单位时,需要换算了,假如我们系统的频率是200Mhz,那么一次中断的间隔是1秒/200,000,000Hz=0.000 000
005秒看一下上面我们的时间单位,对照一下小数点后面是9个零,所以理论上我们系统的精确度是5纳秒。LINUX系统时钟频率是一个常数HZ来决定的,通常HZ=100,那么他的精度度就是10ms(毫秒)。也就是说每10ms一次中断。所以一般来说Linux的精确度是10毫秒。
在Linux 2.6 中,系统时钟每 1 毫秒中断一次(时钟频率,用 HZ 宏表示,定义为 1000,即每秒中断1000 次,2.4中定义为 100,很多应用程序也仍然沿用 100 的时钟频率),这个时间单位称为一个jiffie
内核定时器
1.涉及函数
// 1. 初始化定时器队列结构 init_timer(&buttons_timer); // 2. 定时器超时函数 buttons_timer.function = buttons_timer_function; // 3.或者初始化定时器和超时函数作为一步(data作为fn的参数) setup_timer(timer, fn, data) // 4. 添加定时器 add_timer(&buttons_timer); // 5. 设置定时器超时时间 1\100 s(修改一次超时时间只会触发一次定时器) mod_timer(&buttons_timer, jiffies+HZ/100); // 6.删除定时器 del_timer(&timer);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2.demo
工作队列通过定时器超时函数自动调度工作#include linux/init.h> #include linux/module.h> #include linux/moduleparam.h> #include linux/time.h> #include linux/timer.h> #include linux/workqueue.h> #include asm/atomic.h> MODULE_AUTHOR("lcw"); MODULE_LICENSE("GPL"); struct timer_data { struct timer_list timer; struct workqueue_struct *work_queue; unsigned long prev_jiffies; unsigned int loops; }; static struct timer_list timer1; static struct timer_list timer2; static void do_work(void *); static DECLARE_WORK(test_work, do_work, NULL); static DECLARE_WORK(test_work1, do_work, NULL); static struct workqueue_struct *test_workqueue; atomic_t wq_run_times; unsigned int failed_cnt = 0; // 定时器1超时函数 void test_timer_fn1(unsigned long arg) { struct timer_data *data = (struct timer_data *)arg; mod_timer(&timer1, jiffies+HZ/100); // 设置超时时间 1\100s if (queue_work(test_workqueue, &test_work)== 0) { printk("Timer (0) add work queue failed\n"); (*(&failed_cnt))++; } data->loops++; printk("timer-0 loops: %u\n", data->loops); } // 定时器2超时函数 void test_timer_fn2(unsigned long arg) { struct timer_data *data = (struct timer_data *)arg; mod_timer(&timer2, jiffies+HZ/100); // 设置超时时间 1\100s //if (queue_work(test_workqueue, &test_work)== 0) { if (queue_work(test_workqueue, &test_work1)== 0) { printk("Timer (1) add work queue failed\n"); (*(&failed_cnt))++; } data->loops++; printk("timer-1 loops: %u\n", data->loops); } // work func void do_work(void*arg) { //原子计数值加一 atomic_inc(&wq_run_times); printk("====work queue run times: %u====\n", atomic_read(&wq_run_times)); printk("====failed count: %u====\n",*(&failed_cnt)); } // init int wq_init(void) { //原子计数值初始化 atomic_set(&wq_run_times, 0); // work queue test_workqueue = create_singlethread_workqueue("test-wq"); // timer1 init_timer(&timer1); timer1.function= test_timer_fn1; add_timer(&timer1); // timer2 init_timer(&timer2); timer2.function= test_timer_fn1; add_timer(&timer2); //设置超时时间,启动定时器 mod_timer(&timer1, jiffies+HZ/100); // 设置超时时间 1\100s mod_timer(&timer2, jiffies+HZ/100); // 设置超时时间 1\100s return 0; } void wq_exit(void) { del_timer(&test_data.timer); del_timer(&test_data1.timer); destroy_workqueue(test_workqueue); printk("wq exit success\n"); } module_init(wq_init); module_exit(wq_exit)
相关文章推荐
- Android深度探索:HAL与驱动开发学习笔记--并发控制之自旋锁
- Android深度探索:HAL与驱动开发学习笔记--并发控制之互斥锁
- Android深度探索:HAL与驱动开发学习笔记--并发控制之信号量&完成量
- Android深度探索:HAL与驱动开发学习笔记--内存管理(学习重点)
- Android深度探索:HAL与驱动开发学习笔记--工作队列
- Android深度探索:HAL与驱动开发学习笔记--中断
- Android深度探索:HAL与驱动开发学习笔记--等待队列
- Android深度探索:HAL与驱动开发学习笔记--并发控制之顺序锁
- Android深度探索:HAL与驱动开发学习笔记--并发控制总结
- Android深度探索 卷1 HAL与驱动开发 读书笔记1
- Android深度探索(卷1)HAL与驱动开发 虚拟环境的安装
- Android开发艺术探索学习笔记6——线程和线程池
- Android开发艺术探索——学习笔记_View事件体系
- Android开发艺术探索学习笔记
- android深度搜索学习笔记三( 蜂鸣器驱动)
- 《Android 开发艺术探索》——View 事件体系--View基础知识 (学习笔记)
- 【读书笔记】深度探索 HAL与驱动开发
- android开发艺术探索 学习笔记(二) Activity的启动模式
- android深度搜索学习笔记四(硬件抽像hal第一部分)
- android开发艺术探索 学习笔记(一) Activity生命周期全面分析