ARM体系结构与编程学习(十三)

本文深入讲解了ARM架构下的FIQ与IRQ中断处理机制,包括不可重入与可重入中断处理程序的设计,提供了详细的C语言及汇编语言实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

9.5 FIQ与IRQ异常中断处理程序

arm提供的FIQ与IRQ用于外部设备向CPU请求中断。

9.5.1 不可重入的IRQ/FIQ异常中断处理程序

;使用关键词_irq

__irq void IRQHandler (void)
{
    volatile unsigned int *base = (unsigned int *) 0x80000000;

    if (*base == 1)          // which interrupt was it?
    {
        C_int_handler();     // process the interrupt
    }
    *(base+1) = 0;           // clear the interrupt
}

;对应的汇编程序

IRQHandler PROC
        STMFD    sp!,{r0-r4,r12,lr}
        MOV      r4,#0x80000000
        LDR      r0,[r4,#0]
        SUB      sp,sp,#4
        CMP      r0,#1
        BLEQ     C_int_handler
        MOV      r0,#0
        STR      r0,[r4,#4]
        ADD      sp,sp,#4
        LDMFD    sp!,{r0-r4,r12,lr}
        SUBS     pc,lr,#4
        ENDP

;不使用关键词_irq

void IRQHandler (void)
{
    volatile unsigned int *base = (unsigned int *) 0x80000000;

    if (*base == 1)          // which interrupt was it?
    {
        C_int_handler();     // process the interrupt
    }
    *(base+1) = 0;           // clear the interrupt
}

;对应的汇编程序

IRQHandler PROC
        STMFD    sp!,{r4,lr}
        MOV      r4,#0x80000000
        LDR      r0,[r4,#0]
        CMP      r0,#1
        BLEQ     C_int_handler
        MOV      r0,#0
        STR      r0,[r4,#4]
        LDMFD    sp!,{r4,pc}
        END

可重入的IRQ/FIQ异常中断处理程序

1、将返回地址保存到IRQ的数据栈中

2、保存工作寄存器和SPSR_irq

3、清除中断标志位

4、将处理器切换到系统模式,重新使能IRQ/FIQ中断

5、保存用户模式的LR寄存器和被调用程序不保存的寄存器

6、调用C语言的IRQ/FIQ异常中断处理程序返回,恢复用户模式的寄存器,并禁止IRQ/FIQ

7、切换到IRQ模式,禁止中断

8、恢复工作组寄存器和寄存器LR_irq

9、从IRQ异常中断处理程序中返回

PRESERVE8

    AREA INTERRUPT, CODE, READONLY
    IMPORT C_irq_handler
IRQ
    SUB     lr, lr, #4        ; construct the return address
    STMFD   sp!, {lr}         ; and push the adjusted lr_IRQ
    MRS     r14, SPSR         ; copy spsr_IRQ to r14
    STMFD   sp!, {r12, r14}   ; save work regs and spsr_IRQ

    ; Add instructions to clear the interrupt here
    ; then re-enable interrupts.


MSR CPSR_c, #0x1F ; switch to SYS mode, FIQ and IRQ
                              ; enabled. USR mode registers
                              ; are now current.
    STMFD  sp!, {r0-r3, lr}   ; save lr_USR and non-callee
                              ; saved registers
    BL      C_irq_handler     ; branch to C IRQ handler.
    LDMFD   sp!, {r0-r3, lr}  ; restore registers
    MSR     CPSR_c, #0x92     ; switch to IRQ mode and disable
                              ; IRQs. FIQ is still enabled.

    LDMFD   sp!, {r12, r14}   ; restore work regs and spsr_IRQ
    MSR     SPSR_cf, r14
    LDMFD   sp!, {pc}^        ; return from IRQ.
    END

9.5.2 IRQ异常中断处理程序例程

;保存返回地址

     SUB LR,LR #4

     STMFD  SP!,{LR}

     ;保存SPSR及工作组寄存器R12

     MRS  R14,SPSR

     STMFD SP!,{R12,R14}

     ;读取中断控制器的基地址

     MOV  R12  , #IntBase

     ;读取优先级最高的中断源的优先级

     LDR R12 ,[R12,#IntLevel]

     ;使能中断

     MRS   R14,CPSR

     BIC   R14,R14,#0X80

     MSR   CPSR_c ,R14

     ;跳转到优先级最高的中断对应的中断处理程序

     LDR  PC, [PC,R12,LSR #2]

     ;加入一条NOP指令,实现跳转表的地址计算方法

     NOP

     ;中断处理程序地址表

     ;优先级为0的中断对应的中断处理程序地址

      DCD  Priority0Handler

     ;优先级为1的中断对应的中断处理程序地址

      DCD  Priority1Handler

     ;优先级为2的中断对应的中断处理程序地址

      DCD  Priority2Handler

    

     ;优先级为0的中断对应的中断处理程序

      Priority0Handler

      ;保存工作寄存器

      STMFD   SP!,[R0-R11]

      ;这里为中断处理程序的程序体

      ;...

      ;恢复工作寄存器

      LDMFD  SP!  ,{R0-R11}

      ;禁止中断

      MRS   R12,CPSR

      ORR   R12,R12

      MSR   CPSR_c, R12

      ;恢复SPSR和寄存器R12

       LDMFD  SP!, {R12,R14}

       MSR    SPSR_csxf, R14

       ;从优先级为0的中断程序返回

       LDMFD  SP!, {PC}^

      

     ;优先级为1的中断对应的中断处理程序地址

      Priority1Handler

      ;...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值