ThreadX源码:Cortex-A7的tx_thread_irq_nesting_start(嵌套中断开始动作).s汇编代码分析

news/2024/9/21 12:17:56 标签: ThreadX, ARMv7, 嵌套中断, Cortex-A7, ARM内核

0 参考资料

Cortex M3权威指南(中文).pdf(可以参考ARM指令集用法)

1 前言

tx_thread_irq_nesting_start.s是用来实现Cortex-A7 IRQ嵌套中断的开始函数实现的汇编文件。

2 源码分析

源码如下:

1  IRQ_DISABLE     =       0x80                    // IRQ disable bit
2  MODE_MASK       =       0x1F                    // Mode mask
3  SYS_MODE_BITS   =       0x1F                    // System mode bits

4   .global  _tx_thread_irq_nesting_start
5   .type    _tx_thread_irq_nesting_start,function
6   _tx_thread_irq_nesting_start:
7   MOV     r3,lr                               // Save ISR return address
8   MRS     r0, CPSR                            // Pickup the CPSR
9   BIC     r0, r0, #MODE_MASK                  // Clear the mode bits
10 ORR     r0, r0, #SYS_MODE_BITS              // Build system mode CPSR
11 MSR     CPSR_c, r0                          // Enter system mode
12 STMDB   sp!, {r1, lr}                       // Push the system mode lr on the system mode stack
13 //   and push r1 just to keep 8-byte alignment
14 BIC     r0, r0, #IRQ_DISABLE                // Build enable IRQ CPSR
15 MSR     CPSR_c, r0                          // Enter system mode
16 #ifdef __THUMB_INTERWORK
17 BX      r3                                  // Return to caller
18 #else
19 MOV     pc, r3                              // Return to caller
20 #endif

代码逐行分析:

1  IRQ_DISABLE     =       0x80                    // IRQ disable bit
2  MODE_MASK       =       0x1F                    // Mode mask
3  SYS_MODE_BITS   =       0x1F                    // System mode bits

说明:

汇编中可以使用EQU或=指令来定义宏常量,编译器会将这些定义的符号替换为它们所指定的值。

4   .global  _tx_thread_irq_nesting_start

说明:

.global 用于定义全局符号,以便于被其他文件引用;.local 用于定义局部符号, 仅在当前文件使用。

5   .type    _tx_thread_irq_nesting_start,function

说明:

.type用于设置符号的type属性,可选值为function或object(函数或对象(如全局变量))

这里设置_tx_thread_irq_nesting_start的属性为函数,可以供其它文件调用。

6   _tx_thread_irq_nesting_start:

指示_tx_thread_irq_nesting_start函数入口。

7   MOV     r3,lr

功能:
将lr(程序链接寄存器(用来保存子程序返回地址))的值保存到寄存器R3。

8   MRS     r0, CPSR

功能:
将CPSR寄存器的值保存到R0寄存器,特殊的寄存器如CPSR和SPSR必须通过该指令读取。

9   BIC     r0, r0, #MODE_MASK 

清空模式选择位,将R0寄存器的低5bit(0x1F)清空。

1、指令格式
bic{条件}{S} Rd,Rn,operand
2、指令说明
该指令的效果是,根据operand哪个位为1,清除Rn对应的位,然后将结果存入Rd。

CPSR寄存器低5位为处理器模式选择位,定义如下:
在这里插入图片描述

10 ORR     r0, r0, #SYS_MODE_BITS 

构造模式选择位,将R0寄存器的低5bit(0x1F)全部置1,配置为系统模式。
ORR指令是逻辑“或”指令。

1、指令格式
orr{条件}{S} Rd,Rn,operand
2、指令说明
orr指令,将Rn的值与操作数operand按位逻辑”或”,结果存放到目的寄存器Rd 中。
或者说,根据operand哪个位为1,将Rn对应的位设置为1,然后将结果存入Rd。

11 MSR     CPSR_c, r0

将R0寄存器的值存入CPSR寄存器,进入系统模式。
功能:将R0寄存器的值保存到CPSR寄存器,特殊的寄存器如CPSR和SPSR必须通过该指令写入。

12 STMDB   sp!, {r1, lr}  

在系统模式下将lr、r1依次压栈,保证8字节对齐。
STMDB指令用于将寄存器压栈。
举例:

指令:stmdb sp!,{r0-r12,lr}
含义:sp = sp - 4,先压lr,sp =lr(即将lr中的内容放入sp所指的内存地址)。sp = sp - 4,再压r12,sp = r12。sp = sp - 4,再压r11,sp = r11…sp = sp - 4,最后压r0,sp = r0。

14 BIC     r0, r0, #IRQ_DISABLE

