• os_cpu_a.asm


    在OS_CPU_A.ASM中,定义了开、关中断的方法,在uC/OS-II系统中有三种方法可以实现中断开关,而ARM只适用于模式三,即使用一个局部变量,在中断进入之间保存CPU状态,退出时候再恢复状态。
    OSStart()函数调用OSStartHighRdy()来使就绪态任务中优先级最高的任务开始运行,OSStartHighRdy()必须调用OSTaskSwHook(),调用完STaskSwHook()后,应该使OSRunning标志位为TRUE,最后再切换到最高优先级任务。此函数只是完成了高优先级任务寄存器的恢复,并没有保存当前任务的寄存器。
    OSCtxSw(),任务级切换;
    OSIntCtxSw(),中断级别的任务切换;
    异常处理程序

    ********************************************************************************************************
    ;                                           PUBLIC FUNCTIONS
    ;********************************************************************************************************
                                                                    ; External references
        EXTERN  OSRunning
        EXTERN  OSPrioCur
        EXTERN  OSPrioHighRdy
        EXTERN  OSTCBCur
        EXTERN  OSTCBHighRdy
        EXTERN  OSIntNesting
        EXTERN  OSIntExit
        EXTERN  OSTaskSwHook

                                                                    ; Functions declared in this file
        PUBLIC  OS_CPU_SR_Save
        PUBLIC  OS_CPU_SR_Restore
        PUBLIC  OSStartHighRdy
        PUBLIC  OSCtxSw
        PUBLIC  OSIntCtxSw
                                                                    ; Functions related to exception handling
        PUBLIC  OS_CPU_ARM_ExceptResetHndlr
        PUBLIC  OS_CPU_ARM_ExceptUndefInstrHndlr
        PUBLIC  OS_CPU_ARM_ExceptSwiHndlr
        PUBLIC  OS_CPU_ARM_ExceptPrefetchAbortHndlr
        PUBLIC  OS_CPU_ARM_ExceptDataAbortHndlr
        PUBLIC  OS_CPU_ARM_ExceptAddrAbortHndlr
        PUBLIC  OS_CPU_ARM_ExceptIrqHndlr
        PUBLIC  OS_CPU_ARM_ExceptFiqHndlr
        EXTERN  OS_CPU_ExceptHndlr

    ;********************************************************************************************************
    ;                                                EQUATES
    ;********************************************************************************************************
    ;根据CPSR的低8位设置I,F,T,及M[4:0]
    OS_CPU_ARM_CONTROL_INT_DIS        EQU  0xC0                     ; Disable both FIQ and IRQ
    OS_CPU_ARM_CONTROL_FIQ_DIS        EQU  0x40                     ; Disable FIQ
    OS_CPU_ARM_CONTROL_IRQ_DIS        EQU  0x80                     ; Disable IRQ
    OS_CPU_ARM_CONTROL_THUMB          EQU  0x20                     ; Set THUMB mode
    OS_CPU_ARM_CONTROL_ARM            EQU  0x00                     ; Set ARM mode
    OS_CPU_ARM_MODE_MASK              EQU  0x1F
    OS_CPU_ARM_MODE_USR               EQU  0x10                     ;用户模式   
    OS_CPU_ARM_MODE_FIQ               EQU  0x11                     ;FIQ模式
    OS_CPU_ARM_MODE_IRQ               EQU  0x12                     ;IRQ模式
    OS_CPU_ARM_MODE_SVC               EQU  0x13                     ;管理模式
    OS_CPU_ARM_MODE_ABT               EQU  0x17                     ;终止模式
    OS_CPU_ARM_MODE_UND               EQU  0x1B                     ;未定义模式
    OS_CPU_ARM_MODE_SYS               EQU  0x1F                     ;系统模式
    ;定义异常
    OS_CPU_ARM_EXCEPT_RESET           EQU  0x00
    OS_CPU_ARM_EXCEPT_UNDEF_INSTR     EQU  0x01
    OS_CPU_ARM_EXCEPT_SWI             EQU  0x02
    OS_CPU_ARM_EXCEPT_PREFETCH_ABORT  EQU  0x03
    OS_CPU_ARM_EXCEPT_DATA_ABORT      EQU  0x04
    OS_CPU_ARM_EXCEPT_ADDR_ABORT      EQU  0x05
    OS_CPU_ARM_EXCEPT_IRQ             EQU  0x06
    OS_CPU_ARM_EXCEPT_FIQ             EQU  0x07

    ;********************************************************************************************************
    ;                                      CODE GENERATION DIRECTIVES
    ;********************************************************************************************************
        RSEG CODE:CODE:NOROOT(2)
        CODE32


    ;*********************************************************************************************************
    ;                                  CRITICAL SECTION METHOD 3 FUNCTIONS
    ;采用ucos所提出的模式3来禁止中断和开中断,实现硬保护
    ; Description: Disable/Enable interrupts by preserving the state of interrupts.  Generally speaking you
    ;              would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
    ;              disable interrupts.  'cpu_sr' is allocated in all of uC/OS-II's functions that need to
    ;              disable interrupts.  You would restore the interrupt disable state by copying back 'cpu_sr'
    ;              into the CPU's status register.
    ;
    ;也就是说cpu_sr是一个局部变量,在进入中断之前使用它来保存状态,退出时再恢复
    ;
    ; Prototypes : OS_CPU_SR  OS_CPU_SR_Save    (void);
    ;              void       OS_CPU_SR_Restore (OS_CPU_SR  os_cpu_sr);
    ;
    ;
    ; Note(s)    : (1) These functions are used in general like this:
    ;
    ;                 void Task (void  *p_arg)
    ;                 {
    ;                                                               /* Allocate storage for CPU status register.            */
    ;                 #if (OS_CRITICAL_METHOD == 3)
    ;                      OS_CPU_SR  os_cpu_sr;
    ;                 #endif
    ;
    ;                          :
    ;                          :
    ;                      OS_ENTER_CRITICAL();                     /* os_cpu_sr = OS_CPU_SR_Save();                        */
    ;                          :
    ;                          :
    ;                      OS_EXIT_CRITICAL();                      /* OS_CPU_SR_Restore(cpu_sr);                           */
    ;                          :
    ;                          :
    ;                 }
    ;
    ;              (2) OS_CPU_SR_Restore() is implemented as recommended by Atmel's application note:
    ;
    ;                    "Disabling Interrupts at Processor Level"
    ;*********************************************************************************************************
    OS_CPU_SR_Save
        MRS     R0, CPSR                                            ;复制CPSR到R0
    OS_CPU_SR_Save_Loop
                                                                    ; Set IRQ and FIQ bits in CPSR to disable all interrupts
        ORR     R1, R0, #OS_CPU_ARM_CONTROL_INT_DIS
        
        ;RO中存放了CPSR,把#OS_CPU_ARM_CONTROL_INT_DIS和R0进行逻辑或运算,结果存放到R1中
        
        MSR     CPSR_c, R1
        
        ;传送R1的内容到CPSR,但是只修改CPSR中的控制位域[7:0]
        
        MRS     R1, CPSR                                            ; Confirm that CPSR contains the proper interrupt disable flags
        AND     R1, R1, #OS_CPU_ARM_CONTROL_INT_DIS
        CMP     R1,     #OS_CPU_ARM_CONTROL_INT_DIS
        BNE     OS_CPU_SR_Save_Loop                                 ; Not properly disabled (try again)
        BX      LR                                                  ; Disabled, return the original CPSR contents in R0

    OS_CPU_SR_Restore                                               ; See Note #2
        MSR     CPSR_c, R0
        BX      LR

    ;*********************************************************************************************************
    ;                                           START MULTITASKING
    ;                                       void OSStartHighRdy(void)
    ;
    ; Note(s) : 1) OSStartHighRdy() MUST:
    ;              a) Call OSTaskSwHook() then,
    ;              b) Set OSRunning to TRUE,
    ;              c) Switch to the highest priority task.
    ;;*********************************************************************************************************
    OSStartHighRdy
                                                                    ; Change to SYS mode
        MSR     CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
        LDR     R0, ?OS_Running                                     ; OSRunning = TRUE;
        MOV     R1, #1
        STRB    R1, [R0]
        ;LDR指令将存储器中一个32位的字数据传送到目的寄存器,而STR相反,STRB只是传输低8位
        LDR     R0, ?OS_TaskSwHook                                  ; OSTaskSwHook();
        MOV     LR, PC
        BX      R0
                                                                    ;    SWITCH TO HIGHEST PRIORITY TASK
        LDR     R0, ?OS_TCBHighRdy                                  ;    Get highest priority task TCB address
        LDR     R0, [R0]                                            ;    get stack pointer
        LDR     SP, [R0]                                            ;    switch to the new stack
        LDR     R0, [SP], #4                                        ;    pop new task's CPSR
        
        ;有些代码在这里写成 LDMFD   SP!,{R0}
        
        MSR     CPSR_cxsf, R0
        LDMFD   SP!, {R0-R12, LR, PC}                               ;    pop new task's context

    ;*********************************************************************************************************
    ;                         PERFORM A CONTEXT SWITCH (From task level) - OSCtxSw()
    ;                         任务级切换
    ; Note(s) : 1) OSCtxSw() is called in SYS mode with BOTH FIQ and IRQ interrupts DISABLED
    ;
    ;           2) The pseudo-code for OSCtxSw() is:
    ;              a) Save the current task's context onto the current task's stack
    ;              b) OSTCBCur->OSTCBStkPtr = SP;
    ;              c) OSTaskSwHook();
    ;              d) OSPrioCur             = OSPrioHighRdy;
    ;              e) OSTCBCur              = OSTCBHighRdy;
    ;              f) SP                    = OSTCBHighRdy->OSTCBStkPtr;
    ;              g) Restore the new task's context from the new task's stack
    ;              h) Return to new task's code
    ;
    ;           3) Upon entry:
    ;              OSTCBCur      points to the OS_TCB of the task to suspend
    ;              OSTCBCur指向即将挂起的任务,而OSTCBHighRdy指向即将恢复的任务
    ;              OSTCBHighRdy  points to the OS_TCB of the task to resume
    ;*********************************************************************************************************
    OSCtxSw
                                                                    ; SAVE CURRENT TASK'S CONTEXT
        STMFD   SP!, {LR}                                           ;     Push return address
        ;LR中其实是任务切换时对应的PC值
        STMFD   SP!, {LR}
        STMFD   SP!, {R0-R12}                                       ;     Push registers
        MRS     R0, CPSR                                            ;     Push current CPSR
        TST     LR, #1                                              ;     See if called from Thumb mode
        ORRNE   R0, R0, #OS_CPU_ARM_CONTROL_THUMB                   ;     If yes, Set the T-bit
        STMFD   SP!, {R0}
        ;至此,在堆栈中保存环境的任务已经完成
        
        LDR     R0, ?OS_TCBCur                                      ; OSTCBCur->OSTCBStkPtr = SP;
        LDR     R1, [R0]
        STR     SP, [R1]
        LDR     R0, ?OS_TaskSwHook                                  ; OSTaskSwHook();
        MOV     LR, PC
        BX      R0
        LDR     R0, ?OS_PrioCur                                     ; OSPrioCur = OSPrioHighRdy;
        LDR     R1, ?OS_PrioHighRdy
        LDRB    R2, [R1]
        STRB    R2, [R0]
        LDR     R0, ?OS_TCBCur                                      ; OSTCBCur  = OSTCBHighRdy;
        LDR     R1, ?OS_TCBHighRdy
        LDR     R2, [R1]
        STR     R2, [R0]
        LDR     SP, [R2]                                            ; SP = OSTCBHighRdy->OSTCBStkPtr;
                                                                    ; RESTORE NEW TASK'S CONTEXT
        LDMFD   SP!, {R0}                                           ;    Pop new task's CPSR
        MSR     CPSR_cxsf, R0
        LDMFD   SP!, {R0-R12, LR, PC}                               ;    Pop new task's context

    ;*********************************************************************************************************
    ;                     PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw()
    ;                     中断级的任务切换
    ; Note(s) : 1) OSIntCtxSw() is called in SYS mode with BOTH FIQ and IRQ interrupts DISABLED
    ;
    ;           2) The pseudo-code for OSIntCtxSw() is:
    ;              a) OSTaskSwHook();
    ;              b) OSPrioCur             = OSPrioHighRdy;
    ;              c) OSTCBCur              = OSTCBHighRdy;
    ;              d) SP                    = OSTCBHighRdy->OSTCBStkPtr;
    ;              e) Restore the new task's context from the new task's stack
    ;              f) Return to new task's code
    ;
    ;           3) Upon entry:
    ;              OSTCBCur      points to the OS_TCB of the task to suspend
    ;              OSTCBHighRdy  points to the OS_TCB of the task to resume
    ;
    ;            OSIntCtxSw()和OSCtxSw()相似,区别是OSIntCtxSw()是在ISR中被调用的,ISR已经保存了CPU的寄存器,
    ;            所以不需要再此保存寄存器的值
    ;*********************************************************************************************************
    OSIntCtxSw
        LDR     R0, ?OS_TaskSwHook                                  ; OSTaskSwHook();
        MOV     LR, PC
        BX      R0
        LDR     R0, ?OS_PrioCur                                     ; OSPrioCur = OSPrioHighRdy;
        LDR     R1, ?OS_PrioHighRdy
        LDRB    R2, [R1]
        STRB    R2, [R0]
        LDR     R0, ?OS_TCBCur                                      ; OSTCBCur  = OSTCBHighRdy;
        LDR     R1, ?OS_TCBHighRdy
        LDR     R2, [R1]
        STR     R2, [R0]
        LDR     SP, [R2]                                            ; SP = OSTCBHighRdy->OSTCBStkPtr;
                                                                    ; RESTORE NEW TASK'S CONTEXT
        LDMFD   SP!, {R0}                                           ;    Pop new task's CPSR
        MSR     CPSR_cxsf, R0
        LDMFD   SP!, {R0-R12, LR, PC}                               ;    Pop new task's context

    ;********************************************************************************************************
    ;                                        RESET EXCEPTION HANDLER
    ; 进入异常后,LR会指向下一条指令的地址,所以在压栈的时候,需要减去相应的值。
    ; 对于reset,svc,swi减去0,对于预取终止,irq,fiq减去4,对于数据中止和地址中止减去8
    ;********************************************************************************************************
    OS_CPU_ARM_ExceptResetHndlr
                                                                    ; LR offset to return from this exception:  0
                                                                    ;  (there is no way to return from a RESET exception)
        STMFD   SP!, {R0-R12, LR}                                   ; Push working registers
        MOV     R3, LR                                              ; Save link register
        MOV     R0, #OS_CPU_ARM_EXCEPT_RESET                        ; Set exception ID to OS_CPU_ARM_EXCEPT_RESET
        B            OS_CPU_ARM_ExceptHndlr                         ; Branch to global exception handler

    ;********************************************************************************************************
    ;                                UNDEFINED INSTRUCTION EXCEPTION HANDLER
    ;********************************************************************************************************
    OS_CPU_ARM_ExceptUndefInstrHndlr
                                                                    ; LR offset to return from this exception:  0
        STMFD   SP!, {R0-R12, LR}                                   ; Push working registers
        MOV     R3, LR                                              ; Save link register
        MOV     R0, #OS_CPU_ARM_EXCEPT_UNDEF_INSTR                  ; Set exception ID to OS_CPU_ARM_EXCEPT_UNDEF_INSTR
        B            OS_CPU_ARM_ExceptHndlr                         ; Branch to global exception handler

    ;********************************************************************************************************
    ;                                 SOFTWARE INTERRUPT EXCEPTION HANDLER
    ;********************************************************************************************************
    OS_CPU_ARM_ExceptSwiHndlr
                                                                    ; LR offset to return from this exception:  0
        STMFD   SP!, {R0-R12, LR}                                   ; Push working registers
        MOV     R3, LR                                              ; Save link register
        MOV     R0, #OS_CPU_ARM_EXCEPT_SWI                          ; Set exception ID to OS_CPU_ARM_EXCEPT_SWI
        B            OS_CPU_ARM_ExceptHndlr                         ; Branch to global exception handler

    ;********************************************************************************************************
    ;                                   PREFETCH ABORT EXCEPTION HANDLER
    ;********************************************************************************************************
    OS_CPU_ARM_ExceptPrefetchAbortHndlr
        SUB     LR, LR, #4                                          ; LR offset to return from this exception: -4
        STMFD   SP!, {R0-R12, LR}                                   ; Push working registers
        MOV     R3, LR                                              ; Save link register
        MOV     R0, #OS_CPU_ARM_EXCEPT_PREFETCH_ABORT               ; Set exception ID to OS_CPU_ARM_EXCEPT_PREFETCH_ABORT
        B            OS_CPU_ARM_ExceptHndlr                         ; Branch to global exception handler

    ;********************************************************************************************************
    ;                                     DATA ABORT EXCEPTION HANDLER
    ;********************************************************************************************************
    OS_CPU_ARM_ExceptDataAbortHndlr
        SUB     LR, LR, #8                                          ; LR offset to return from this exception: -8
        STMFD   SP!, {R0-R12, LR}                                   ; Push working registers
        MOV     R3, LR                                              ; Save link register
        MOV     R0, #OS_CPU_ARM_EXCEPT_DATA_ABORT                   ; Set exception ID to OS_CPU_ARM_EXCEPT_DATA_ABORT
        B            OS_CPU_ARM_ExceptHndlr                         ; Branch to global exception handler

    ;********************************************************************************************************
    ;                                    ADDRESS ABORT EXCEPTION HANDLER
    ;********************************************************************************************************
    OS_CPU_ARM_ExceptAddrAbortHndlr
        SUB     LR, LR, #8                                          ; LR offset to return from this exception: -8
        STMFD   SP!, {R0-R12, LR}                                   ; Push working registers
        MOV     R3, LR                                              ; Save link register
        MOV     R0, #OS_CPU_ARM_EXCEPT_ADDR_ABORT                   ; Set exception ID to OS_CPU_ARM_EXCEPT_ADDR_ABORT
        B            OS_CPU_ARM_ExceptHndlr                         ; Branch to global exception handler

    ;********************************************************************************************************
    ;                                  INTERRUPT REQUEST EXCEPTION HANDLER
    ;********************************************************************************************************
    OS_CPU_ARM_ExceptIrqHndlr
        SUB     LR, LR, #4                                          ; LR offset to return from this exception: -4
        STMFD   SP!, {R0-R12, LR}                                   ; Push working registers
        MOV     R3, LR                                              ; Save link register
        MOV     R0, #OS_CPU_ARM_EXCEPT_IRQ                          ; Set exception ID to OS_CPU_ARM_EXCEPT_IRQ
        B            OS_CPU_ARM_ExceptHndlr                         ; Branch to global exception handler

    ;********************************************************************************************************
    ;                               FAST INTERRUPT REQUEST EXCEPTION HANDLER
    ;********************************************************************************************************
    OS_CPU_ARM_ExceptFiqHndlr
        SUB     LR, LR, #4                                          ; LR offset to return from this exception: -4
        STMFD   SP!, {R0-R12, LR}                                   ; Push working registers
        MOV     R3, LR                                              ; Save link register
        MOV     R0, #OS_CPU_ARM_EXCEPT_FIQ                          ; Set exception ID to OS_CPU_ARM_EXCEPT_FIQ
        B            OS_CPU_ARM_ExceptHndlr                         ; Branch to global exception handler

    ;********************************************************************************************************
    ;                                       GLOBAL EXCEPTION HANDLER
    ;********************************************************************************************************
    OS_CPU_ARM_ExceptHndlr
        MRS     R1, SPSR                                            ; Save CPSR (i.e. exception's SPSR)
                                                                    ; DETERMINE IF WE INTERRUPTED A TASK OR ANOTHER LOWER PRIORITY EXCEPTION
                                                                    ;   SPSR.Mode = FIQ, IRQ, SVC, ABT, UND : Other exception
                                                                    ;   SPSR.Mode = SYS                     : Task
                                                                    ;   SPSR.Mode = USR                     : *unsupported state*
        AND     R2, R1, #OS_CPU_ARM_MODE_MASK                       ;   保留R1的低8位控制位
        CMP     R2,     #OS_CPU_ARM_MODE_SYS
        BNE     OS_CPU_ARM_ExceptHndlr_BreakExcept

    ;********************************************************************************************************
    ;                                  EXCEPTION HANDLER: TASK INTERRUPTED
    ;********************************************************************************************************
    OS_CPU_ARM_ExceptHndlr_BreakTask
        MRS     R2, CPSR                                            ; Save exception's CPSR
        MOV     R4, SP                                              ; Save exception's stack pointer
                                                                    ; Change to SYS mode & disable interruptions
        MSR     CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
                                                                    ; SAVE TASK'S CONTEXT ONTO TASK'S STACK
        STMFD   SP!, {R3}                                           ;   Push task's PC
        STMFD   SP!, {LR}                                           ;   Push task's LR
        STMFD   SP!, {R5-R12}                                       ;   Push task's R12-R5
        LDMFD   R4!, {R5-R9}                                        ;   Move task's R4-R0 from exception stack to task's stack
        STMFD   SP!, {R5-R9}
        TST     R3, #1                                              ;   See if called from Thumb mode
        ORRNE   R1, R1, #OS_CPU_ARM_CONTROL_THUMB                   ;   If yes, Set the T-bit
        STMFD   SP!, {R1}                                           ;   Push task's CPSR (i.e. exception SPSR)
                                                                    ; if (OSRunning == 1)
        LDR     R1, ?OS_Running
        LDRB    R1, [R1]
        CMP     R1, #1
        BNE     OS_CPU_ARM_ExceptHndlr_BreakTask_1
                                                                    ; HANDLE NESTING COUNTER
        LDR     R3, ?OS_IntNesting                                  ;   OSIntNesting++;
        LDRB    R4, [R3]
        ADD     R4, R4, #1
        STRB    R4, [R3]
        LDR     R3, ?OS_TCBCur                                      ;   OSTCBCur->OSTCBStkPtr = SP;
        LDR     R4, [R3]
        STR     SP, [R4]
    OS_CPU_ARM_ExceptHndlr_BreakTask_1
        MSR     CPSR_cxsf, R2                                       ; RESTORE INTERRUPTED MODE
        LDR     R1, ?OS_CPU_ExceptHndlr                             ; OS_CPU_ExceptHndlr();
        MOV     LR, PC
        BX      R1
                                                                    ; Adjust exception stack pointer. This is needed because
                                                                    ; exception stack is not used when restoring task context.
        ADD     SP, SP, #(14*4)
                                                                    ; Change to SYS mode & disable interruptions.
        MSR     CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
                                                                    ; Call OSIntExit(). This call MAY never return
                                                                    ;  if a ready task with higher priority than
                                                                    ;  the interrupted one is found.
        LDR     R0, ?OS_IntExit
        MOV     LR, PC
        BX      R0
                                                                    ; RESTORE NEW TASK'S CONTEXT
        LDMFD   SP!, {R0}                                           ;    Pop new task's CPSR
        MSR     CPSR_cxsf, R0
        LDMFD   SP!, {R0-R12, LR, PC}                               ;    Pop new task's context

    ;********************************************************************************************************
    ;                               EXCEPTION HANDLER: EXCEPTION INTERRUPTED
    ;********************************************************************************************************
    OS_CPU_ARM_ExceptHndlr_BreakExcept
        MRS     R2, CPSR                                            ; Save exception's CPSR
                                                                    ; Change to SYS mode & disable interruptions
        MSR     CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
                                                                    ; HANDLE NESTING COUNTER
        LDR     R3, ?OS_IntNesting                                  ;   OSIntNesting++;
        LDRB    R4, [R3]
        ADD     R4, R4, #1
        STRB    R4, [R3]
        MSR     CPSR_cxsf, R2                                       ; RESTORE INTERRUPTED MODE
        LDR     R3, ?OS_CPU_ExceptHndlr                             ; OS_CPU_ExceptHndlr();
        MOV     LR, PC
        BX      R3
                                                                    ; Change to SYS mode & disable interruptions
        MSR     CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
                                                                    ; HANDLE NESTING COUNTER
        LDR     R3, ?OS_IntNesting                                  ;   OSIntNesting--;
        LDRB    R4, [R3]
        SUB     R4, R4, #1
        STRB    R4, [R3]
        MSR     CPSR_cxsf, R2                                       ; RESTORE INTERRUPTED MODE
        LDMFD   SP!, {R0-R12, PC}^                                  ; Pull working registers and return from exception.

    ;*********************************************************************************************************
    ;                                     POINTERS TO VARIABLES
    ;*********************************************************************************************************
        DATA
    ?OS_Running:
        DC32    OSRunning
    ?OS_PrioCur:
        DC32    OSPrioCur
    ?OS_PrioHighRdy:
        DC32    OSPrioHighRdy
    ?OS_TCBCur:
        DC32    OSTCBCur
    ?OS_TCBHighRdy:
        DC32    OSTCBHighRdy
    ?OS_IntNesting:
        DC32    OSIntNesting
    ?OS_TaskSwHook:
        DC32    OSTaskSwHook
    ?OS_IntExit:
        DC32    OSIntExit
    ?OS_CPU_ExceptHndlr:
        DC32    OS_CPU_ExceptHndlr

        END
  • 相关阅读:
    WinAPI: midiOutReset 重置输出设备
    WinAPI: midiOutLongMsg 向输出设备发送一条系统专用的 MIDI 消息
    WinAPI: midiInStart 启动输入
    WinAPI: midiOutClose 关闭输出设备
    WinAPI: midiInStop 停止输入
    bootstrap居中
    设计模式之访问者模式
    zend framework 开发环境搭建及入门
    转:GIT GUI使用
    Asp web.config详解
  • 原文地址:https://www.cnblogs.com/pengwangguoyh/p/4446332.html
Copyright © 2020-2023  润新知