Android深度探索:HAL与驱动开发学习笔记--时间管理

来源:互联网 发布:linux vi如何保存退出 编辑:程序博客网 时间:2024/06/05 00:41

这里跟我们经常用到就是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

内核定时器

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 funcvoid 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));}// initint 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)

阅读全文
0 0
原创粉丝点击