我是编写嵌入式驱动程序的新手,所以请帮助我。 以下模块应使用定时器中断来切换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