电子产业一站式赋能平台

PCB联盟网

搜索
查看: 33|回复: 0
收起左侧

Linux驱动基础 | 延时函数的使用

[复制链接]

369

主题

369

帖子

4297

积分

四级会员

Rank: 4

积分
4297
发表于 2025-2-23 10:54:00 | 显示全部楼层 |阅读模式
点击上方“Linux随笔录”,选择“置顶/星标公众号”
福利干货,第一时间送达
  • 前言
  • 思考
  • 延时函数的定义
  • mdelay的定义
  • msleep的定义
  • 延迟函数的使用
  • mdelay的使用
  • msleep的使用
  • 注意事项
  • mdelay的注意事项
  • msleep的注意事项
  • 总结
  • 最后

    前言 linux 驱动开发过程中,经常会用到延迟函数:udelay,mdelay,usleep,msleep,usleep_range,所以本篇记录下获取内核延时所用到的API使用,用的比较多的mdelay和msleep。本篇讲下mdelay和msleep的使用
    思考 msleep和mdelay都是内核的ms级延时函数使用时有何区别,面试题经常会被问到,不会的同学看过来
    延时函数的定义 mdelay的定义延迟函数mdelay的定义位于file: include/linux/delay.h文件中
    #ifndef mdelay
    44 #define mdelay(n) (\
    45         (__builtin_constant_p(n) && (n)
    47 #endif
    可以从定义看到,CPU在做忙等待,延时效果是精准延时
    msleep的定义延迟函数msleep的定义位于file: kernel/time/timer.c文件中
    2029 /**
    2030  * msleep - sleep safely even with waitqueue interruptions
    2031  * @msecs: Time in milliseconds to sleep for
    2032  */
    2033 void msleep(unsigned int msecs)
    2034 {      
    2035         unsigned long timeout = msecs_to_jiffies(msecs) + 1;
    2036
    2037         while (timeout)
    2038                 timeout = schedule_timeout_uninterruptible(timeout);
    2039 }      
    2040
    2041 EXPORT_SYMBOL(msleep);
    我们看下schedule_timeout_uninterruptible函数做了哪些事情
    1914 signed long __sched schedule_timeout_uninterruptible(signed long timeout)
    1915 {
    1916         __set_current_state(TASK_UNINTERRUPTIBLE);
    1917         return schedule_timeout(timeout);
    1918 }
    1919 EXPORT_SYMBOL(schedule_timeout_uninterruptible·);
    解释下:__set_current_state(TASK_UNINTERRUPTIBLE)是设置当前进程设置不可中断状态, 就是让进程睡够指定时间才能唤醒,睡眠过程不可被中断(即UNINTERRUPTIBLE),意思不会被信号打断提前唤醒,然后schedule_timeout(timeout)函数timeout时间内主动调用schedule()主动让出CPU资源timeout时间,也就是说msleep会有上下文切换的开销,所以说msleep要比实际timeout的时间多延时一点时间
    延迟函数的使用 我们就用mdelay和msleep都写个都延时1s,看看他们的延时效果
    mdelay的使用来看个mdelay的使用demo
    #include
    #include
    #include
    static int __init my_module_init(void)
    {
        printk(KERN_INFO "Module loading...
    ");
       
        mdelay(1000); // 延迟 1000 毫秒 (1 秒)
        printk(KERN_INFO "1 second delay finished.
    ");
        return 0;
    }
    static void __exit my_module_exit(void)
    {
        printk(KERN_INFO "Module unloading...
    ");
    }
    module_init(my_module_init);
    module_exit(my_module_exit);
    MODULE_LICENSE("GPL");
    MODULE_DESCRIPTION("A simple module using mdelay");
    MODULE_AUTHOR("Your Name");
    然后编译完放板子上加载驱动
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表