ARM非向量中断初始化程序和向量初始化程序

来源:互联网 发布:淘宝网刺客信条袖剑 编辑:程序博客网 时间:2024/06/05 03:36

;********************************************************
;* NAME    : 44BINIT.S         *
;* Version : 10.April.2000        *
;* Description:           *
;* C start up codes         *
;* Configure memory, Initialize ISR ,stacks   *
;* Initialize C-variables        *
;* Fill zeros into zero-initialized C-variables  *
;********************************************************

GET ..\inc\option.s
GET ..\inc\memcfg.s

;Memory Area
;GCS6 64M 16bit(8MB) DRAM/SDRAM(0xc000000-0xc7fffff)
;APP RAM=0xc000000~0xc7effff
;MON  RAM=0xc7f0000-0xc7fffff
;STACK    =0xc7ffa00    

;Interrupt Control
INTPND  EQU 0x01e00004  ;中断请求寄存器
INTMOD  EQU 0x01e00008  ;中断模式寄存器
INTMSK  EQU 0x01e0000c  ;中断屏蔽寄存器
I_ISPR  EQU 0x01e00020  ;中断IRQ矢量模式-未经处理的IRQ中断寄存器
I_CMST  EQU 0x01e0001c  ;中断IRQ矢量模式-当前主单元中辅单元和IRQ中断源的优先级

;Watchdog timer
WTCON  EQU 0x01d30000  ;看门狗寄存器

;Clock Controller
PLLCON  EQU 0x01d80000  ;时钟寄存器
CLKCON  EQU 0x01d80004
LOCKTIME EQU 0x01d8000c

;Memory Controller
REFRESH  EQU 0x01c80024  ;内存刷新寄存器

;BDMA destination register
BDIDES0  EQU 0x1f80008  ;BDM目标地址寄存器
BDIDES1  EQU 0x1f80028  ;BDMA目标地址寄存器

;Pre-defined constants   ;各种处理器模式定义
USERMODE EQU 0x10
FIQMODE  EQU 0x11
IRQMODE  EQU 0x12
SVCMODE  EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT  EQU 0xc0

;check if tasm.exe is used.
GBLL    THUMBCODE
[ {CONFIG} = 16
THUMBCODE SETL {TRUE}
  CODE32
|  
THUMBCODE SETL {FALSE}
]

[ THUMBCODE
  CODE32   ;for start-up code for Thumb mode
]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Vector Macro;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    MACRO
$HandlerLabel HANDLER $HandleLabel

