linux:如何修改定时器以发送合适的中断

时间:2014-08-28 13:51:45

标签: linux timer module interrupt

我是编写嵌入式驱动程序的新手,所以请帮助我。 以下模块应使用定时器中断来切换Atmel sam91-9260 MC上的Pin。 切换间隔必须介于4ms - 3ms之间。

#include "my-wdt.h"
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <asm/gpio.h>
#include <asm/uaccess.h>
#include <asm/irq.h>

#include <linux/interrupt.h>
#include <linux/io.h>

//#include <linux/delay.h>


#define WDT_PIN     AT91_PIN_PA23

#define IRQ_NUMB 2

#define TIMER_CONTROL_ITO_MSK 0x01
#define TIMER_CONTROL_CONT_MSK 0x02
#define TIMER_CONTROL_START_MSK 0x04
#define TIMER_CONTROL_STOP_MSK 0x08

#define TIMER_STATUS_TO_MSK 0x01
#define TIMER_STATUS_RUN_MSK 0x02

#define TIMER_BASE 0x100
#define TIMER_CONTROL_OFFSET 4
#define TIMER_STATUS_OFFSET 0 

static const char WDT_name[] = "my-WDT";

static int __init WDT_init(void);
static void __exit WDT_exit(void);

static irqreturn_t irq_handler(int irq, void *dummy, struct pt_regs * regs);

static char wdt_state = 0;


module_init (WDT_init);
module_exit (WDT_exit);


static int __init WDT_init(void){

    at91_set_gpio_output(WDT_PIN , 0x0);    //wdt
    at91_set_gpio_value(WDT_PIN, wdt_state );

    //do{ //testing wdt
    //  wdt_state = wdt_state ^ 0x01;
    //  at91_set_gpio_value(WDT_PIN, wdt_state );
    //  mdelay(4);
    //}while(1);

    if(! request_irq(IRQ_NUMB, irq_handler,0,WDT_name, NULL)){
        printk(KERN_INFO "%s: Driver successfull registred.\n",WDT_name);   
    }else{
        printk(KERN_INFO "%s: Can't register driver.\n",WDT_name);
        return -EIO;
    }

    //initialize timer
    enable_irq (IRQ_NUMB);
    writew(TIMER_CONTROL_ITO_MSK | TIMER_CONTROL_START_MSK | TIMER_CONTROL_CONT_MSK, TIMER_BASE+(TIMER_CONTROL_OFFSET));

    return 0;
}


static void __exit WDT_exit(void){
    at91_set_gpio_input(WDT_PIN , 0x01);

    free_irq(IRQ_NUMB, NULL);

    printk(KERN_INFO "%s: Driver successfull unregistred.\n", WDT_name);
    return;
}


static irqreturn_t irq_handler(int irq, void *dummy, struct pt_regs * regs){
    //printk(KERN_ALERT "Interrupt handler executed!\n");

    writew(0,TIMER_BASE+TIMER_STATUS_OFFSET); // clear interrupt flag
    wdt_state = wdt_state ^ 0x01;
    at91_set_gpio_value(WDT_PIN, wdt_state );

    return IRQ_HANDLED;
}


MODULE_AUTHOR("Pat");
MODULE_DESCRIPTION("WDT Driver");
MODULE_LICENSE("GPL");

我举了一个例子,如果出了什么问题请注意我。 如何将计时器设置为特定周期?

我自己找到了答案。我正在尝试这个: how-to-add-a-peridic-timer-callback-in-a-linux-kernel-module

THX to all

0 个答案:

没有答案