构造CPSR寄存器内容,也就是将IRQ使能位置0,使能IRQ。
相关寄存器描述如下:
在这里插入图片描述
在这里插入图片描述

15 MSR     CPSR_c, r0

将R0寄存器的值写入CPSR寄存器,进入使能IRQ的系统模式。

17 BX      r3 

执行结束,返回父函数。
如果编译器生成的代码使用Thumb指令集,则执行该语句。
BX指令:带状态切换的跳转指令

BX 指令跳转到指令中所指定的目标地址, 目标地址处的指令既可以是ARM 指令,也可以是Thumb指令。因为 BX 指令会根据 Rm的最低两位切换处理器的状态(ARM指令是4字节对齐,最低两位可以用作状态指示,如果最低两位是0,表示切换到ARM状态;Thumb指令是2字节对齐,最低一位可以用作指示,如果最低一位是1,表示切换到Thumb状态)

19 MOV     pc, r3 

将r3寄存器的值写入PC,返回父函数。
如果编译器生成的代码使用ARM指令集,则执行该语句。

3 总结

tx_thread_irq_nesting_start.s的主要功能就是在进入IRQ时,将模式切换到系统模式然后使能IRQ(硬件进入IRQ会自动失能IRQ),使得IRQ能够被嵌套。
这里有个关键操作,在系统模式下需要将进入中断前的LR压入系统模式栈区,以便后面退出中断时LR值恢复被中断打断,避免系统模式下进入子函数(使用BL指令会修改LR的值)后LR被修改无法返回父函数。


http://www.niftyadmin.cn/n/5668774.html

相关文章

【裸机装机系列】11.kali(ubuntu)-优化-扩展root分区存储空间

如果你在安装分区的时候选择的是“guided-use entire disk and set up LVM”,那自动分配的root分区的空间很小,需要手动进行扩容。由于是采用lvm来进行分区的,扩容就相对来说简单很多。 可以通过缩小/home分区的LVM一些空闲空间,而…

Redis基础数据结构之 Sorted Set 有序集合 源码解读

目录标题 Sorted Set 是什么?Sorted Set 数据结构跳表(skiplist)跳表节点的结构定义跳表的定义跳表节点查询层数设置 Sorted Set 基本操作 Sorted Set 是什么? 有序集合(Sorted Set)是 Redis 中一种重要的数据类型,…

Python用TOPSIS熵权法重构粮食系统及期刊指标权重多属性决策MCDM研究|附数据代码...

原文链接:https://tecdat.cn/?p37724 在当今世界,粮食系统的稳定性至关重要。尽管现有的全球粮食系统在生产和分配方面表现出较高的效率,但仍存在大量人口遭受饥饿以及诸多粮食安全隐患。与此同时,在学术领域,准确评估…

window批处理脚本:将本地的三个文件通过SCP传输到Linux设备上

文件名send_file.bat: echo off setlocal:: 提示用户输入远程IP地址 set /p remoteIpAddressplease input IP::: 定义本地文件名 set "localFile1111" set "localFile2222" set "localFile3333":: 获取本地文件的完整路径 set "…

攻防世界Web新手练习区题目(view_source到simple_php)WP

目录 view_source​ robots​ Training-WWW-Robots PHP2​ get_post​ backup​ cookie​ disabled_button​ simple_js​ xff_referer​ weak_auth​ command_execution​ simple_php​ view_source 获取在线场景后访问题目场景 在右键不管用的情况下&#xff0…

普元DWS - Linux下安装DWS标准版

1 前言 普元DWS全称是普元数据开发平台。 功能是对不同结构的数据进行转换处理,比如将MySQL的数据转换到达梦数据库中。 本文讲解如何在Linux下安装DWS标准版 2 DWS的版本 普元DWS有两个版本:微服务版和标准版。 微服务版是基于分布式部署的&#x…

Unity的Text组件中实现输入内容的渐变色效果

要在Unity的Text组件中实现输入内容的渐变色效果,默认的Text组件不直接支持渐变色。但是,你可以通过以下几种方式实现: ### 1. **使用Shader**来实现渐变效果 通过自定义Shader为Text组件创建一个渐变效果。这是一个常用的做法&#xff0…

新产品,推出 MLX90372GVS 第三代 Triaxis® 位置传感器 IC,适用于汽车和工业系统(MLX90372GVS-ACE-308)

Triaxis 旋转和线性位置传感器IC: MLX90372GVS-ACE-103 MLX90372GVS-ACE-108 MLX90372GVS-ACE-301 MLX90372GVS-ACE-200 MLX90372GVS-ACE-208 MLX90372GVS-ACE-303 MLX90372GVS-ACE-300 MLX90372GVS-ACE-350 MLX90372GVS-ACE-100 MLX90372GVS-ACE-101 MLX90372GVS-…