zoukankan      html  css  js  c++  java
  • 内核定时器timer_list

    内核在时钟中断发生后执行检测各个定时器是否到期,到期后的定时器处理函数将作为软中断在底半部执行。实质上,时钟中断处理程序会唤起TIMER_SOFTIRQ软中断,运行当前处理器上到期的所有定时器。linux提供的内核定时器数据结构为timer_list。

    一. 定义

    timer_list定义在linux/timer.h中,实现在kernel/timer.c中。

    struct timer_list {
        struct list head_entry;
        unsigned long expires;    //到期时间
        struct tves_base *base;
    
        void (*func)(unsigned long);
        unsigned long data;
    
        int slack;
    
    #ifdef CONFIG_TIMER_STATS
        int start_pid;
        void *start_site;
        char start_comm[16];
    #endif
    
    #ifdef CONFIG_LOCKDEP
        struct lockdep_map lockdep_map;
    #endif
    
    };

    内核相关定义:HZ和jiffies

    HZ  时钟频率
    jiffies 32位无符号数,当前时钟计数

    # define HZ     CONFIG_HZ   /* Internal kernel timer frequency */
    # define USER_HZ    100     /* some user interfaces are */
    linux/jiffies.h
    /*
     * The 64-bit value is not atomic - you MUST NOT read it
     * without sampling the sequence number in jiffies_lock.
     * get_jiffies_64() will do this for you as appropriate.
     */
    extern u64 __jiffy_data jiffies_64;
    extern unsigned long volatile __jiffy_data jiffies;
    
    #if (BITS_PER_LONG < 64) 
    u64 get_jiffies_64(void);
    #else
    static inline u64 get_jiffies_64(void)
    {
        return (u64)jiffies;
    }
    #endif

    二. 函数

    初始化定时器

    init_timer(&mytimer);

    DEFINE_TIMER(_name, _function, _expires, _data);

    TIMER_INITIALIZER(_function, _expires, _data);

    setup_timer(timer, fn, data);

    首次使能定时器

    add_timer(&mytimer);
    再次使能定时器

    mod_timer(&mytimer, unsigned long expires);
    删除定时器

    del_timer_sync(&mytimer); //删除前要等待定时器处理完,不能发生在中断上下文。

    del_timer(&mytimer); //删除定时器

    三. 示例

    #include <linux/init.h>
    #include <linux/module.h>
    #include <asm/current.h>
    #include <linux/timer.h>
    #inlcude <linux/sched.h>
    
    MODULE_LISENCE("GPL");
    
    extern struct task_struct *current;
    
    struct timer_list mytimer;
    
    void timer_handler(unsigned long arg)
    {
        printk("timer arg = %d
    ", arg);
        mod_timer(&mytimer, jiffies + HZ * 5);
    
        return;
    }
    
    static int __init akae_init(void)
    {
        int local = 0;
    
        printk("module name is %s
    ", KBUILD_MODNAME);
        printk("akae_init at %p
    ", akae_init);
    
        printk("jiffies at %p
    ", &jiffies);
        printk("jiffies is %ld
    ", jiffies);
    
        printk("The process is "%s" (pid %i)
    ", current->name, curent->pid);
        
        init_timer(&mytimer);
    
        printk("HZ is %d
    ", HZ);
        mytimer.expires = jiffies + HZ * 5;
        mytimer.function = timer_handler;
        mytimer.data = 100;
    
        add_timer(&mytimer);
    
        return 0;
    }
    
    static void __exit akae_exit(void)
    {
        printk("module eixt.
    ");
        printk("akae_exit at %p
    ", akae_exit);
    
        del_timer_sync(&mytimer);
    
        return;
    }
    
    module_init(akae_init);
    module_exit(akae_exit);
  • 相关阅读:
    EXTJS 4.2 资料 控件之checkboxgroup的用法(静态数据)
    EXTJS 4.2 资料 控件之Window窗体相关属性的用法
    EXTJS 4.2 资料 控件之textfield文本框加事件的用法
    Entity Framework 学习笔记(一)之数据模型 数据库
    EXTJS 4.2 资料 控件之checkboxgroup的用法(动态数据)
    EXTJS 4.2 资料 控件之Grid 列鼠标悬停提示
    Entity Framework 学习笔记(二)之数据模型 Model 使用过程
    EXTJS 4.2 资料 控件之radiogroup 的用法
    EXTJS API
    vue移动端弹框组件,vue-layer-mobile
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/8561404.html
Copyright © 2011-2022 走看看