【ARM】-IRQ 和 FIQ 异常中断处理程序的返回

news/2024/10/28 21:28:31/

文章目录

    • 处理流程
    • 示例
    • 代码实现

处理流程

通常处理器执行完当前指令后,查询 IRQ 中断引脚及 FIQ 中断引脚,并且查看系统是否允许 IRQ 中断及 FIQ中断。
如果有中断引脚有效,并且系统允许该中断产生,处理器将产生 IRQ 异常中断或 FIQ 异常中断。
当 IRQ 和 FIQ 异常中断产生时,程序计数器 PC 的值已经更新,它指向当前指令后面第 3 条指令(对于 ARM 系统来说它指向当前指令地址加 12 个字节的位置,对于 Thumb 指令来说,它指向当前指令加 6 个字节的位置)。
当 IRQ 和 FIQ 异常中断发生时,处理器将 PC-4 的值保存到异常模式下的寄存器 LR_mode 中,这时 LR_mode 中的值即为PC-4 ,即指向当前指令后的第二条指令。因此返回操作需要将 LR_mode - 4(指向当前指令的下一条指令) 赋给 PC,可以通过下面的指令来实现:

SUBS PC, LR, #4  // 注意 S ,指定了 S 意味着同时将SPSR 拷贝到 CPSR

该指令将寄存器 LR 中的值减 4 后,复制到程序计数器 PC 中,实现程序返回,同时将 SPSR_mode 寄存器内容复制到 CPSR 中。
当异常中断处理程序中使用了数据栈时,可以通过下面的指令在异常中断处理程序时保存被中断程序的执行现场,在退出异常中断处理程序时恢复被中断程序的执行现场。异常中断处理程序中使用的数据栈由用户提供。

subs lr, lr, #4
stmdb sp!, {r0-r12, lr}   // 保存现场 r0-r12 - reg_list
// user code
ldmia sp!, {r0-r12, pc}^  // 恢复现场 r0-r12 - reg_list

在上述指令中,reg_list 是异常中断处理程序中使用的寄存器列表。标识符 ^ 指示将 SPSR_mode 寄存器内容复制到 CPSR 寄存器中,该指令只能在特权模式下使用。

示例

在这里插入图片描述
1、假设在 instruction+0 指令执行完成后发生 irq/frq 异常
2、此时 PC 值 已经更新,指向 instruction+3
3、进入 irq/frq 异常后,LR_mode = PC -4,所以此时 LR 指向 instruction+2
4、irq/frq 异常处理完成之后,程序需要返回到 instruction+1 处执行,所以将此时的 LR_mode 寄存器的值 -4 赋给 PC。

代码实现

    .align 2.arm.weak IRQ_Handler.type IRQ_Handler, %functionIRQ_Handler:push {lr}                   /* 保存lr地址 */push {r0-r3, r12}           /* 保存r0-r3,r12寄存器 */mrs r0, spsr                /* 读取spsr寄存器 */push {r0}                   /* 保存spsr寄存器 */.if 0 /* on qemu platform it always return 0, i don't know why */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*/
.elseldr r1, =0x00a00000
.endifadd 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 */

http://www.ppmy.cn/news/700359.html

相关文章

LangChain大型语言模型(LLM)应用开发(三):Chains

LangChain是一个基于大语言模型(如ChatGPT)用于构建端到端语言模型应用的 Python 框架。它提供了一套工具、组件和接口,可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互&#x…

途乐证券|股票缩量下跌是什么意思?意味着什么?

投资者在进行股票投资时可能会遇到股票缩量下跌的情况,那么这是什么意思呢?股票缩量下跌意味着什么呢?下面途乐证券为大家准备了相关内容,以供参考。 股票缩量下跌是什么意思? 股票缩量下跌指的是股票的买卖有效成交在…

小米手环断连解决方案

一天24小时有23个半小时处于断连状态,收不到消息通知。崩溃~ 首先应用有一个自启动管理,我觉得我对自启动管理可能有误区, 我以为的自启动时小米运动app自己启动,自己就能运行,好像貌似不是这样。 接下来是华为手机的…

list转换为arrayList

1、区别&#xff1a;list是一个接口&#xff1b;array List是一个类 2、两者都是集合. 为什么要转换呢&#xff1f; 因为ArrayList 类型不安全&#xff0c;效率较低。 List一点安全&#xff0c;效率比ArrayList要高。 list转array list List<string> litt new List&l…

即时通讯系统集成开发

在即将开发或已有的应用系统中可以快速将信贸通即时通讯系统进行集成&#xff0c;统一用户资料&#xff0c;在线状态等&#xff0c;无需直接操作数据库&#xff0c;只需调用已经封装好的相关类函数和接口&#xff0c;即可进行相应的用户以及消息操作&#xff0c;保持业务数据安…

携手并进 | 有孚网络与NTT通信(中国)合作新进展

​近日&#xff0c;在广州日本工商俱乐部大型活动上&#xff0c;NTT通信系统&#xff08;中国&#xff09;有限公司&#xff08;以下简称“NTT通信&#xff08;中国&#xff09;”&#xff09;向与会的100多家日资企业代表推荐了&#xff0c;由NTT通信&#xff08;中国&#xf…

什么是拓扑

拓扑学是几何学的一个分支&#xff0c;但是这种几何学又和通常的平面几何、立体几何不同。通常的平面几何或立体几何研究的对象是点、线、面之间的位置关系以及它们的度量性质。拓扑学对于研究对象的长短、大小、面积、体积等度量性质和数量关系都无关。 举例来说&#xff0c;…

中思拓研究院简介

为响应中央号召&#xff0c;“要运用大数据提升国家治理现代化水平”&#xff0c;推动优化经济治理基础数据库&#xff0c;促进实现决策的科学化、治理的精准化、服务的高效化&#xff0c;2020年1月16日&#xff0c;在国家信息中心有关领导和众多银企领导的参与和见证下&#x…