hrtimer和work工作队列的使用
2017-01-06 16:15
736 查看
1.hrtimers - 为高分辨率kernel定时器,可作为超时或周期性定时器使用
vibe_timer.function = vibrator_timer_func;
/* 设置定时器的回调函数,定时器到时该函数将被调用 */
static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
注:该回调函数为原子操作不能被中断
ktime_set(value / 1000, (value % 1000) * 1000000),HRTIMER_MODE_REL);
static void vibe_work_func(struct work_struct *work)
5 例子代码
#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");
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);5 例子代码
#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");
6 测试结果
相关文章推荐
- windows 内核文档化API/导出但未文档化API/未导出API
- Linux 安装VNC
- libopencv_gpu.so.2.4: undefined reference to `cv::gpu
- 架构师的必备素质和成长途径
- 【lua】table是否为空的判断
- Umeng错误统计集成
- HttpServletResponse对象常见应用
- Linux MariaDB 遗忘密码后重置密码
- Python收集centos7IP地址
- iOS 利用 UISegmentedControl在同一个控制器切换不同的tableView
- linux下tomcat服务器内存、端口及监控用户配置
- nginx 11个处理阶段 && nginx lua 8个处理阶段
- 在PHP中封装MySQL常用函数
- 浅谈Spring事务隔离级别
- 百度地图坐标转换API和地图API
- curl与file_get_contents获取内容的比较
- RabbitMQ vhost
- 彻底了解View 的坐标关系
- 如何不让google.com跳转到google.com.hk?
- (转)本地通知和远程推送