07
01

Linux porting on different platform HowTo(3)

QT2410的timer一共四組,我這邊先略過timer詳細的操作步驟,相關資料在網路上都可以找得到,而timer範例程式碼可參考我之前寫的qt2410 bootloader

打開arch/arm/mach-qt2410/time2410.c,可看到如下程式碼
  1. struct sys_timer qt2410_timer = {
  2.         .init           = qt2410_time_init,
  3.         .offset         = qt2410_gettimeoffset,
  4. };



qt2410_time_init就是qt2410 timer初始化的程式碼擺放位置,而gettimeoffset是kernel提供給各個architecture要自訂的API

瞭解架構後就來塞程式碼吧,首先是initial的部份,initial要做三件事
(1)初始化timer0(我用timer0當系統時鐘,最小tick count 1us)
(2)註冊timer中斷(增加kernel tick count)
(3)開啟timer中斷
詳細程式碼如下所示
  1. void __init qt2410_time_init (void) 
  2. { 
  3. unsigned long temp;
  4.  
  5. qt2410_timer_irq.handler = qt2410_timer_interrupt;
  6. setup_irq(nTIMER0_INT, &qt2410_timer_irq);
  7.  
  8.  
  9. temp=__raw_readl(rTCFG0);
  10. temp|=249;
  11. __raw_writel(temp,rTCFG0);
  12.  
  13. temp=__raw_readl(rTCFG1);
  14. temp|=0x03;
  15. __raw_writel(temp,rTCFG1);
  16.  
  17. __raw_writel(12,rTCNTB0);
  18.  
  19. temp=__raw_readl(rTCON);
  20. temp|=(1<<1);
  21. __raw_writel(temp,rTCON);
  22.  
  23. temp=__raw_readl(rTCON);
  24. temp&=~(1<<1);
  25. __raw_writel(temp,rTCON);
  26.  
  27. temp=__raw_readl(rTCON);
  28. temp|=0x9;
  29. __raw_writel(temp,rTCON);
  30.  
  31. INT_ENABLE(nTIMER0_INT);
  32. }


而timer的中斷函式與註冊程式碼如下所示
  1. static irqreturn_t qt2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  2. {                                                                                                                                       
  3.         //timer_cnt++; 
  4.         write_seqlock(&xtime_lock);                                                                                                                                         
  5.         timer_tick(regs);         
  6.         write_sequnlock(&xtime_lock);                                                                                                                           
  7.         return IRQ_HANDLED;
  8. }
  9.  
  10.  static struct irqaction qt2410_timer_irq =
  11.  {
  12.         .name           = "QT2410 Timer Tick",
  13.         .flags          = SA_INTERRUPT | SA_TIMER,
  14.         .handler        = qt2410_timer_interrupt
  15. };


至於gettimeoffset就參考4510的寫法,不需要大改

寫完之後,就可以試著用ICE去load vmlinux並執行,看看timer是否能正確處理timer interrupt
下圖是用ICE在timer interrupt設中斷的情況
標籤: embedded
評論: 0 | 引用: 0 | 閱讀: 4993
發表評論
暱 稱: 密 碼:
網 址: E - mail:
驗證碼: 驗證碼圖片 選 項:
頭 像:
內 容: