• RK3568平台 内核定时器的使用


    一.linux内核定时器

    硬件为内核提供了一个系统定时器来计算流逝的时间(即基于未来时间点的计时方式,以当前时刻为计时开始的起点,以未来的某一时刻为计时的终点),内核只有在系统定时器的帮助下才能计算和管理时间,但是内核定时器的精度并不高,所以不能作为高精度定时器使用。并且内核定时器的运行没有周期性,到达计时终点后会自动关闭。如果要实现周期性定时,就要在定时处理函数中重新开启定时器。

    二.内核定时器数据结构

    1. struct timer_list {
    2.     struct list_head entry, /*定时器列表*/
    3.     unsigned long expires, /*定时器到期时间,单位为节拍数*/
    4.     void (*function) (unsigned long), /*定时器处理函数*/
    5.     unsigned long data,/*作为参数被传入定时器处理函数*/
    6.     struct timer_base_s *base,
    7.     ...
    8.   };

    三.内核定时器API

    add_timer:

    1. 作用:
    2. add_timer函数用于向Linux内核注册定时器,使用add_timer函数向内核注册定时器以后,定时器就会开始运行。
    3. 参数:
    4. timer:要注册的定时器。
    5. 返回值:

    del_timer:

    1. 作用:
    2. del_timer函数用于删除一个定时器,不管定时器有没有被激活,都可以使用此函数删除。在多处理器系统上,定时器可能会在其他的处理器上运行,因此在调用del_timer函数删除定时器之前要先等待其他处理器的定时处理器函数退出。
    3. 参数:
    4. timer:要删除的定时器。
    5. 返回值:
    6. 0,定时器还没被激活;
    7. 1,定时器已经激活。

     mod_timer:

    1. 作用:
    2. mod_timer函数用于修改定时值,如果定时器还没有激活的话,mod_timer函数会激活定时器。
    3. 参数:
    4. timer:要修改超时时间(定时值)的定时器。
    5. expires:修改后的超时时间。
    6. 返回值:
    7. 0,调用mod_timer函数前定时器未被激活;
    8. 1,调用mod_timer函数前定时器已被激活。

     四.相关概念介绍

    节拍率:

    内核中有一个宏HZ,表示一秒所对应的节拍数,可以通过这个宏来把时间转换成节拍数,1秒的表示如下:

    mytimer.expires = jiffies+HZ;
    

    在使用 add_timer()函数向 Linux 内核注册定时器之前,还需要设置定时时间,定时时间由 timer_list 结构体中的 expires 参数所确定,单位为节拍数,可以通过图形化界面设置系统节拍的频率。

    从上图可以看出可选的系统节拍率为 100Hz、250Hz、300Hz 和1000Hz,默认情况下选择300Hz。

    五.定时器驱动程序

    1. #include <linux/init.h>
    2. #include <linux/module.h>
    3. #include <linux/timer.h>
    4. static void function_test(struct timer_list *t);//定义function_test定时功能函数
    5. DEFINE_TIMER(timer_test,function_test);//定义一个定时器
    6. static void function_test(struct timer_list *t)
    7. {
    8. printk("this is function test \n");
    9. mod_timer(&timer_test,jiffies_64 + msecs_to_jiffies(5000));//使用mod_timer函数将定时时间设置为五秒后
    10. }
    11. static int __init timer_mod_init(void) //驱动入口函数
    12. {
    13. timer_test.expires = jiffies_64 + msecs_to_jiffies(5000);//将定时时间设置为五秒后
    14. add_timer(&timer_test);//添加一个定时器
    15. return 0;
    16. }
    17. static void __exit timer_mod_exit(void) //驱动出口函数
    18. {
    19. del_timer(&timer_test);//删除一个定时器
    20. printk("module exit \n");
    21. }
    22. module_init(timer_mod_init);
    23. module_exit(timer_mod_exit);
    24. MODULE_LICENSE("GPL v2");
    25. MODULE_AUTHOR("topeet");

    每隔五秒钟会打印“this is function test”

  • 相关阅读:
    一次做数据报表的踩坑经历,让我领略了数据同步增量和全量的区别
    一次就能释放大量Mac内存空间的方法,你用过哪种?
    [项目管理-5]:软硬件项目管理 - 项目人力资源管理 (人)
    js_typeof关键字和比较运算符
    ffmpeg花屏解决(修改源码,丢弃不完整帧)
    创建资产报错:号码范围 71 没有在号码分配范围内
    Google Earth Engine(GEE)扩展——geetool中的的各类型的其它函数(字符串、数字、列表、字典、几何、特征、影像、地图和特征集合)
    Java线程池基础
    车联网技术解决方案与应用案例--智能TBOX车载终端
    深度学习入门-与学习相关的技巧
  • 原文地址:https://blog.csdn.net/weixin_49303682/article/details/136199371