|
我使用TC0编一个定时中断的驱动,RC比较的方法产生定时.每次中断用do_gettimeofday((struct timeval *) tv_head)获取时间,用户程序read()这个时间,打印出来.insmod时系统报错segmentation fault.在/proc/modules和/proc/devices里可以看到注册的这个设备,/proc/interrupts里看不到申请的中断.用result = request_irq(17,short_tl_interrupt ,SA_INTERRUPT,"tmr0-irq", NULL)申请的中断.TC0的ID给的是17,我就直接用了.请教!谢谢!
初始化函数:
#define TC0_ID 17
#define TC_IER_CPCS (AT91_REG)1<<4
#define TC_IDR_CPCS (AT91_REG)1<<4
#define TC_CMR_CPCTRG 0x4000 ///////////////////RC compare trigger enable
#define TC_CMR_TCCLKS 0x4 /////////////////////SCLK=32.768kHz
#define TC_RC_VALUE 0x8000
#define TC_CCR_CLKEN 0x1 ////////////////////clock enable
#define TC_CCR_CLKDIS 0x2 ////////////////////clock disable
#define TC_CCR_SWTRG 0x4 ////////////////////software trigger
#define AIC_SMR17_PRIOR 4 //////////////////////interrupt priority
#define AIC_IDCR_DIS (AT91_REG)1<<TC0_ID ////////////////interrupt disable
#define AIC_IECR_EN (AT91_REG)1<<TC0_ID ////////////////interrupt enable
#define AIC_ICCR_CLR (AT91_REG)1<<TC0_ID ////////////////clear interrupt flag
int short_init(void)
{
int result;
/* Set up owner pointers.*/
SET_MODULE_OWNER(&short_fops);
result = register_chrdev(0, "tmrint", &short_fops);
if (result < 0) {
printk(KERN_INFO "tmrint: can't get major number\n");
return result;
}
if (major == 0) major = result; /* dynamic */
short_buffer = __get_free_pages(GFP_KERNEL,0); /* never fails */
short_head = short_tail = short_buffer;
short_task.routine = (void (*)(void *)) short_do_tasklet;
short_task.data = NULL; /* unused */
short_irq = TC0_ID;
*(AT91C_AIC_IDCR) = AIC_IDCR_DIS;///////////////////////close interrupt
*(AT91C_TC0_CMR) = (AT91_REG)(TC_CMR_CPCTRG+TC_CMR_TCCLKS);
*(AT91C_TC0_RC) = (AT91_REG)TC_RC_VALUE;
*(AT91C_AIC_SMR17) = AIC_SMR17_PRIOR;
*(AT91C_AIC_ICCR) = AIC_ICCR_CLR;
/////////////////////////////////////////////////initialization
result = request_irq(short_irq,short_tl_interrupt ,SA_INTERRUPT,"tmr0-irq", NULL);
if (result) {
printk(KERN_INFO " can't get assigned irq %i\n",short_irq);
short_irq = -1;
}
else
{ ///////////////////////////////////////////open interrupt
printk(KERN_INFO " get assigned irq %i\n", short_irq);
*(AT91C_TC0_CCR) = (AT91_REG)TC_CCR_CLKEN;
*(AT91C_TC0_IER) = TC_IER_CPCS;
*(AT91C_AIC_IECR) = AIC_IECR_EN;
*(AT91C_TC0_CCR) = (AT91_REG)TC_CCR_SWTRG;
}
return 0;
} |
|