4412 Linux定时器

发布者:幸福时光最新更新时间:2022-01-10 来源: eefocus关键字:Linux  定时器 手机看文章 扫描二维码
随时随地手机看文章

一、Linux定时器基础知识

1.1 定时器的使用范围

延后执行某个操作,定时查询某个状态;前提是对时间要求不高的地方


1.2 内核时间概念

  • Hz:(系统时钟通过CONFIG_HZ来设置,范围是100-1000;HZ决定使用中断发生的频率)


    • 1/200 = 5ms,说明4412中是5ms产生一次时钟中断。如果就没有定义的话,默认是100

  • 内核的全局变量jiffies:(记录内核自启动来的节拍数,内核之启动以来,产生的中断数)时钟中断,每产生一个中断,jiffies就加1。

  • jiffies/HZ:jiffies除以Hz得到内核自启动以来的秒数


2.1 内核定时器的例程

结构体timer_list,函数setup_timer,add_timer,del_timer,mod_timer

 timer_list

struct timer_list {

    /*

     * All fields that change during normal runtime grouped to the

     * same cacheline

     */

    struct list_head entry;

    unsigned long expires;

    struct tvec_base *base;


    void (*function)(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

};




timer_list参数

  • struct list_head entry双向链表

  • unsigned long expires:超时时间,记录什么时候产生时钟中断

  • struct tvec_base *base:管理时钟的结构体

  • void *(function)(unsigned long):时钟中断产生之后的动作

  • unsigned long data:传递的参数


#define setup_timer(timer, fn, data)                   

    do {                               

        static struct lock_class_key __key;         

        setup_timer_key((timer), #timer, &__key, (fn), (data));

    } while (0)


void add_timer(struct timer_list *timer);

int del_timer(struct timer_list * timer);

int mod_timer(struct timer_list *timer, unsigned long expires);


2.2 双向链表

platform_driver_register→driver_register

→bus_add_driver

→struct bus_type *bus

→struct subsys_private *p

→struct kset subsys→struct list_head list;

 

2.3 mod_timer相当于

mod_timer = del_timer(time);timer->expires = expires;add_timer(timer);

 

3 内核定时器实现的分析

从内核定时器初始化到定时器例程

3.1 add_timer如何添加定时器

        add_timer→mod_timer
        →__mod_timer(内核函数有下划线,表示“局部函数”)
        →internal_add_timer

3.2 struct tvec_base *base结构体分析--管理内核时钟的结构体

        struct tvec_base {

            spinlock_t lock;    //自旋锁

            struct timer_list *running_timer;    //内核中正在处理的定时器

            unsigned long timer_jiffies;        //内核目前正在处理的定时器时间

            unsigned long next_timer;    

            struct tvec_root tv1;

            {

                struct list_head vec[TVR_SIZE];//256长度数组

                TVR_SIZE→#define TVR_SIZE (1 << TVR_BITS)

                TVR_BITS=8;

                宏定义CONFIG_BASE_SMALL=0

                TVR_SIZE = 256

            }

            struct tvec tv2;    //64长度数组

            struct tvec tv3;

            struct tvec tv4;

            struct tvec tv5;

        }


per_cpu 与CPU核多少有关    
DEFINE_PER_CPU看到这样的变量,就表明这个变量是和CPU核相关的。

有一些宏定义是在内核目录的config文件配置的 

3.3 internal_add_timer

分析idx参数
如果idx<256,则将time_list添加到TV1
如果idx<256*64,则将time_list添加到TV2
如果idx<256*64*64,则将time_list添加到TV3
如果idx<256*64*64*64,则将time_list添加到TV4
如果idx > 0xffffffffUL,则将time_list添加到TV5

 

3.4 list_add_tail

双向链表操作函数都在include/linux/list.h文件中


关键字:Linux  定时器 引用地址:4412 Linux定时器

上一篇:4412 4路pwm输出
下一篇:4412 SPI驱动

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved