⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_cpu_a.s

📁 ucosii在AT91RM9200下运行程序
💻 S
📖 第 1 页 / 共 2 页
字号:
@              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:
    LDR     R0, =OSTaskSwHook                                   @ OSTaskSwHook();
    MOV     LR, PC
    BX      R0

    LDR     R0, =OSPrioCur                                      @ OSPrioCur = OSPrioHighRdy;
    LDR     R1, =OSPrioHighRdy
    LDRB    R2, [R1]
    STRB    R2, [R0]

    LDR     R0, =OSTCBCur                                       @ OSTCBCur  = OSTCBHighRdy;
    LDR     R1, =OSTCBHighRdy
    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
@********************************************************************************************************

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
    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, =OSRunning
    LDRB    R1, [R1]
    CMP     R1, #1
    BNE     OS_CPU_ARM_ExceptHndlr_BreakTask_1

                                                                @ HANDLE NESTING COUNTER
    LDR     R3, =OSIntNesting                                   @   OSIntNesting++;
    LDRB    R4, [R3]
    ADD     R4, R4, #1
    STRB    R4, [R3]

    LDR     R3, =OSTCBCur                                       @   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, =OSIntExit
    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, =OSIntNesting                                   @   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, =OSIntNesting                                   @   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.


    .ltorg

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -