内核sem、wait_queue_head_t、timer和kernel_thread使用驱动范例
来源:互联网 发布:华为交换机端口应用acl 编辑:程序博客网 时间:2024/05/01 05:27
浅析linux内核中sem、wait_queue_head_t、timer和kernel_thread使用驱动范例
#include <linux/sched.h>
#define __TIMER_TEST_MOD1 1
#define __TIMER_TEST_MOD2 2
#define __TIMER_TEST_MOD3 3
#define __TIMER_TEST_MOD4 4
#define __TIMER_TEST_MOD5 5
#define __TIMER_TEST_MOD6 6
#define TIMER_TEST_MOD __TIMER_TEST_MOD6
static inline void restart_timer_delay(struct timer_list *timer, unsigned long msecs)
{
mod_timer(timer,jiffies + msecs_to_jiffies(msecs));
}
struct _sgliethttp_timer
{
wait_queue_head_t waitQ;
struct semaphore sem;
struct timer_list timer;
int timer_freq;
volatile int timer_counts;
volatile int thread_run,thread_quited;
};
static struct _sgliethttp_timer sgliethttp_timer, *gliethttp_timer;
static void timer_func(unsigned long data)
{
restart_timer_delay(&gliethttp_timer->timer, gliethttp_timer->timer_freq);
gliethttp_timer->timer_counts++;
#if (TIMER_TEST_MOD == __TIMER_TEST_MOD2)
up(&gliethttp_timer->sem);
#endif
#if ( (TIMER_TEST_MOD == __TIMER_TEST_MOD3) || /
(TIMER_TEST_MOD == __TIMER_TEST_MOD4) || /
(TIMER_TEST_MOD == __TIMER_TEST_MOD5) || /
(TIMER_TEST_MOD == __TIMER_TEST_MOD6) || 0/
)
wake_up(&gliethttp_timer->waitQ);
//对于wait_event_interruptible_timeout和wait_event_timeout来说,
//就是唤醒timer_thread,然后检查pre_timer_count != gliethttp_timer->timer_counts是否为真,
//如果为真,那么将退出wait_event_interruptible_timeout和wait_event_timeout.
#endif
}
static int timer_thread(void *data)
{
#if ( (TIMER_TEST_MOD == __TIMER_TEST_MOD1) || /
(TIMER_TEST_MOD == __TIMER_TEST_MOD3) || /
(TIMER_TEST_MOD == __TIMER_TEST_MOD4) || 0/
)
int pre_timer_count = gliethttp_timer->timer_counts;
#endif
while(gliethttp_timer->thread_run)
{
#if (TIMER_TEST_MOD == __TIMER_TEST_MOD1)
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);printk("M");
if(gliethttp_timer->timer_counts != pre_timer_count)
{
printk("L");
pre_timer_count = gliethttp_timer->timer_counts;
}
#endif
#if (TIMER_TEST_MOD == __TIMER_TEST_MOD2)
//down_interruptible(&gliethttp_timer->sem);
down(&gliethttp_timer->sem);
printk("L");
#endif
#if (TIMER_TEST_MOD == __TIMER_TEST_MOD3)
wait_event_timeout(gliethttp_timer->waitQ, pre_timer_count != gliethttp_timer->timer_counts, 5*HZ);
pre_timer_count++;
printk("L");
#endif
#if (TIMER_TEST_MOD == __TIMER_TEST_MOD4)
wait_event_interruptible_timeout(gliethttp_timer->waitQ, pre_timer_count != gliethttp_timer->timer_counts, 5*HZ);
pre_timer_count++;
printk("L");
#endif
#if ( (TIMER_TEST_MOD == __TIMER_TEST_MOD5) || (TIMER_TEST_MOD == __TIMER_TEST_MOD6) )
interruptible_sleep_on_timeout(&gliethttp_timer->waitQ, 5*HZ);
printk("L");
#endif
}
gliethttp_timer->thread_quited = 1;
return 0;
}
static int init_gliethttp_timer(void)
{
gliethttp_timer = &sgliethttp_timer;
init_waitqueue_head(&gliethttp_timer->waitQ);
init_MUTEX_LOCKED(&gliethttp_timer->sem);
//init_MUTEX(&gliethttp_timer->sem);
//sema_init(&gliethttp_timer->sem, 10);
gliethttp_timer->thread_run = 1;
gliethttp_timer->thread_quited = 0;
gliethttp_timer->timer_counts = -1;
gliethttp_timer->timer_freq = 100;
setup_timer(&gliethttp_timer->timer, timer_func, gliethttp_timer->timer_freq);
restart_timer_delay(&gliethttp_timer->timer, gliethttp_timer->timer_freq);
kernel_thread(timer_thread, NULL, 0);
printk(KERN_DEBUG"timer test start!/n");
printk(KERN_EMERG"timer test start!/n");
printk(KERN_ALERT"timer test start!/n");
printk(KERN_CRIT"timer test start!/n");
printk(KERN_ERR"timer test start!/n");
printk(KERN_WARNING"timer test start!/n");
printk(KERN_NOTICE"timer test start!/n");
printk(KERN_INFO"timer test start!/n");
//没咒念了,只能使用dmesg|tail来查看结果了
return 0;
}
static void cleanup_gliethttp_timer(void)
{
//del_timer(&timer);
del_timer_sync(&gliethttp_timer->timer);
#if (TIMER_TEST_MOD == __TIMER_TEST_MOD6)
{
gliethttp_timer->thread_run = 0;
wake_up(&gliethttp_timer->waitQ);
//如果在等待,那么唤醒timer_thread,让他去检测while(gliethttp_timer->thread_run)
while(gliethttp_timer->thread_quited == 0)
{
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
printk("Q");
}
}
#endif
printk(KERN_DEBUG"/nGoodbye, timer test/n");
}
module_init(init_gliethttp_timer);
module_exit(cleanup_gliethttp_timer)
====================================
Makefile中内容
obj-m:=gliethttp_timer.o
然后执行:
make -C /lib/modules/`uname -r`/build M=`pwd` modules
即可编译生成出
gliethttp_timer.ko
然后insmod
gliethttp_timer.ko
即可
【gliethttp.Leith】.
原文地址:http://blog.chinaunix.net/u1/38994/showart_1130557.html
附件为:gliethttp_timer.tar.bz2
- 内核sem、wait_queue_head_t、timer和kernel_thread使用驱动范例
- 内核sem、wait_queue_head_t、timer和kernel_thread使用驱动范例
- wait_queue_head_t 使用
- linux设备驱动开发中内核线程和timer的使用
- 关于内核线程(kernel_thread)
- linux内核函数kernel_thread
- 内核红黑树使用范例
- 内核timer使用
- 内核timer使用
- 内核线程函数kernel_thread解析
- 等待队列wait_queue_head_t使用
- wait_queue_head_t和wait_queue_t 联系
- wait_queue_head_t和wait_queue_t
- linux内核与驱动-驱动程序范例
- SEM和SEM如何互相帮助?
- kernel_thread
- Linux内核Timer使用注意事项
- 说说内核线程(kthread_create 和 kernel_thread的区别就在于前者多加了个链表)
- Game UI Studio [the beginning]
- Linux 用户态与内核态的交互
- ASP的字符串处理函数
- 数据库的索引,mysql中的索引|||如何在mysql中对text字段加索引?|||mysql数据库中的字段在什么情况下加索引?|||高手请进:text字段不能做索引,有无其他方法?|||该建那个字段
- Microsoft SQL Server之数据库存档
- 内核sem、wait_queue_head_t、timer和kernel_thread使用驱动范例
- c++程序处理过程
- 十六进制数的减法问题
- 动态数组C语言实现
- poj1125 Floyd-Warshall算法
- 编写整数字符串转化函数(不用itoa与atoi)
- 浅析sys_socket创建socket的简易流程
- ASCII码表在线查询(1.0 beta 1)
- 浅析ethx网卡发送函数sys_write简易流程