查看: 1074|回复: 0

芯灵思Sinlinx A64开发板Linux内核定时器编程

[复制链接]
  • TA的每日心情
    奋斗
    2016-4-14 10:16
  • 签到天数: 9 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2019-3-11 16:32:39 | 显示全部楼层 |阅读模式
    分享到:
    开发平台 芯灵思Sinlinx A64
    内存: 1GB   存储: 4GB
    开发板详细参数 https://m.tb.cn/h.3wMaSKm
    开发板交流群 641395230
    Linux 内核定时器是内核用来控制在未来某个时间点(基于jiffies)调度执行某个函数的一种机制,其实现位于 <Linux/timer.h> 和 kernel/timer.c 文件中。

    内核定时器的数据结构

    struct timer_list {
        struct list_head entry;  //双向链表元素list:用来将多个定时器连接成一条双向循环队列。
        unsigned long expires; //expires 字段表示期望定时器执行的 jiffies 值,到达该 jiffies 值时,将调用 function 函数,并传递 data 作为参数。
        void (*function)(unsigned long); //指向一个可执行函数。当定时器到期时,内核就执行function所指定的函数。而data域则被内核用作function函数的调用参数。
        unsigned long data;
        struct tvec_base *base;
        /* ... */
    };
    时间比较操作
    在定时器应用中经常需要比较两个时间值,以确定timer是否超时,所以Linux内核在timer.h头文件中定义了4个时间关系比较操作宏。这里我们说时刻a在时刻b之后,就意味着时间值a≥b。
    Linux强烈推荐用户使用它所定义的下列4个时间比较操作宏(include/linux/timer.h):
    #define time_after(a,b) ((long)(b) - (long)(a) < 0)
    #define time_before(a,b) time_after(b,a)
    #define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0)
    #define time_before_eq(a,b) time_after_eq(b,a)

    Linux 内核时间相关转换函数
    1. unsigned long usecs_to_jiffies(const unsigned int u)
    功能: 把微秒转换成时钟节拍
    参数: u 时间微秒
    返回: 对应的时钟节拍数量
    2. unsigned long msecs_to_jiffies(const unsigned int m)
    功能: 把毫秒转换成时钟节拍
    参数: u 时间毫秒
    返回: 对应的时钟节拍数量
    示例: 要定时从现在开始, 3 毫秒执行一个函数
    expires 设置为 jiffies+ msecs_to_jiffies(3)

    Linux 内核定时器操作相关 API
    1. 静态定义结构体变量并且初始化(宏)
    DEFINE_TIMER(_name, _function, _expires, _data)
    功能: 定义一个名字为_name 的 struct timer_list 结构的变量, 并且初始化它的 function, expires, data 成员

    2. 定时器初始化(宏)
    init_timer(timer)
    功能: 只是对 struct timer_list 结构成员进行一些基础初始化操作, function, expires, data 成员还需要用户自
    己填充。

    3.设置定时器(宏)
    setup_timer(timer, fn, data)
    功能: 设置定时器中的 function, data 和一些基础成员, expires 并没有初始化, 需要用户自己进行初始化

    4. 注册定时器到内核
    void add_timer(struct timer_list *timer)
    功能: 向内核注册一个定时器, 注册后会马上开始计时。
    5.从内核注销定时器
    int del_timer(struct timer_list * timer);
    功能: 从内核定时链表上删除指定的定时器, 删除后就不会再执行绑定的函数

    6. 修改定时器定时时间值, 并且重新注册
    int mod_timer(struct timer_list *timer, unsigned long expire0.s);
    功能: 修改定时器定时时间值, 并且重新注册, 不管这个定时的超时函数是否执行过。 执行完成后会马上启
    动定时。

    内核定时器编程步骤
    Step1 定义timer_list 结构变量
    Step2 定义超时函数
    Step3 对timer_list结构变量进行初始化
    Step4 注册定时器,启动定时
    Step5 注销定时器

    驱动代码:
    1. #include <linux/module.h>
    2. #include <linux/init.h>
    3. #include <linux/timer.h>

    4. //Step1 timer_list 结构变量
    5. struct timer_list timer;
    6. //Step2 超时函数
    7. void timer_fun(long data)
    8. {
    9.                 printk("%s is call! data:%d\r\n",__FUNCTION__,data);//__FUNCTION__   获取当前函数名
    10.                 mod_timer(&timer, jiffies + HZ*1); //再次修改本定时器超时时间为当前时间后1秒
    11. }
    12. static int __init timer_init(void)
    13. {
    14.                 //Step3 对timer_list结构变量进行初始
    15.                 init_timer(&timer);
    16.                 setup_timer(&timer, timer_fun, 666);
    17.                 timer.expires = jiffies + HZ*2;
    18.                 //Step4 注册定时器,启动定时
    19.                 add_timer(&timer);
    20.                 printk("Timer start!\r\n");
    21.                 return 0;
    22. }
    23. static void __exit timer_exit(void) //Module exit function specified by module_exit()
    24. {
    25.                 //Step5 注销定时器
    26.                 del_timer_sync(&timer);
    27.                 printk("Timer over!\r\n");
    28. }
    29. module_init(timer_init);
    30. module_exit(timer_exit);
    31. MODULE_LICENSE("GPL");
    复制代码



    Makefile代码:
    1. KERN_DIR = /work/lichee/linux-3.4
    2. all:
    3.         make -C $(KERN_DIR) M=`pwd` modules
    4. clean:
    5.         make -C $(KERN_DIR) M=`pwd` modules clean
    6.         rm -rf modules.order
    7. obj-m        += timer_drv.o
    复制代码

    最后使用 dmseg 命令查看,可以看到每隔1秒打印一次


    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-11-19 20:19 , Processed in 0.116681 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.