QT2410的timer一共四組,我這邊先略過timer詳細的操作步驟,相關資料在網路上都可以找得到,而timer範例程式碼可參考我之前寫的qt2410 bootloader
打開arch/arm/mach-qt2410/time2410.c,可看到如下程式碼
qt2410_time_init就是qt2410 timer初始化的程式碼擺放位置,而gettimeoffset是kernel提供給各個architecture要自訂的API
瞭解架構後就來塞程式碼吧,首先是initial的部份,initial要做三件事
(1)初始化timer0(我用timer0當系統時鐘,最小tick count 1us)
(2)註冊timer中斷(增加kernel tick count)
(3)開啟timer中斷
詳細程式碼如下所示
void __init qt2410_time_init (void)
{
unsigned long temp;
qt2410_timer_irq.handler = qt2410_timer_interrupt;
setup_irq(nTIMER0_INT, &qt2410_timer_irq);
temp=__raw_readl(rTCFG0);
temp|=249;
__raw_writel(temp,rTCFG0);
temp=__raw_readl(rTCFG1);
temp|=0x03;
__raw_writel(temp,rTCFG1);
__raw_writel(12,rTCNTB0);
temp=__raw_readl(rTCON);
temp|=(1<<1);
__raw_writel(temp,rTCON);
temp=__raw_readl(rTCON);
temp&=~(1<<1);
__raw_writel(temp,rTCON);
temp=__raw_readl(rTCON);
temp|=0x9;
__raw_writel(temp,rTCON);
INT_ENABLE(nTIMER0_INT);
}
而timer的中斷函式與註冊程式碼如下所示
static irqreturn_t qt2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
//timer_cnt++;
write_seqlock(&xtime_lock);
timer_tick(regs);
write_sequnlock(&xtime_lock);
return IRQ_HANDLED;
}
static struct irqaction qt2410_timer_irq =
{
.name = "QT2410 Timer Tick",
.flags = SA_INTERRUPT | SA_TIMER,
.handler = qt2410_timer_interrupt
};
至於gettimeoffset就參考4510的寫法,不需要大改
寫完之後,就可以試著用ICE去load vmlinux並執行,看看timer是否能正確處理timer interrupt
下圖是用ICE在timer interrupt設中斷的情況
留言