自学内容网 自学内容网

ThreadX源码:Cortex-A7的tx_thread_irq_nesting_end(嵌套中断结束动作).s汇编代码分析

0 参考资料

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

1 前言

tx_thread_irq_nesting_end.S是用来实现Cortex-A7 IRQ嵌套中断的结束函数实现的汇编文件。

2 源码分析

源码如下:

1.#ifdef TX_ENABLE_FIQ_SUPPORT
2.DISABLE_INTS    =       0xC0                    // Disable IRQ/FIQ interrupts
3.#else
4.DISABLE_INTS    =       0x80                    // Disable IRQ interrupts
5.#endif
6.MODE_MASK       =       0x1F                    // Mode mask
7.IRQ_MODE_BITS   =       0x12                    // IRQ mode bits

8.    .global  _tx_thread_irq_nesting_end
9.    .type    _tx_thread_irq_nesting_end,function
10._tx_thread_irq_nesting_end:
11.    MOV     r3,lr                               @ Save ISR return address
12.    MRS     r0, CPSR                            @ Pickup the CPSR
13.    ORR     r0, r0, #DISABLE_INTS               @ Build disable interrupt value
14.    MSR     CPSR_c, r0                          @ Disable interrupts
15.    LDMIA   sp!, {r1, lr}                       @ Pickup saved lr (and r1 throw-away for 
16.                                                @   8-byte alignment logic)
17.    BIC     r0, r0, #MODE_MASK                  @ Clear mode bits
18.    ORR     r0, r0, #IRQ_MODE_BITS              @ Build IRQ mode CPSR
19.    MSR     CPSR_c, r0                          @ Re-enter IRQ mode
20.#ifdef __THUMB_INTERWORK
21.    BX      r3                                  @ Return to caller
22.#else
23.    MOV     pc, r3                              @ Return to caller
24.#endif

代码逐行分析:

1.#ifdef TX_ENABLE_FIQ_SUPPORT
2.DISABLE_INTS    =       0xC0                    // Disable IRQ/FIQ interrupts
3.#else
4.DISABLE_INTS    =       0x80                    // Disable IRQ interrupts
5.#endif
6.MODE_MASK       =       0x1F                    // Mode mask
7.IRQ_MODE_BITS   =       0x12                    // IRQ mode bits

说明:

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

8.    .global  _tx_thread_irq_nesting_end

说明:

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

9.    .type    _tx_thread_irq_nesting_end,function

说明:

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

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

10._tx_thread_irq_nesting_end:

指示_tx_thread_irq_nesting_end函数入口。

11.    MOV     r3,lr                               @ Save ISR return 

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

12.    MRS     r0, CPSR

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

13.    ORR     r0, r0, #DISABLE_INTS

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

14.    MSR     CPSR_c, r0

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

15.    LDMIA   sp!, {r1, lr} 

在系统模式下r1、lr依次出栈,保证8字节对齐。
LDMIA指令用于将寄存器出栈。
用法如下:
在这里插入图片描述

16.    BIC     r0, r0, #MODE_MASK 
18.    ORR     r0, r0, #IRQ_MODE_BITS 

构造CPSR寄存器内容,首先将模式选择位清空,然后将模式设置为IRQ模式。
CPSR寄存器低5位为处理器模式选择位,定义如下:
在这里插入图片描述

19.    MSR     CPSR_c, r0 

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

21.    BX      r3

执行结束,返回父函数。
如果编译器生成的代码使用Thumb指令集,则执行该语句。
BX指令用法如下:
在这里插入图片描述

23.    MOV     pc, r3 

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

3 总结

tx_thread_irq_nesting_start.s的主要功能就是在完成了中断嵌套工作之后,将模式由系统模式切换到IRQ模式(切换到IRQ模式前使能IRQ)。
这里有个关键操作,就是将进入嵌套中断时保存在系统模式栈区的LR出栈,以便退出中断结束时返回中断打断点继续执行,LR仍然是打断前的值,否则系统模式下函数无法正常返回(LR存储了函数返回地址)。


原文地址:https://blog.csdn.net/kevin1499/article/details/141789337

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!