$HandlerLabel
    sub     sp,sp,#4   ;decrement sp(to store jump address)
    stmfd   sp!,{r0}   ;PUSH the work register to stack(lr does't push because it return to original address)
    ldr     r0,=$HandleLabel ;load the address of HandleXXX to r0
    ldr     r0,[r0]    ;load the contents(service routine start address) of HandleXXX
    str     r0,[sp,#4]   ;store the contents(ISR) of HandleXXX to stack
    ldmfd   sp!,{r0,pc}   ;POP the work register and pc(jump to ISR)
    MEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    IMPORT |Image$$RO$$Limit| ;End of ROM code (=start of ROM data)
    IMPORT |Image$$RW$$Base| ;Base of RAM to initialise
    IMPORT |Image$$ZI$$Base| ;Base and limit of area
    IMPORT |Image$$ZI$$Limit| ;to zero initialise

    IMPORT  Main    ;The main entry of mon program

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Code Begin;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    AREA    Init,CODE,READONLY

    ENTRY
    b ResetHandler    ;for debug
    b HandlerUndef    ;handlerUndef
    b HandlerSWI    ;SWI interrupt handler
    b HandlerPabort    ;handlerPAbort
    b HandlerDabort    ;handlerDAbort
    b .       ;handlerReserved
    b HandlerIRQ
    b HandlerFIQ

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IMPORTANT NOTE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;If the H/W vectored interrutp mode is enabled, The above two instructions should                       ;
;be changed like below, to work-around with H/W bug of S3C44B0X interrupt controller.                   ;
; b HandlerIRQ  ->  subs pc,lr,#4                                                                       ;
; b HandlerIRQ  ->  subs pc,lr,#4                                                                       ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;中断向量表
VECTOR_BRANCH
    ldr pc,=HandlerEINT0 ;mGA 0x20
    ldr pc,=HandlerEINT1 ;
    ldr pc,=HandlerEINT2 ;
    ldr pc,=HandlerEINT3 ;
    ldr pc,=HandlerEINT4567 ;
    ldr pc,=HandlerTICK  ;mGA 0x34
b .
b .
    ldr pc,=HandlerZDMA0 ;mGB 0x40
    ldr pc,=HandlerZDMA1 ;
    ldr pc,=HandlerBDMA0 ;
    ldr pc,=HandlerBDMA1 ;
    ldr pc,=HandlerWDT  ;
    ldr pc,=HandlerUERR01 ;mGB 0x54
    b .
    b .
    ldr pc,=HandlerTIMER0 ;mGC 0x60
    ldr pc,=HandlerTIMER1 ;
    ldr pc,=HandlerTIMER2 ;
    ldr pc,=HandlerTIMER3 ;
    ldr pc,=HandlerTIMER4 ;
    ldr pc,=HandlerTIMER5 ;mGC 0x74
    b .
    b .
    ldr pc,=HandlerURXD0 ;mGD 0x80
    ldr pc,=HandlerURXD1 ;
    ldr pc,=HandlerIIC  ;
    ldr pc,=HandlerSIO  ;
    ldr pc,=HandlerUTXD0 ;
    ldr pc,=HandlerUTXD1 ;mGD 0x94
    b .
    b .
    ldr pc,=HandlerRTC  ;mGKA 0xa0
    b .
    b .
    b .
    b .
    b .      ;mGKA
    b .
    b .
    ldr pc,=HandlerADC     ;mGKB 0xc0
    b .      ;
    b .      ;
    b .      ;
    b .      ;
    b .      ;mGKB
    b .
    b .
    ldr pc,=EnterPWDN  ;0xe0=EnterPWDN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;向量中断的处理方法                                                                                      ;
;Example: HandlerADC HANDLE HandleADC 解为               ;
;HandlerADC      ;HandlerADC为中断向量表的入口            ;
;   sub     sp,sp,#4   ;将sp减少一个字节,使其在堆栈高端留出存储返回地址,因为pc在寄存器组中的   ;
;        ;的位置大于r0,出栈时装入的是栈的高端的内容         ;
;   stmfd   sp!,{r0}   ;保存r0                 ;
;   ldr     r0,=HandleADC  ;装载中断处理函数的指针             ;
;   ldr     r0,[r0]    ;装载中断处理函数的地址             ;
;   str     r0,[sp,#4]   ;将中断处理函数的地址存入刚才预留的位置,r0的上面        ;
;   ldmfd   sp!,{r0,pc}   ;出栈后,pc指向的既是中断处理函数的地址           ;
;                                                                                                       ;
; INTCON^2 == 0时,vector table使能                  ;
; 发生中断->HandlerADC->HandleADC(pISR_ADC,即:_ISR_STARTADDRESS+0x20);         ;                         
; 若要在程序中处理此中断,只要将中断服务函数的指针赋给pISR_ADC,如:pISR_ADC = (int)ADCIsr                   ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    LTORG

HandlerFIQ  HANDLER HandleFIQ
HandlerIRQ  HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI  HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort

HandlerADC  HANDLER HandleADC
HandlerRTC  HANDLER HandleRTC
HandlerUTXD1 HANDLER HandleUTXD1
HandlerUTXD0 HANDLER HandleUTXD0
HandlerSIO  HANDLER HandleSIO
HandlerIIC  HANDLER HandleIIC
HandlerURXD1 HANDLER HandleURXD1
HandlerURXD0 HANDLER HandleURXD0
HandlerTIMER5 HANDLER HandleTIMER5
HandlerTIMER4 HANDLER HandleTIMER4
HandlerTIMER3 HANDLER HandleTIMER3
HandlerTIMER2 HANDLER HandleTIMER2
HandlerTIMER1 HANDLER HandleTIMER1
HandlerTIMER0 HANDLER HandleTIMER0
HandlerUERR01 HANDLER HandleUERR01
HandlerWDT  HANDLER HandleWDT
HandlerBDMA1 HANDLER HandleBDMA1
HandlerBDMA0 HANDLER HandleBDMA0
HandlerZDMA1 HANDLER HandleZDMA1
HandlerZDMA0 HANDLER HandleZDMA0
HandlerTICK  HANDLER HandleTICK
HandlerEINT4567 HANDLER HandleEINT4567
HandlerEINT3 HANDLER HandleEINT3
HandlerEINT2 HANDLER HandleEINT2
HandlerEINT1 HANDLER HandleEINT1
HandlerEINT0 HANDLER HandleEINT0


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;非向量中断的处理                        ;
;如果I_ISPC的使用不正确,此时I_ISPR可能为零                     ;
;堆栈内容的变化                         ;
;                                                                                                       ;
;H sp |--|  |--|  |--|  |--|  sp |--|                                            ;
;  |  |  sp |  |   |  |   |ad|->pc |  |                                            ;
;  |  |     |  |  |r9|  |r9|->r9 |  |                                            ;
;L  |  |     |  |  sp |r8|  sp |r8|->r8 |  |                                            ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


IsrIRQ       ;using I_ISPR register.
    sub     sp,sp,#4   ;预留返回指针的存储位置
    stmfd   sp!,{r8-r9}  

    ldr     r9,=I_ISPR
    ldr     r9,[r9]    ;载入I_ISPR

cmp  r9, #0x0   ;If the IDLE mode work-around is used,r9 may be 0 sometimes.
beq  %F2     ;无可处理中断,返回

    mov     r8,#0x0    ;r8为偏移量,清零

0
    movs    r9,r9,lsr #1  ;从右向左逐位检验
    bcs     %F1
    add     r8,r8,#4   ;偏移量累加
    b     %B0   

1
    ldr     r9,=HandleADC  ;中断处理表的首址
    add     r9,r9,r8   ;计算中断处理表的入口地址 r9+r8,即装载中断处理函数的指针
    ldr     r9,[r9]    ;装载中断处理函数的地址
    str     r9,[sp,#8]   ;将中断处理函数的地址存入刚才预留的位置,r8和r9的上面
    ldmfd   sp!,{r8-r9,pc}  ;出栈后,pc指向的既是中断处理函数的地址

2
ldmfd sp!,{r8-r9}   ;恢复r8,r9
add  sp,sp,#4   ;恢复栈指针
subs pc,lr,#4   ;返回

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;复位中断处理函数                       ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ResetHandler
    ldr     r0,=WTCON      ;禁止看门狗
    ldr     r1,=0x0 
    str     r1,[r0]

    ldr     r0,=INTMSK
    ldr     r1,=0x07ffffff   ;禁止所有中断
    str     r1,[r0]

    ;以下三段设置时钟控制寄存器
   
    ldr r0,=LOCKTIME
    ldr r1,=0xfff  
    str r1,[r0]

    [ PLLONSTART
  ldr r0,=PLLCON   ;temporary setting of PLL
  ldr r1,=((M_DIV<<12)+(P_DIV<<4)+S_DIV)
  str r1,[r0]
    ]

    ldr     r0,=CLKCON  
    ldr     r1,=0x7ff8      ;All unit block CLK enable
    str     r1,[r0]

;****************************************************
;change BDMACON reset value for BDMA                *
;****************************************************

    ldr     r0,=BDIDES0      
    ldr     r1,=0x40000000  ;BDIDESn reset value should be 0x40000000 
    str     r1,[r0]

    ldr     r0,=BDIDES1     
    ldr     r1,=0x40000000  ;BDIDESn reset value should be 0x40000000 
    str     r1,[r0]    ;将 BDMA目标地址设置为0x40000000

    ;****************************************************
    ;设定存储器控制寄存器                 * 
    ;****************************************************
    ldr     r0,=SMRDATA
    ldmia   r0,{r1-r13}
    ldr     r0,=0x01c80000  ;BWSCON Address
    stmia   r0,{r1-r13}

    ;****************************************************
    ;初始化堆栈                     *
    ;****************************************************
    ldr     sp, =SVCStack  ;复位后位SVC模式
    bl     InitStacks

    ;****************************************************
    ;设置中断处理                *
    ;****************************************************
    ldr     r0,=HandleIRQ  ;This routine is needed
    ldr     r1,=IsrIRQ   ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c
    str     r1,[r0]

    ;****************************************************
    ;Copy and paste RW data/zero initialized data     *
    ;****************************************************
    LDR     r0, =|Image$$RO$$Limit| ; Get pointer to ROM data
    LDR     r1, =|Image$$RW$$Base| ; and RAM copy
    LDR     r3, =|Image$$ZI$$Base|
;Zero init base => top of initialised data
  
    CMP     r0, r1       ; Check that they are different
    BEQ     %F1
0
    CMP     r1, r3       ; Copy init data
    LDRCC   r2, [r0], #4     ;--> LDRCC r2, [r0] + ADD r0, r0, #4
    STRCC   r2, [r1], #4     ;--> STRCC r2, [r1] + ADD r1, r1, #4
    BCC     %B0
1
    LDR     r1, =|Image$$ZI$$Limit| ; Top of zero init segment
    MOV     r2, #0
2
    CMP     r3, r1       ;Zero init
    STRCC   r2, [r3], #4
    BCC     %B2

    [ :LNOT:THUMBCODE
  bl Main       ;Don't use main() because ......
  b .     
    ]

    [ THUMBCODE        ;for start-up code for Thumb mode
  orr lr,pc,#1
  bx lr
  CODE16
  bl Main      ;Don't use main() because ......
  b .
  CODE32
    ]

;****************************************************
;* The function for initializing stack    *
;****************************************************
InitStacks
;Don't use DRAM,such as stmfd,ldmfd......
;SVCstack is initialized before
;Under toolkit ver 2.50, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'

    mrs     r0,cpsr
    bic     r0,r0,#MODEMASK
    orr     r1,r0,#UNDEFMODE|NOINT
    msr     cpsr_cxsf,r1   ;UndefMode
    ldr     sp,=UndefStack

    orr     r1,r0,#ABORTMODE|NOINT
    msr     cpsr_cxsf,r1       ;AbortMode
    ldr     sp,=AbortStack

    orr     r1,r0,#IRQMODE|NOINT
    msr     cpsr_cxsf,r1       ;IRQMode
    ldr     sp,=IRQStack

    orr     r1,r0,#FIQMODE|NOINT
    msr     cpsr_cxsf,r1       ;FIQMode
    ldr     sp,=FIQStack

    bic     r0,r0,#MODEMASK|NOINT
    orr     r1,r0,#SVCMODE
    msr     cpsr_cxsf,r1       ;SVCMode
    ldr     sp,=SVCStack

;USER mode is not initialized.
    mov     pc,lr ;The LR register may be not valid for the mode changes.

;****************************************************
;* The function for entering power down mode  *
;****************************************************
;void EnterPWDN(int CLKCON);
EnterPWDN
    mov     r2,r0               ;r0=CLKCON
    ldr     r0,=REFRESH 
    ldr     r3,[r0]
    mov     r1, r3
    orr     r1, r1, #0x400000   ;self-refresh enable
    str     r1, [r0]

    nop     ;Wait until self-refresh is issued. May not be needed.
    nop     ;If the other bus master holds the bus, ...
    nop     ; mov r0, r0
    nop
    nop
    nop
    nop

;enter POWERDN mode
    ldr     r0,=CLKCON
    str     r2,[r0]

;wait until enter SL_IDLE,STOP mode and until wake-up
    mov     r0,#0xff
0   subs    r0,r0,#1
    bne     %B0

;exit from DRAM/SDRAM self refresh mode.
    ldr     r0,=REFRESH
    str     r3,[r0]
    mov     pc,lr

    LTORG

SMRDATA DATA
;*****************************************************************
;* Memory configuration has to be optimized for best performance *
;* The following parameter is not optimized.                     *
;*****************************************************************

;*** memory access cycle parameter strategy ***
; 1) Even FP-DRAM, EDO setting has more late fetch point by half-clock
; 2) The memory settings,here, are made the safe parameters even at 66Mhz.
; 3) FP-DRAM Parameters:tRCD=3 for tRAC, tcas=2 for pad delay, tcp=2 for bus load.
; 4) DRAM refresh rate is for 40Mhz.

    [ BUSWIDTH=16
  DCD 0x11111001 ;Bank0=OM[1:0], Bank1~Bank7=16bit
    | ;BUSWIDTH=32
  DCD 0x22222220 ;Bank0=OM[1:0], Bank1~Bank7=32bit
    ]
DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0
DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1
DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2
DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3
DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4
DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5
[ BDRAMTYPE="DRAM"
     DCD ((B6_MT<<15)+(B6_Trcd<<4)+(B6_Tcas<<3)+(B6_Tcp<<2)+(B6_CAN)) ;GCS6 check the MT value in parameter.a
     DCD ((B7_MT<<15)+(B7_Trcd<<4)+(B7_Tcas<<3)+(B7_Tcp<<2)+(B7_CAN)) ;GCS7
| ;"SDRAM"
  DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6
  DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7
]
DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) ;REFRESH RFEN=1, TREFMD=0, trp=3clk, trc=5clk, tchr=3clk,count=1019
DCD 0x10   ;SCLK power down mode, BANKSIZE 32M/32M
DCD 0x20   ;MRSR6 CL=2clk
DCD 0x20   ;MRSR7

ALIGN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;RW BEGIN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
AREA RamData, DATA, READWRITE

^ (_ISR_STARTADDRESS-0x500)
   
UserStack  # 256 ;c1(c7)ffa00
SVCStack  # 256 ;c1(c7)ffb00
UndefStack  # 256 ;c1(c7)ffc00
AbortStack  # 256 ;c1(c7)ffd00
IRQStack  # 256 ;c1(c7)ffe00
FIQStack  # 0 ;c1(c7)fff00


  ^ _ISR_STARTADDRESS
