Linux驱动中delayed_workqueue使用:
2018-01-26 17:10
711 查看
在驱动中,有时不能使用中断(这种情况很少遇到),此时delayed_workqueue就可以发挥其巨大的功效了。也可以用其它同类的内核API实现:如timer.delayed_workqueue的使用过程如下:
(1)定义workqueue: struct workqueue_struct *test_workqueue; // kernel/workqueue.c
(2)定义workqueue要做的delayed工作:struct delayed_work test_delayed_work;// include/linux/workqueue.h
(3)初始化workqueue:INIT_DELAYED_WORK(&test_delayed_work,test_workqueue_func); //定义在:include/linux/workqueue.h
(4) 创建线程queue并加以名字:test_workqueue = create_singlethread_workqueue("name_of_this_queue");
(5)运行queue:queue_delayed_work(test_workqueue, &test_delayed_work, delay_time); //定义在:kernel/workqueue.c, 其中delay_time是延迟多少时间来运行queue。
注: 在test_workqueu_func中一定要再次将delayed_workqueue加入queue中,即再次运行queue_delayed_work。否则,此queue只运行一次。
下面详细讲解每个函数。
#define INIT_DELAYED_WORK(_work, _func) \
do { \
INIT_WORK(&(_work)->work, (_func)); \
init_timer(&(_work)->timer); \
} while (0)
#define INIT_WORK(_work, _func) \
do { \
(_work)->data = (atomic_long_t) WORK_DATA_INIT(); \
INIT_LIST_HEAD(&(_work)->entry); \
PREPARE_WORK((_work), (_func)); \
} while (0)
#endif
// WORK_DATA_INIT() == 0;
// PREPARE_WORK((_work), (_func)) == (_work)->func = (_func);
struct delayed_work {
struct work_struct work;
struct timer_list timer;
};
#define init_timer(timer) init_timer_key((timer), NULL, NULL)
init_timer_key((timer), NULL, NULL) --> debug_time_init [ NOP]
使用delayed workqueue最主要的是调用queue_delayed_work。如果delay = 0,则直接调用:queue_work 其具体实现过程:queue_work --> queue_work_on --> __queue_work --> insert_work
如果delay !=0,则调用:queue_delayed_work_on
其具体实现过程:queue_delayed_work_on 此函数是通过timer来完成最后的延时工作。
在驱动中,有时不能使用中断(这种情况很少遇到),此时delayed_workqueue就可以发挥其巨大的功效了。也可以用其它同类的内核API实现:如timer.delayed_workqueue的使用过程如下:
(1)定义workqueue: struct workqueue_struct *test_workqueue; // kernel/workqueue.c
(2)定义workqueue要做的delayed工作:struct delayed_work test_delayed_work;// include/linux/workqueue.h
(3)初始化workqueue:INIT_DELAYED_WORK(&test_delayed_work,test_workqueue_func); //定义在:include/linux/workqueue.h
(4) 创建线程queue并加以名字:test_workqueue = create_singlethread_workqueue("name_of_this_queue");
(5)运行queue:queue_delayed_work(test_workqueue, &test_delayed_work, delay_time); //定义在:kernel/workqueue.c, 其中delay_time是延迟多少时间来运行queue。
注: 在test_workqueu_func中一定要再次将delayed_workqueue加入queue中,即再次运行queue_delayed_work。否则,此queue只运行一次。
下面详细讲解每个函数。
#define INIT_DELAYED_WORK(_work, _func) \
do { \
INIT_WORK(&(_work)->work, (_func)); \
init_timer(&(_work)->timer); \
} while (0)
#define INIT_DELAYED_WORK(_work, _func) \ do { \ INIT_WORK(&(_work)->work, (_func)); \ init_timer(&(_work)->timer); \ } while (0)
#define INIT_WORK(_work, _func) \
do { \
(_work)->data = (atomic_long_t) WORK_DATA_INIT(); \
INIT_LIST_HEAD(&(_work)->entry); \
PREPARE_WORK((_work), (_func)); \
} while (0)
#endif
// WORK_DATA_INIT() == 0;
// PREPARE_WORK((_work), (_func)) == (_work)->func = (_func);
struct delayed_work {
struct work_struct work;
struct timer_list timer;
};
#define INIT_WORK(_work, _func) \ do { \ (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ INIT_LIST_HEAD(&(_work)->entry); \ PREPARE_WORK((_work), (_func)); \ } while (0) #endif // WORK_DATA_INIT() == 0; // PREPARE_WORK((_work), (_func)) == (_work)->func = (_func); struct delayed_work { struct work_struct work; struct timer_list timer; };INIT_WORK的主要工作是data赋值为0; 初始化entry链表;将_func传给work的_func。
#define init_timer(timer) init_timer_key((timer), NULL, NULL)
#define init_timer(timer) init_timer_key((timer), NULL, NULL)
init_timer_key((timer), NULL, NULL) --> debug_time_init [ NOP]
使用delayed workqueue最主要的是调用queue_delayed_work。如果delay = 0,则直接调用:queue_work 其具体实现过程:queue_work --> queue_work_on --> __queue_work --> insert_work
如果delay !=0,则调用:queue_delayed_work_on
其具体实现过程:queue_delayed_work_on 此函数是通过timer来完成最后的延时工作。
相关文章推荐
- Linux驱动中delayed_workqueue使用
- cancel_rearming_delayed_workqueue 函数使用的一个小备注
- 慢慢学Linux驱动开发,第七篇,scull的使用
- Linux 视频设备驱动V4L2最常用的控制命令使用说明(1.02)
- Linux下USB从(USB gadget) 驱动配置与使用
- 关于linux驱动(应用)程序头文件使用
- 块设备驱动向LINUX移植的常规步骤及INITRD的使用
- 使用eclipse开发linux驱动
- android系统PS2全键盘驱动(上)-使用linux的标准接口实现
- linux下使用JDBC需要安装驱动jar包
- Linux 视频设备驱动V4L2最常用的控制命令使用说明
- 基于S3C2440的嵌入式Linux驱动——DS18B20温度传感器(添加使用platform总线机制)
- Linux 视频设备驱动V4L2最常用的控制命令使用说明
- Linux定时器的使用-内核驱动定时器
- linux驱动中使用其它模块导出的符号
- 转:linux下使用USB转串口线的方法-minicom和hl-340/341(usb转串口线)驱动
- 使用eclipse开发linux驱动
- linux 2.6.x spi驱动,spidev,使用从设备
- Linux视频设备驱动常用控制命令使用说明
- Linux 设备驱动 Edition 3) ---- workqueue