• linux 工作队列之schedule_delayed_work用法



    前言

    linux 工作队列之schedule_delayed_work用法


    一、定义自己的delayed_work

    函数原型:

    struct delayed_work {                          
           struct work_struct work;                          
           struct timer_list timer;                 
    };
    
    • 1
    • 2
    • 3
    • 4

    定义自己的:

    struct My_Dvice_struct{  
               struct delayed_work work; 
    };
    struct My_Dvice_struct My_Dvice; 
    
    • 1
    • 2
    • 3
    • 4

    二、定义在工作队列中被调用的函数

    1.在工作队列中被调用的函数原型

     typedef void (*work_func_t)(struct work_struct *work);
    
    • 1

    2.定义在工作队列中被调用的自己实现的函数

    自己实现的函数要有在工作队列中被调用的函数原型的保持形参一至:(struct work_struct *work)

    static void func_callback(struct work_struct *work)
    
    • 1

    func_callback处理的事情:每1s在驱动获取时间打印出来

    static void func_callback(struct work_struct *work)
    {   
        struct timex txc;  
        struct rtc_time tm;
    	do_gettimeofday(&(txc.time));
    	rtc_time_to_tm(txc.time.tv_sec,&tm);
    	printk("%s-UTC time:%d-%d-%d %d:%d:%d    -",__func__,tm.tm_year+1900,tm.tm_mon, tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec);
    	schedule_delayed_work(&My_Dvice.work,msecs_to_jiffies(1000));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    三、初始化数据结构

    原型:

    第一个参数:自己定义的delayed_work 
    第二个参数:自己定义的func_callback
    
    INIT_DELAYED_WORK(struct delayed_work *work, work_func_t func)
    
    • 1
    • 2
    • 3
    • 4

    初始化我们在平台设备的probe下进行初始化:

    static int My_probe(struct platform_device *dev)
    {
    	printk("%s\n",__func__);
    	INIT_DELAYED_WORK(&My_Dvice.work, func_callback);//初始化数据结构
    	-----
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    四、提交任务到工作队列

    原型:

      int schedule_delayed_work(struct delayed_work *work, unsigned long delay);
    
    • 1

    自己实现的:

    schedule_delayed_work(&My_Dvice.work,msecs_to_jiffies(1000));
    
    • 1

    初始化我们在平台设备的probe下进行初始化:

    static int My_probe(struct platform_device *dev)
    {
    	printk("%s\n",__func__);
    	INIT_DELAYED_WORK(&My_Dvice.work, func_callback);
    	schedule_delayed_work(&My_Dvice.work,msecs_to_jiffies(1000));
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    五、测试现象

    cmd 将我们的ko文件push到系统

    C:\Users\86182>adb root
    restarting adbd as root
    C:\Users\86182>adb remount
    remount succeeded
    C:\Users\86182>adb push xxxxxxxxxxxxx\kernel\drivers\leds\platform.ko /
    \\xxxxxxxxxxxxx\kernel\drivers\le...file pushed, 0 skipped. 26.5 MB/s (283920 bytes in 0.010s)
    C:\Users\86182>adb shell
    rk3399:/ # insmod p
    platform.ko  proc/        product/
    rk3399:/ # insmod platform.ko
    rk3399:/ #
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    打印口:每1s打印打印一次时间

    [ 2066.874421] func_callback-UTC time:2022-6-8 1:50:43    -func_callback
    [ 2067.877757] func_callback-UTC time:2022-6-8 1:50:44    -func_callback
    [ 2068.881091] func_callback-UTC time:2022-6-8 1:50:45    -func_callback
    [ 2069.884425] func_callback-UTC time:2022-6-8 1:50:46    -func_callback
    [ 2070.887635] func_callback-UTC time:2022-6-8 1:50:47    -func_callback
    [ 2071.890968] func_callback-UTC time:2022-6-8 1:50:48    -func_callback
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    总结

    实现的:demo.c
    编译ko: obj-m += platform.o

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #define use_dts 0
    struct My_Dvice_struct{  
               struct delayed_work work; 
    		   
    };
    struct My_Dvice_struct My_Dvice;  
    
    static void func_callback(struct work_struct *work)
    {   
        struct timex txc;  
        struct rtc_time tm;
    	do_gettimeofday(&(txc.time));
    	rtc_time_to_tm(txc.time.tv_sec,&tm);
    	printk("%s-UTC time:%d-%d-%d %d:%d:%d    -",__func__,tm.tm_year+1900,tm.tm_mon, tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec);
    	schedule_delayed_work(&My_Dvice.work,msecs_to_jiffies(1000));
    }
    static int My_probe(struct platform_device *dev)
    {
    	printk("%s\n",__func__);
    	INIT_DELAYED_WORK(&My_Dvice.work, func_callback);
    	schedule_delayed_work(&My_Dvice.work,msecs_to_jiffies(1000));
    	return 0;
    }
    #if use_dts
    static const struct of_device_id platform_of_match[] = {//设备树下使用
            { .compatible = "platform_hello", },
            {},
    };
    MODULE_DEVICE_TABLE(of, platform_of_match);
    #else
    static struct platform_device My_platform_device = {//无设备树下使用
    	.name = "platform_hello",
    	.id = -1,
    }; 
    #endif
    static int My_remove(struct platform_device *dev)
    {
    	printk("My driver remove\r\n");
    	return 0;
    }
    
    static struct platform_driver My_driver= {
    	.driver = {
    		.name = "platform_hello",
    		.owner	= THIS_MODULE,
    #if use_dts
    
    		.of_match_table = of_match_ptr(platform_of_match),	//设备树下使用
    #endif
    	},
    	.probe = My_probe,
    	.remove = My_remove,
    };
    
    static int __init Mydriver_init(void)
    {
    	platform_driver_register(&My_driver);/*注册platform驱动*/
    	platform_device_register(&My_platform_device);/*注册platform设备*/
    	return 0;
    }
    static void __exit Mydriver_exit(void)
    {
    	platform_driver_unregister(&My_driver);/*卸载platform驱动*/
    	platform_device_unregister(&My_platform_device);/*卸载platform设备*/
    }
    
    module_init(Mydriver_init);
    module_exit(Mydriver_exit);
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("pangxiwen");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
  • 相关阅读:
    qt环境配置
    Python字典
    SpringCloudAlibaba:4.3云原生网关higress的JWT 认证
    SpringCloud Gateway--网关服务基本介绍和基本原理
    【javaEE】多线程初阶(Part5单例模式)
    【科学文献计量】知识单元的频次统计与分布(简单阅览和完整频次统计)
    第五十五章 本地化和基于标签的开发
    PyTorch的自动求导
    【进阶篇】MySQL数据库中的 锁详解
    docker-compose安装教程
  • 原文地址:https://blog.csdn.net/qq_38312843/article/details/126000445