HandleReset  # 4
HandleUndef  # 4
HandleSWI  # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ  # 4
HandleFIQ  # 4

;Don't use the label 'IntVectorTable',
;because armasm.exe cann't recognize this label correctly.
;the value is different with an address you think it may be.
;IntVectorTable
HandleADC  # 4
HandleRTC  # 4
HandleUTXD1  # 4
HandleUTXD0  # 4
HandleSIO  # 4
HandleIIC  # 4
HandleURXD1  # 4
HandleURXD0  # 4
HandleTIMER5 # 4
HandleTIMER4 # 4
HandleTIMER3 # 4
HandleTIMER2 # 4
HandleTIMER1 # 4
HandleTIMER0 # 4
HandleUERR01 # 4
HandleWDT  # 4
HandleBDMA1  # 4
HandleBDMA0  # 4
HandleZDMA1  # 4
HandleZDMA0  # 4
HandleTICK  # 4
HandleEINT4567 # 4
HandleEINT3  # 4
HandleEINT2  # 4
HandleEINT1  # 4
HandleEINT0  # 4   ;0xc1(c7)fff84

  END
44B0的启动代码

 

求教:很奇怪的指令,不知道什么意思

44b0x初始化代码基本上看懂了,不过对于非向量中断处理的地方,有几条指令一直没看懂,查arm编程手册也没有找到相关解释,所以又要来请教各位啦。
代码如下:
    bcs        %F1;
    add        r8,r8,#4
    b        %B0;
