LCD實驗學習筆記(八):中斷

s3c2440有60箇中斷源(其中15個爲子中斷源)。函數

31個32位的通用寄存器,6個程序狀態寄存器。有6種工做模式(系統/用戶模式,快中斷模式,管理模式,數據訪問停止模式,中斷模式,未定指令停止模式)。每種模式都有16個通用寄存器和1(或2)個程序狀態寄存器。spa

R15(pc)是程序計數器,R14(lr)是鏈接寄存器,在異常時自動保存pc備份,r13(sp)是棧指針寄存器。指針

CPSR是當狀程序狀態寄存器。其[7:0]爲控制位,[7]爲中斷禁止位,[6]爲快中斷禁止位,[5]爲CPU狀態位,[4:0]爲工做模式位。,it

程序狀態寄存器(PSR)的F位[6]設爲1,禁用快速中斷(FRQ)。class

程序狀態寄存器(PSR)的I位[7]設爲1,禁用普通中斷(IRQ)。psr

SPSR程序狀態保存寄存器,用於在異常時保存CPSR,從異常返回時恢復CPSR。請求

中斷的處理過程:程序

1,中斷控制器聚集中斷信號告訴CPU;數據

2,CPU自動保存當前運行的環境,調用中斷服務程序ISR進行處理(lr=pc+4或+8,即當前指令地址的一下條;cpsr複製到spsr;pc值等於異常向量表中的地址,即轉去執行異常向量表中的指令);異常

3,ISR經過讀中斷控制器相關寄存器,識別哪一個中斷髮生了,進行相應處理;

4,清除中斷;

5,恢復被中斷的程序的運行環境(pc=lr-4或-8,spsr複製回cpsr),繼續執行。

 

s3c2440中斷控制器中有五個控制寄存器:中斷源等待寄存器(SRCPND),中斷模式寄存器(INTMOD),屏蔽寄存器(INTMSK),優先級寄存器(PRIORITY),中斷等待寄存器(INTPND)。

SRCPND寄存器各位對應不一樣的中斷,其中外部中斷EINT4-7共用bit4,EINT8-23共用bin5。各位初始值爲0,當中斷髮生時,對應位值改成1。

INTMOD寄存器各位用於標記該位對應的中斷是模式,0爲IRQ,1爲FRQ。只容許有一箇中斷設爲FRQ。初始值都爲0。

INIMSK寄存器各位標記該位對應中斷是否可用,0表示有效,1表示禁止。初始值都爲1,即禁止全部中斷。

PRIORITY寄存器用於設置6箇中斷優先權仲裁模塊的工做方式,主要用來設定各中斷優先策略。

INTPND寄存器的32位同一時刻最多隻容許有一個值爲1,這一位是有相就的中斷請求發生,且該中斷未被屏蔽,並且該中斷請求經過了優先仲裁。這個中斷請求將被送到CPU,CPU將跳轉到中斷服務程序執行。中斷服務程序能夠讀取INTPND或INTOFFSET寄存器(當INTPND中某位標記中斷請求發生了,INTOFFSET寄存器中的值爲0-31,標記INTPND的哪一位被置爲1了)的值,以肯定哪一個中斷髮生了。

有的幾個中斷共有一個SRCPND的中斷位,好比INT_AC97和INT_WDT共用INT_WDT_AC97中斷位。這種子中斷共15個。子中斷髮生時,先在INTSRCPND寄存器相應位置1,若是INTSUBMSK寄存器相應位未屏蔽(即該位爲0),則該中斷送到SRCPND寄存器。

23個外部中斷:

 EINTINT0-2三個寄存器用於設置23個外部中斷的觸發方式和過濾器是否有效。觸發方式有低電平、高電平、降低沿、上升沿、電平高低變化。

EINTFLT0-3三個寄存器用於設置外部中斷引腳的過濾參數。

EINTMASK寄存器用於設置23個外部中斷的屏蔽狀況,默認是禁用中斷的。

EINTPEND寄存器記錄着23個外部中斷哪個發生了。發生中斷的對應位置1。初始值爲0。但清除中斷位標記時要寫入1。

 

進入和退出IRQ、保存和恢復環境代碼:


 

HandleIRQ:
  sub lr, lr, #4 @ 計算返回地址
  stmdb sp!, { r0-r12,lr } @ 保存使用到的寄存器
              @ 注意,此時的sp是中斷模式的sp
              @ 初始值是上面設置的4096

  ldr lr, =int_return @ 設置調用IRQ_Handle函數後的返回地址
  ldr pc, =IRQ_Handle @ 調用中斷分發函數,在interrupt.c中
int_return:
  ldmia sp!, { r0-r12,pc }^ @ 中斷返回, ^表示將spsr的值複製到cpsr

中斷服務代碼示例:


/*interrupt registes*/
#define SRCPND (*(volatile unsigned long *)0x4A000000)
#define INTMOD (*(volatile unsigned long *)0x4A000004)
#define INTMSK (*(volatile unsigned long *)0x4A000008)
#define PRIORITY (*(volatile unsigned long *)0x4A00000c)
#define INTPND (*(volatile unsigned long *)0x4A000010)
#define INTOFFSET (*(volatile unsigned long *)0x4A000014)
#define SUBSRCPND (*(volatile unsigned long *)0x4A000018)
#define INTSUBMSK (*(volatile unsigned long *)0x4A00001c)

/*external interrupt registers*/
#define EINTMASK (*(volatile unsigned long *)0x560000a4)
#define EINTPEND (*(volatile unsigned long *)0x560000a8)

#define BIT_ALLMSK (0xffffffff)

//聲明50箇中斷服務函數指針

void (*isr_handle_array[50])(void);

//虛擬中斷服務

void Dummy_isr(void)
{
  while(1);
}

//初始化中斷

void init_irq(void)
{
  int i = 0;
  for (i = 0; i < sizeof(isr_handle_array) / sizeof(isr_handle_array[0]); i++)
  {
  isr_handle_array[i] = Dummy_isr;
  }

  INTMOD = 0x0; // 全部中斷都設爲IRQ模式
  INTMSK = BIT_ALLMSK; // 先屏蔽全部中斷

}

//中斷處理

void IRQ_Handle(void)
{
  unsigned long oft = INTOFFSET;
  //清中斷
  if (oft == 4)
    EINTPEND = 1<<7; //EINT4-7合用IRQ4,注意EINTPEND[3:0]保留未用,向這些位寫入1可能致使未知結果
  SRCPND = 1<<oft;
  INTPND = INTPND;

  /* 調用中斷服務程序 */   isr_handle_array[oft]();}

相關文章
相關標籤/搜索