最简陋的arm定时器1s定时程序
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include //这个头文件里的__REG()宏返回的就是寄存器的虚拟地址,在下面程序里(驱动程序里用的都是虚拟地址,不能用物理地址)
#include
#include
#include
#define KERNEL_DEBUG
#define DEVICE_NAME "mytimer"
#define CB_MAJOR 232
#define TIMER_OUT GPIO_C12 //用一个GPIO口告诉外设定时到
static devfs_handle_t devfs_h;
char timer_out=0;
void initial_timer()
{ int bb;
//powermanagement MPLL M=0x52,P=2,S=3
//MPLLCON=0x00052023;//这句在系统启动后似乎不能加上,估计启动后不能重写这个寄存器
/*
bb=MPLLCON;//这里读到的值是5c040,若采用这个值则16和256分频后为48828.125Hz
printk("MPLLCO=%x\n",bb);
*/
//mux=11, 16分频
TCFG1=0x00000003;
//prescalor=256
TCFG0=0x000000FF;
TCNTB0=0xBEBC;//48828
TCMPB0=0xBEBC/2;
bb=TCON;
TCON=bb|0x2;//set the manual update bit
bb=TCON;
TCON=bb|0x4;//set the inverter bit
//start timer0
bb=(bb&0xD)|0x9;//reset manual update bit,set the start bit and reload bit
TCON=bb;
}
//以下几个接口都是空壳
static ssize_t timer_read(struct file *file,char *buffer,size_t count,loff_t *ppos)
{ return 0;
}
static ssize_t timer_write(struct file *file, const char *buffer, size_t count)
{
return 0;
}
static int timer_ioctl(struct inode *inode, struct file *file ,unsigned int cmd, unsigned long arg)
{
return 0;
}
//发生中断时执行此函数
static void timer_irq(int irq,void *dev_id,struct pt_regs *reg)
{
int found=0;
printk("into the ISR\n");
if(irq==IRQ_TIMER0)
{ printk("time out irq%d",irq);
found=1;
}
if(!found)
{
printk("Bad irq%d",irq);
return;
}
if(timer_out==0)
{ timer_out=1;
write_gpio_bit(TIMER_OUT,0);
}
else
{ timer_out=0;
write_gpio_bit(TIMER_OUT,1);
}
}
static struct file_operations timer_fops={
owner: THIS_MODULE,
write: timer_write,
//poll: timer_select,
read: timer_read,
ioctl: timer_ioctl,
};
//整个驱动的初始化入口
static int __init timer_init(void)
{
int ret;
ret=register_chrdev(CB_MAJOR,DEVICE_NAME,&timer_fops);
printk("get to timer!\n");
set_gpio_ctrl(GPIO_MODE_OUT|GPIO_PULLUP_EN|TIMER_OUT);
write_gpio_bit(TIMER_OUT,1);
initial_timer();
printk("after initial_timer()\n");
if(ret<0)
{
printk(DEVICE_NAME" can't register major number\n");
return ret;
}
//关联中断和中断函数
if(request_irq(IRQ_TIMER0,&timer_irq,SA_INTERRUPT,DEVICE_NAME,&timer_irq))
{
printk(DEVICE_NAME "can't request irqs\n");
return -1;
}
//关联设备和fops结构
devfs_h=devfs_register(NULL,DEVICE_NAME,DEVFS_FL_DEFAULT,CB_MAJOR,0,S_IFCHR|S_IRUSR|S_IWUSR,&timer_fops,NULL);
return 0;
}
static void __exit timer_exit(void)
{
devfs_unregister(devfs_h);
free_irq(IRQ_TIMER0,timer_irq);
unregister_chrdev(CB_MAJOR, DEVICE_NAME);
}
module_init(timer_init);
module_exit(timer_exit);
阅读(758) | 评论(0) | 转发(0) |