linux 工作队列之schedule_delayed_work用法

本文详细介绍了如何在Linux内核中使用schedule_delayed_work工作队列机制,从定义delayed_work结构、实现回调函数、初始化数据结构、提交任务到工作队列,到最后的测试验证,每一步都清晰阐述,展示了如何每隔1秒打印当前UTC时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

linux 工作队列之schedule_delayed_work用法


一、定义自己的delayed_work

函数原型:

struct delayed_work {                          
       struct work_struct work;                          
       struct timer_list timer;                 
};

定义自己的:

struct My_Dvice_struct{  
           struct delayed_work work; 
};
struct My_Dvice_struct My_Dvice; 

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

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

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

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

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

static void func_callback(struct work_struct *work)

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));
}

三、初始化数据结构

原型:

第一个参数:自己定义的delayed_work 
第二个参数:自己定义的func_callback

INIT_DELAYED_WORK(struct delayed_work *work, work_func_t func)

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

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

四、提交任务到工作队列

原型:

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

自己实现的:

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

初始化我们在平台设备的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;
}

五、测试现象

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:/ #

打印口:每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


总结

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

#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/platform_device.h>
#include <linux/fb.h>
#include <linux/err.h>
#include <linux/pwm.h>
#include <linux/slab.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/rtc.h>
#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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

那肯定是很多年以后!

你的鼓励就我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值