天天看点

linux 汇编语言ldreq,请教一个中断句柄的问题 - ARM技术论坛-ARM嵌入式论坛-人气最火爆ARM学习论坛 - 21ic电子技术开发论坛...

首先,谢谢大家能够进来看我的这个问题。

我想请教一个问题:

代码:

NoInt       EQU 0x80

USR32Mode   EQU 0x10

SVC32Mode   EQU 0x13

SYS32Mode   EQU 0x1f

IRQ32Mode   EQU 0x12

FIQ32Mode   EQU 0x11

;引入的外部标号在这声明

IMPORT  OSIntCtxSw                      ;任务切换函数

IMPORT  OSIntExit                       ;中断退出函数

IMPORT  OSTCBCur

IMPORT  OSTCBHighRdy

IMPORT  OSIntNesting                    ;中断嵌套计数器

IMPORT  StackUsr

IMPORT  OsEnterSum

CODE32

PRESERVE8

AREA    IRQ,CODE,READONLY

MACRO

$IRQ_Label HANDLER $IRQ_Exception_Function

EXPORT  $IRQ_Label                      ; 输出的标号

IMPORT  $IRQ_Exception_Function         ; 引用的外部标号

$IRQ_Label

SUB     LR, LR, #4                      ; 计算返回地址

STMFD   SP!, {R0-R3, R12, LR}           ; 保存任务环境

MRS     R3, SPSR                        ; 保存状态

STMFD   SP, {R3, SP, LR}^               ; 保存用户状态的R3,SP,LR,注意不能回写

; 如果回写的是用户的SP,所以后面要调整SP

LDR     R2,  =OSIntNesting              ; OSIntNesting++

LDRB    R1, [R2]

ADD     R1, R1, #1

STRB    R1, [R2]

SUB     SP, SP, #4*3

MSR     CPSR_c, #(NoInt | SYS32Mode)    ; 切换到系统模式

CMP     R1, #1

LDREQ   SP, =StackUsr

BL      $IRQ_Exception_Function         ; 调用c语言的中断处理程序

;       MSR     CPSR_c, #(NoInt | SYS32Mode)    ; 切换到系统模式

LDR     R2, =OsEnterSum                 ; OsEnterSum,使OSIntExit退出时中断关闭

MOV     R1, #1

STR     R1, [R2]

BL      OSIntExit

LDR     R2, =OsEnterSum                 ; 因为中断服务程序要退出,所以OsEnterSum=0

MOV     R1, #0

STR     R1, [R2]

MSR     CPSR_c, #(NoInt | IRQ32Mode)    ; 切换回irq模式

LDMFD   SP, {R3, SP, LR}^               ; 恢复用户状态的R3,SP,LR,注意不能回写

; 如果回写的是用户的SP,所以后面要调整SP

LDR     R0, =OSTCBHighRdy

LDR     R0, [R0]

LDR     R1, =OSTCBCur

LDR     R1, [R1]

CMP     R0, R1

ADD     SP, SP, #4*3                    ;

MSR     SPSR_cxsf, R3

LDMEQFD SP!, {R0-R3, R12, PC}^          ; 不进行任务切换

LDR     PC, =OSIntCtxSw                 ; 进行任务切换

MEND

;

;

IRQ_Handler HANDLER IRQ_Exception

UART1_Handler HANDLER UART1_Exception

;

Timer0_Handler  HANDLER Timer0_Exception

END

个人理解:

这里是定义一个Handler的宏,该宏是用来做进入中断前的处理。

问题:

为什么在UC/OS-II中添加3个中断句柄,而在一个while(1)的前后台系统中没有定义?

是不是该这样理解:

进入中断函数有两种方式,一种是C语言的,另一种是汇编语言的,汇编语言就采用了句柄的方式,而在汇编中采用的是在函数名前加_IRQ,来表示该函数为中断函数,两者是等同的作用。如果是这样的话,那用_IRQ方式的句柄,他在进入中断前处理的代码在哪里呢?是编译器自动生成的吗?怎样可以查看?是编译器处理的话,是不是不同的编译器处理的代码有或多或少的区别呢?

附:

用的是keil的编译环境。

用没有人可以系统地讲解一下,谢谢大家了!