OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6043|回复: 1

imx6u start.S中 IRQ中断的问题

[复制链接]

5

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2015-10-30
在线时间
27 小时
发表于 2021-6-2 08:36:13 | 显示全部楼层 |阅读模式
10金钱
各位大神,小弟刚接触imx6u,看见裸机开发中的中断例程,start.S
/* IRQ中断!重点!!!!! */
IRQ_Handler:
    push {lr}                   /* 保存lr地址 */
    push {r0-r3, r12}           /* 保存r0-r3,r12寄存器 */

    mrs r0, spsr                /* 读取spsr寄存器 */
    push {r0}                   /* 保存spsr寄存器 */

    mrc p15, 4, r1, c15, c0, 0 /* 从CP15的C0寄存器内的值到R1寄存器中
                                * 参考文档ARM Cortex-A(armV7)编程手册V4.0.pdf P49
                                * Cortex-A7 Technical ReferenceManua.pdf P68 P138
                                */                          
    add r1, r1, #0X2000         /* GIC基地址加0X2000,也就是GIC的CPU接口端基地址 */
    ldr r0, [r1, #0XC]          /* GIC的CPU接口端基地址加0X0C就是GICC_IAR寄存器,
                                 * GICC_IAR寄存器保存这当前发生中断的中断号,我们要根据
                                 * 这个中断号来绝对调用哪个中断服务函数
                                 */
    push {r0, r1}               /* 保存r0,r1 */

    cps #0x13                   /* 进入SVC模式,允许其他中断再次进去 */

    push {lr}                   /* 保存SVC模式的lr寄存器 */
    ldr r2, =system_irqhandler  /* 加载C语言中断处理函数到r2寄存器中*/
    blx r2                      /* 运行C语言中断处理函数,带有一个参数,保存在R0寄存器中 */

    pop {lr}                    /* 执行完C语言中断服务函数,lr出栈 */
    cps #0x12                   /* 进入IRQ模式 */
    pop {r0, r1}               
    str r0, [r1, #0X10         /* 中断执行完成,写EOIR */

    pop {r0}                        
   msr spsr_cxsf, r0           /* 恢复spsr */
    pop {r0-r3, r12}            /* r0-r3,r12出栈 */
    pop {lr}                    /* lr出栈 */
    subs pc, lr, #4             /* 将lr-4赋给pc */






最后的画横线的部分


我们在进入中断的时候,ARM切换到了IRQ模式,
硬件会在进入中断的时候把用户模式的cpsr寄存器拷贝到IRQ模式的spsr
现在执行完毕了中断需要切换回来
只需要在IRQ模式下把spsr拷贝到自己的cpsr就可以了
上面的代码没有这一步啊,怎么从irq切换回去呢?


最佳答案

查看完整内容[请看2#楼]

这个问题我自己来回答吧, 从异常处理程序返回 要从异常处理程序返回,必须进行两个单独的操作: 1.从保存的 SPSR 中恢复 CPSR。 2.将返回地址写入 PC 寄存器。 在 ARM 体系结构中,这可以通过使用两类指令从异常中返回: ① RFE 指令: 它将链接寄存器和 SPSR 从当前模式堆栈弹出。 ② 其他会设置 PC 寄存器指令,并让该指令带有 S 后缀: 例如“ SUBS PC, LR, #offset” , 注意:“ S”表示从 SPSR 中恢复 CPSR。 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2015-10-30
在线时间
27 小时
 楼主| 发表于 2021-6-2 08:36:14 | 显示全部楼层

这个问题我自己来回答吧,
从异常处理程序返回
要从异常处理程序返回,必须进行两个单独的操作:
1.从保存的 SPSR 中恢复 CPSR。
2.将返回地址写入 PC 寄存器。
在 ARM 体系结构中,这可以通过使用两类指令从异常中返回:
① RFE 指令:
它将链接寄存器和 SPSR 从当前模式堆栈弹出。
② 其他会设置 PC 寄存器指令,并让该指令带有 S 后缀:
例如“ SUBS PC, LR, #offset” , 注意:“ S”表示从 SPSR 中恢复 CPSR。
如果异常处理程序入口,使用堆栈来保存现场,则它可以使用带有“ ^” 限定符的加载指令返回。例如,
异常处理程序可以使用以下命令在一条指令中返回:
LDMFD sp!, {pc} ^
LDMFD sp!, {R0-R12, pc} ^
在此示例中, ^限定符表示 SPSR 同时复制到 CPSR。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 19:43

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表