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);
  • 相关阅读:
    PostgreSQL数据库笔记
    LayUI
    Spring
    Mybatis
    Mybatis生成
    server服务器信息页面添加步骤
    Java数据类型和MySql数据类型对应表
    空字符串
    json解析尖括号<>
    JSON--List集合转换成JSON对象
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/8561404.html
Copyright © 2011-2022 走看看