打印

请教一个中断句柄的问题

[复制链接]
3072|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
definitely|  楼主 | 2009-2-17 15:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
os, ST, TI, IO, TE
首先,谢谢大家能够进来看我的这个问题。
我想请教一个问题:
代码:

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
;/*定时器0中断*/
Timer0_Handler  HANDLER Timer0_Exception

    END

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

问题:
为什么在UC/OS-II中添加3个中断句柄,而在一个while(1)的前后台系统中没有定义?
是不是该这样理解:
进入中断函数有两种方式,一种是C语言的,另一种是汇编语言的,汇编语言就采用了句柄的方式,而在汇编中采用的是在函数名前加_IRQ,来表示该函数为中断函数,两者是等同的作用。如果是这样的话,那用_IRQ方式的句柄,他在进入中断前处理的代码在哪里呢?是编译器自动生成的吗?怎样可以查看?是编译器处理的话,是不是不同的编译器处理的代码有或多或少的区别呢?
附:
用的是keil的编译环境。

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

相关帖子

沙发
Ice_River| | 2009-2-17 16:12 | 只看该作者

你需要理解的东西很多!

中断接口文件IRQ.INC:
NoInt EQU 0x80 //禁止IRQ中断
USR32Mode EQU 0x10 //用户模式
SVC32Mode EQU 0x13 //管理模式
SYS32Mode EQU 0x1f //系统模式
IRQ32Mode EQU 0x12 //中断模式
FIQ32Mode EQU 0x11 //快速中断模式
;引入的外部标号在这声明
//IMPORT表示引用外部的信息
IMPORT OSIntCtxSw ;任务切换函数//引用外部的函数
IMPORT OSIntExit ;中断退出函数
IMPORT OSTCBCur      ;当前任务堆栈指针
IMPORT OSTCBHighRdy   ;最高优先级任务堆栈指针
IMPORT OSIntNesting ;中断嵌套计数器
IMPORT StackUsr     ; 用户模式堆栈
IMPORT OsEnterSum     ;中断计数器

CODE32
AREA IRQ,CODE,READONLY
MACRO
$IRQ_Label HANDLER $IRQ_Exception_Function
EXPORT $IRQ_Label ; 输出的标号
IMPORT $IRQ_Exception_Function ; 引用的外部标号
$IRQ_Label
SUB LR, LR, #4 ; 计算返回地址  LR 保存用户模式PC 相当于PC-4
//进入中断后,它的返回地址该怎么计算呢,可以这样来理解,因为它的指令流水线是3级的,即执行进入中断函数时,PC已经指向欲取值的指令即当前执行的地址+8;当已进入中断时,LR里面装的是PC,所以要想中断返回到正确的地址处,就必须把LR-4。
STMFD SP!, {R0-R3, R12, LR} ; 保存任务环境
//这里面为什么只把R0-R3,R12,LR保存呢,其它不用吗,是这样的,我们可以从你装的ADS1.2目录下的PDF文件夹里面的ADS_DeveloperGuide_D.PDF文件的2.2就可以发现r4-r11装的是局部变量,在进行函数跳转时,编译器它会自动保护它们的。
MRS R3, SPSR ; 保存状态
STMFD SP, {R3, SP, LR}^ ; 保存用户状态的R3,SP,LR,注意不能回写 //前面一个SP是IRQ模式的,后面一个SP是用户模式的,为什么不能回写呢,如果你回写的话,那么它保存的是用户的SP,显然是不行的。不知这样理解对不对。{^} 代表用户模式下的寄存器将被保存
; 如果回写的是用户的SP,所以后面要调整SP
LDR R2, =OSIntNesting ; OSIntNesting++  //中断嵌套数+1
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是IRQ模式的,后面一个SP是用户模式的,为什么不能回写呢,如果你回写的话,那么它保存的是用户的SP,显然是不行的。不知这样理解对不对。
; 如果回写的是用户的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
END

这里有部分说明,多数是网上下载的,希望能帮你。

使用特权

评论回复
板凳
一朝成名| | 2009-2-17 16:21 | 只看该作者

哈哈,ice是uc-os行家阿

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

128

帖子

2

粉丝