问题:
   bcs是什么指令? %表示什么意思? 还有,在44binit.s文件中,没有看到F1、B0的定义啊,这两个变量是在哪儿冒出来的呢???

另外,还有一个关于中断的问题。我看44b0x有i_ispc,f_ispc,i_ispr,但是没有f_ispr,是不是对于IRQ和FIQ中断,都是使用I_ISPR寄存器呢?类似于INTPND,不管是IRQ还是FIQ,只要有中断,相应位就置1。而对于中断服务,也不管是irq还是fiq,只要当前某个中断被服务,在i_ispr中相应位也置1.是这样的吗?

这个我知道一点
0,1是局部标号,%B是向后搜索局部标号, %F是向前搜索局部标号 。都是伪操作
I_ISPR寄存器各位表明发生了应该调用那个中断子程序。只能1位置位,其它位为0,比如说串口1发送中断发生,这时I_ISPR的
值为0X04,ldr    r9,=I_ISPR
          ldrr9,[r9] 两条指令后,r9的内容为0X4 ,
movs    r9,r9,lsr #1 r9内容右移一位
bcs    %F1  判断是否把置位是否转移到C位,
   add    r8,r8,#4 如果没有的R8加4
如果r9内容为0x04 需要右移3次 ,之后r8的内容为8 然后HandleADC的地址 加上r8的值 就是串口1发送中断的地址,这个地址的内容是中断子程序的地址

 

 

谢谢,不过还差一点不明白
程序中代码是这样的:
0   //局部变量
    movs    r9,r9,lsr #1;r9=r9>>1
    bcs        %F1//bcs表示条件跳转,c=1时跳转至1,但是这里怎么是只向前搜索呢,应该是只向后搜索啊,因为局部变量1在后面定义的啊???
    add        r8,r8,#4
    b        %B0//这里也是,B表示只向后搜索,但往后搜索不可能搜索到0啊,应该是向前搜索吧

1//局部变量
    ldr        r9,=HandleADC
    add        r9,r9,r8
    ldr        r9,[r9]//r9=中断处理入口地址
    str        r9,[sp,#8]//[sp+8] = r9,相当于把isr入口地址入栈
    ldmfd   sp!,{r8-r9,pc}//恢复r8,r9,同时pc=isr入口地址

其它的wjhtinger说得很明白了,我加上了注释,理解不对还请指正。
就是感觉%F和%B要换个位置。
bcs        %F1  应改为 bcs        %B1
b        %B0  应改为 b        %F0
不知是我哪里理解错了,呵呵

 

 



 

原创粉丝点击