您的位置:首页 > 其它

hrtimer和work工作队列的使用

2016-06-07 15:10 239 查看

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

view
plaincopy
to clipboardprint?

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

/* linux/drivers/ker-driver.c

* Author: Woodpecker <Pecker.hu@gmail.com>

*

* 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 <Pecker.hu@gmail.com>");

MODULE_DESCRIPTION("Kernel driver");

MODULE_LICENSE("GPL");

驱动的运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: