#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/time.h>
#include <linux/timer.h>
#define KERNELTIMER_WRITE_ADDR 0x378
#define TIME_STEP (2*HZ / 10)
typedef struct {
struct timer_list timer;
unsigned long led;
}__attribute__((packed)) KERNEL_TIMER_MANAGER;
static KERNEL_TIMER_MANAGER *ptrmng = NULL;
void kerneltimer_timeover (unsigned long arg);
void kerneltimer_registertimer (KERNEL_TIMER_MANAGER *pdata, unsigned long timeover)
{
init_timer (&(pdata->timer)); /*初始化 timer_list 结构*/
pdata->timer.expires = get_jiffies_64() + timeover;
pdata->timer.data = (unsigned long) pdata; /*指针地址转换为整数暂存*/
/*设置超时后处理函数,(unsigned long)型pdata变量超时后自动传入kerneltimer_timerover函数作为其参数*/
pdata->timer.function = kerneltimer_timeover;
add_timer (&(pdata->timer)); /*注册 timer 结构体*/
}
void kerneltimer_timeover (unsigned long arg)
{
KERNEL_TIMER_MANAGER *pdata = NULL;
if (arg) {
pdata = (KERNEL_TIMER_MANAGER *) arg;
outb ((unsigned char) (pdata->led & 0xFF), KERNELTIMER_WRITE_ADDR);
pdata->led = ~(pdata->led);
kerneltimer_registertimer(pdata, TIME_STEP);
}
}
int kerneltimer_init (void)
{
ptrmng = kmalloc (sizeof (KERNEL_TIMER_MANAGER), GFP_KERNEL);
if (ptrmng == NULL) return -ENOMEM;
memset (ptrmng, 0, sizeof (KERNEL_TIMER_MANAGER));
ptrmng->led = 0;
kerneltimer_registertimer (ptrmng, TIME_STEP);
return 0;
}
void kerneltimer_exit (void)
{
if (ptrmng != NULL) {
del_timer (&(ptrmng->timer));
kfree (ptrmng);
}
outb (0x00, KERNELTIMER_WRITE_ADDR);
}
module_init (kerneltimer_init);
module_exit (kerneltimer_exit);
MODULE_LICENSE ("Dual BSD/GPL");
欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) | Powered by Discuz! X3.2 |