zoukankan      html  css  js  c++  java
  • ATMEL精妙的IRQ中断处理过程

    A: 从栈地址开始,栈顶为AT91SAM7S64的16K片内RAM尽头0x00204000
    IRQ_STACK_SIZE = 3*8*4
    FIQ_STACK_SIZE = 0x004
    ABT_STACK_SIZE = 0x004
    UND_STACK_SIZE = 0x004
    SVC_STACK_SIZE = 0x800
    SYS_STACK_SIZE = 0x400

    irq栈为什么用3*8*4=96B呢?因为irq最多8级嵌套,ARM字长4B,而3,是由于每次进栈均破坏了3个寄存器r0、spsr、lr,所以需要压栈保存的也就是3。计算十分精准,没有一个字浪费,这是AT第一牛X的地方。

    当irq发生时,下列操作处理器自动完成:
    1。r14(irq)=返回地址
    2。spsr(irq)=cpsr(中断发生前的模式)
    3。改cpsr,成模式为irq,禁止irq中断。
    4。设pc,跳转到0x00000018去

    下面看中断0x00000018指向的irq_handle代码:

    ;因为要继续调用函数,lr会被冲掉,所以压irq栈
    sub lr,lr,#4
    stmfd sp!,{lr}

    ;将r0和spsr压irq栈,因为下面用到r0,spsr
    mrs r14,spsr
    stmfd sp!,{r0,r14}

    ;写IVR,支持保护模式,普通模式无效
    ;释放NIRQ,清除保护模式下中断源
    ldr r14,=AT91C_BASE_AIC
    ldr r0,[r14,#AIC_IVR]
    str r14,[r14, #AIC_IVR]

    ;允许中断嵌套,由irq模式切换入svc模式
    msr cpsr_c, #ARM_MODE_SVC

    ;保存scratch和被使用到的寄存器、lr入svc堆栈
    stmfd sp!, {r1-r3, r12, r14}

    ;跳转到AIC_IVR指向的中断服务程序地址
    mov r14,pc
    bx r0

    ;恢复scratch、被用到的寄存器、lr
    ldmia sp!,{r1-r3, r12, r14}

    ;禁止irq中断嵌套,由svc切换到irq模式。
    msr cpsr_c,#I_BIT | ARM_MODE_IRQ

    ;写AIC_EOICR
    ldr r14,=AT91C_BASE_AIC
    str r14,[r14, #AIC_EOICR]

    ;恢复spsr、r0
    ldmia sp!,{r0, r14}
    msr spsr_cxsf, r14

    ;中断返回
    ldmia sp!, {pc}^

    以上就是全部,让我惊叹的是如上做法支持了中断嵌套,想了想,自己以前搞的东西还真是全部回避回去了,也就是说,以前各个中断并没有优先级区分,进了中断就关门i->I。中断服务程序执行完了再打开,优点是简单明了,缺点是中断服务程序必须迅速处理完.

  • 相关阅读:
    byte在计算机中的存储方式--Double.byteValue()的输出结果思考
    启动Eclipse时An internal error occurred during: "Initializing Java Tooling".错误
    java实现两个int数交换
    cmd编译运行java
    java配置环境变量
    使用jQuery获取session中存储的list集合
    搭建ssm框架,可实现登录和数据展示以及增删改查
    java 生成UUID
    jQuery serialize()方法获取不到数据,alert结果为空
    SpringMVC架构的项目,js,css等静态文件导入有问题
  • 原文地址:https://www.cnblogs.com/shangdawei/p/4538994.html
Copyright © 2011-2022 走看看