hrtimer和work工作队列的使用
Posted 柒月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hrtimer和work工作队列的使用相关的知识,希望对你有一定的参考价值。
1.hrtimers - 为高分辨率kernel定时器,可作为超时或周期性定时器使用
1). hrtimer_init初始化定时器工作模式。
hrtimer_init(&vibe_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
vibe_timer.function = vibrator_timer_func;
/* 设置定时器的回调函数,定时器到时该函数将被调用 */
static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
注:该回调函数为原子操作不能被中断
2). hrtimer_start的第二个参数用于设置超时参数。
hrtimer_start(&vibe_timer,
ktime_set(value / 1000, (value % 1000) * 1000000),HRTIMER_MODE_REL);
3). INIT_WORK初始化工作队列。
INIT_WORK(&vibe_work, vibe_work_func);
static void vibe_work_func(struct work_struct *work)
4). schedule_work调用工作队列。
schedule_work(&vibe_work);
- /* linux/drivers/ker-driver.c
- * Author: Woodpecker <[email protected]>
- *
- * kernel-driver
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- *
- */
- #include <linux/module.h> /* MODULE_LICENSE */
- #include <linux/kernel.h> /* printk,pr_info */
- #include <linux/errno.h> /* EINVAL,EAGAIN,etc. */
- #include <linux/err.h> /* IS_ERR */
- #include <linux/fb.h> /* FB header file */
- #include <linux/init.h> /* module_init */
- #include <linux/semaphore.h> /* init_MUTEX APIs */
- #include <linux/mm.h> /* vm_area_struct */
- #include <linux/dma-mapping.h> /* DMA APIs */
- #include <linux/delay.h> /* mdelay,msleep */
- #include <linux/hrtimer.h>
- #include <linux/time.h> /* struct timespec */
- #define KER_PRINT(fmt, ...) printk("<ker-driver>"fmt, ##__VA_ARGS__);
- static struct hrtimer vibe_timer;
- static struct work_struct vibe_work;
- static void vibe_work_func(struct work_struct *work)
- {
- KER_PRINT("vibe_work_func:msleep(50)/n");
- msleep(50); /* CPU sleep */
- }
- static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
- {
- struct timespec uptime;
- do_posix_clock_monotonic_gettime(&uptime);
- KER_PRINT("Time:%lu.%02lu/n",
- (unsigned long) uptime.tv_sec,
- (uptime.tv_nsec / (NSEC_PER_SEC / 100)));
- KER_PRINT("vibrator_timer_func/n");
- schedule_work(&vibe_work);
- return HRTIMER_NORESTART;
- }
- static int __init ker_driver_init(void)
- {
- int value = 2000; /* Time out setting,2 seconds */
- struct timespec uptime;
- KER_PRINT("ker_driver_init/n");
- hrtimer_init(&vibe_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- vibe_timer.function = vibrator_timer_func;
- hrtimer_start(&vibe_timer,
- ktime_set(value / 1000, (value % 1000) * 1000000),HRTIMER_MODE_REL);
- //static inline ktime_t ktime_set(const long secs, const unsigned long nsecs) 第一个参数为秒,第二个为纳秒
- do_posix_clock_monotonic_gettime(&uptime);
- KER_PRINT("Time:%lu.%02lu/n",
- (unsigned long) uptime.tv_sec,
- (uptime.tv_nsec / (NSEC_PER_SEC / 100)));
- INIT_WORK(&vibe_work, vibe_work_func); /* Intialize the work queue */
- return 0;
- }
- static void __exit ker_driver_exit(void)
- {
- hrtimer_cancel(&vibe_timer);
- }
- module_init(ker_driver_init);
- module_exit(ker_driver_exit);
- MODULE_AUTHOR("Woodpecker <[email protected]>");
- MODULE_DESCRIPTION("Kernel driver");
- MODULE_LICENSE("GPL");
驱动的运行结果:
以上是关于hrtimer和work工作队列的使用的主要内容,如果未能解决你的问题,请参考以下文章
Linux工作队列的INIT_WORK跟DECLARE_WORK到底是3个参数还是2个参数?
RabbitMQ入门教程:工作队列(Work Queues)