青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

UCOS2移植到cortex-M0

經過別人在板子上幾天幾夜的測試,跑了6、7個任務同時開了4、5個中斷,CPU滿負荷。完全沒問題,已經用在產品上。
主要就修改一個文件os_cpu_a.asm和任務創建時堆棧初始化代碼。
花了兩天時間(以前沒接觸過cortex-m0也沒寫過匯編,多年沒接觸過單片機了)。
以下是os_cpu_a.asm。有不少的草稿代碼,應該不影響閱讀的,請自行忽略。
;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                               (c) Copyright 1992-2010, Micrium, Weston, FL
;                                          All Rights Reserved
;
;                               ARM Cortex-M0 Port (without OS extensions)
;
; File      : OS_CPU_A.ASM
; Version   : V2.86
; By        : Jean J. Labrosse
;
; For       : ARMv6M Cortex-M0 (without OS extensions)
; Mode      : Thumb2
; Toolchain : RealView Development Suite
;             RealView Microcontroller Development Kit (MDK)
;             ARM Developer Suite (ADS)
;             Keil uVision
;********************************************************************************************************
;********************************************************************************************************
;                                           PUBLIC FUNCTIONS
;********************************************************************************************************
    EXTERN  OSRunning                                           ; External references
    EXTERN  OSPrioCur
    EXTERN  OSPrioHighRdy
    EXTERN  OSTCBCur
    EXTERN  OSTCBHighRdy
    EXTERN  OSIntNesting
    EXTERN  OSIntExit
    EXTERN  OSTaskSwHook
    EXTERN  OS_CPU_ExceptHndlr
    EXTERN  OS_CPU_ExceptStkBase
    EXTERN  OS_CPU_CtxSw
    
    EXPORT  OS_CPU_SR_Save                                      ; Functions declared in this file
    EXPORT  OS_CPU_SR_Restore
    EXPORT  OSStartHighRdy
    EXPORT  OSCtxSw
    EXPORT  OSIntCtxSw
    EXPORT  OS_CPU_CM0_ExceptHndlr
;********************************************************************************************************
;                                                EQUATES
;********************************************************************************************************
CM0_SETPEND     EQU     0xE000E200
CM0_IRQ0SET     EQU     0xFFFFFFFF
CM0_THUMB_CTL     EQU     0x01000000
;********************************************************************************************************
;                                      CODE GENERATION DIRECTIVES
;********************************************************************************************************
    AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
REQUIRE8
PRESERVE8
        
;*********************************************************************************************************
;                                   CRITICAL SECTION METHOD 3 FUNCTIONS
;
; 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.
;
; Prototypes :     OS_CPU_SR  OS_CPU_SR_Save(void);
;                  void       OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
;
;
; Note(s)    : 1) These functions are used in general like this:
;
;                 void Task (void *p_arg)
;                 {
;                 #if OS_CRITICAL_METHOD == 3          /* Allocate storage for CPU status register */
;                     OS_CPU_SR  cpu_sr;
;                 #endif
;
;                          :
;                          :
;                     OS_ENTER_CRITICAL();             /* cpu_sr = OS_CPU_SaveSR();                */
;                          :
;                          :
;                     OS_EXIT_CRITICAL();              /* OS_CPU_RestoreSR(cpu_sr);                */
;                          :
;                          :
;                 }
;*********************************************************************************************************
OS_CPU_SR_Save
        MRS     R0, PRIMASK                 ; Set prio int mask to mask all (except faults)
        CPSID   I
        BX      LR
OS_CPU_SR_Restore
        MSR     PRIMASK, 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.
;
;           2) When tested with IAR EWARM, the processor reaches the startup code in handler mode.
;              Consequently, to re-enable interrupts, it is necessary to return from OSStartHighRdy()
;              as if returning from an exception.  The commented code at the end of this function
;              performs the 'normal' function return and MIGHT need to be substituted for the last three
;              lines of code in this function, which load the link register with the exception return
;              value and then return.
;*********************************************************************************************************
NVIC_INT_CTRL   EQU     0xE000ED04               ; interrupt control state register
NVIC_SHPR3      EQU     0xE000ED20               ; system priority register (2)
NVIC_PENDSV_PRI EQU     0x00FF0000               ; PendSV priority value (lowest)
NVIC_PENDSVSET  EQU     0x10000000               ; value to trigger PendSV exception
PendSV_Handler  PROC
                EXPORT  PendSV_Handler           
OS_CPU_PendSVHandler
    CPSID   I                                                   ; Prevent interruption during context switch
    MRS     R0, PSP                                             ; PSP is process stack pointer
    CMP     R0, #0X00
    BEQ     OS_CPU_PendSVHandler_nosave
;    CBZ     R0, OS_CPU_PendSVHandler_nosave                     ; Skip register save the first time
;    SUBS    R0, R0, #0x20                                       ; Save remaining regs r4-11 on process stack
;    STM     R0, {R4-R11}
MRS R1, MSP
MSR MSP, R0
MSR PSP, R1
MOV R0, R8
MOV R1, R9
MOV R0, R8
MOV R1, R9
PUSH {R0-R7}
MRS R0,MSP
MRS     R2, MSP                                             ; PSP is process stack pointer
MRS     R3, PSP                                             ; PSP is process stack pointer
MSR MSP, R3
MSR PSP, R2
;    PUSH    {R0-R7}
    LDR     R1, =OSTCBCur                                       ; OSTCBCur->OSTCBStkPtr = SP;
    LDR     R1, [R1]
    STR     R0, [R1]                                            ; R0 is SP of process being switched out
                                                                ; At this point, entire context of process has been saved
OS_CPU_PendSVHandler_nosave
    PUSH    {R14}                                               ; Save LR exc_return value
    LDR     R0, =OSTaskSwHook                                   ; OSTaskSwHook();
    BLX     R0
    POP     {R0}
;    MSR     LR, R0
    MOV     LR,  R0
;    POP     {R14}
    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     R0, [R2]                                            ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
;    LDM     R0, {R0-R7}                                        ; Restore r4-11 from new process stack
;    ADDS    R0, R0, #0x20
;    MSR     PSP, R0                                             ; Load PSP with new process SP
    LDR     R0, [R2]                                            ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
    ;LDM     R0, {R0-R7}                                        ; Restore r4-11 from new process stack
    ADDS    R0, R0, #0x20
    MSR     PSP, R0                                             ; Load PSP with new process SP
SUBS    R0, R0, #0X20
LDM     R0, {R0-R7}
    MOV     R8, R0
    MOV     R9, R1
    MOV     R10, R2
    MOV     R11, R3
    MOVS     R2, #0x04
    MOV     R0, LR
    ORRS    R0, R2 
    MOV     LR, R0
;    ORR     LR, LR, #0x04                                       ; Ensure exception return uses process stack
    CPSIE   I
    BX      LR                                                  ; Exception return will restore remaining context
ENDP
OSStartHighRdy
    ; set the PendSV exception priority
    LDR     r0, =NVIC_SHPR3
    LDR     r1, =NVIC_PENDSV_PRI
    LDR     r2, [r0,#0x00]       ; read
    ORRS    r1,r1,r2             ; modify
    STR     r1, [r0]             ; write-back
    MOVS    R0, #0                                              ; Set the PSP to 0 for initial context switch call
    MSR     PSP, R0
    LDR     R0, =OS_CPU_ExceptStkBase                           ; Initialize the MSP to the OS_CPU_ExceptStkBase
    LDR     R1, [R0]
    MSR     MSP, R1    
    LDR     R0, =OSRunning                                      ; OSRunning = TRUE
    MOVS    R1, #1
    STRB    R1, [R0]
    
    LDR     R0, =NVIC_INT_CTRL                                  ; Trigger the PendSV exception (causes context switch)
    LDR     R1, =NVIC_PENDSVSET
    STR     R1, [R0]
    CPSIE   I                                                   ; Enable interrupts at processor level
OSStartHang
    B       OSStartHang                                         ; Should never get here
    ; set the PendSV exception priority
    LDR     r0, =NVIC_SHPR3
    LDR     r1, =NVIC_PENDSV_PRI
    LDR     r2, [r0,#0x00]       ; read
    ORRS    r1,r1,r2             ; modify
    STR     r1, [r0]             ; write-back
    ; trigger the PendSV exception (causes context switch)
    LDR     r0, =NVIC_INT_CTRL
    LDR     r1, =NVIC_PENDSVSET
    STR     r1, [r0]
B .
    LDR     R0, __OS_TaskSwHook                                 ; OSTaskSwHook();
    BLX     R0
    LDR     R0, __OS_Running                                    ; OSRunning = TRUE;
    MOVS    R1, #1
    STRB    R1, [R0]
    
                                                                ; SWITCH TO HIGHEST PRIORITY TASK:
    LDR     R0, __OS_TCBHighRdy                                 ;   Get highest priority task TCB address,
    LDR     R1, [R0]                                            ;   Get stack pointer,
    LDR     R2, [R1]
    MSR     MSP, R2                                             ;   Switch to the new stack,
    
    POP    {R0-R7}                                              ;   Pop new task's R8-R11 (into R0-R3), R4-R7
    MOV     R8,  R0                                              
    MOV     R9,  R1
    MOV     R10, R2
    MOV     R11, R3    
        
                                                                ; NORMAL FUNCTION RETURN (see Note #2)
    ADD     SP, #0x10
    POP    {R0-R3}                                              ;   Pop new task's R12, PC, LR, PSR into (R0, R1, R2, R3, respectively)
    MOV     R12, R0
    MOV     LR,  R1
    MSR     PSR, R3
    
    PUSH   {R2}                                                 ;   Save PC
    
    SUB     SP, #0x1C                                           
    POP    {R0-R3}                                              ;   Pop new task's R0-R3
    ADD     SP, #0x0C
    
    CPSIE   I                                                   ;   Enable interrupts
    
    POP    {PC}                                                 ;   Pop new task's PC
    
                                                                ; EXCEPTION FUNCTION RETURN (see Note #2)
;   LDR     R0, =CM1_EXCEPTRTN                                  ; Load LR (R14) with exception return value.
;   MOV     LR,  R0
;
;   BX      LR                                                  ; Return, as if from exception.
   
    
;*********************************************************************************************************
;                                PERFORM A CONTEXT SWITCH (From task level)                               
;                                                OSCtxSw()                                                    
;
; Note(s) : 1) OSCtxSw() is called when OS wants to do a task context switch.
;
;           2) This function triggers an IRQ #0, which will perform the context switch.  The variable
;              OS_CPU_CtxSw is set to '1' to indicate that a context switch should be performed.
;*********************************************************************************************************
OSCtxSw
    LDR     R0, =NVIC_INT_CTRL                                  ; Trigger the PendSV exception (causes context switch)
    LDR     R1, =NVIC_PENDSVSET
    STR     R1, [R0]
    BX      LR
 ;   LDR     R0, __OS_CPU_CtxSw                                  ; OS_CPU_CtxSw = TRUE
 ;   MOVS    R1, #1
 ;   STRB    R1, [R0]
    
 ;   LDR     R0, =CM0_SETPEND                                    ; Trigger interrupt
 ;   LDR     R1, =CM0_IRQ0SET
 ;   STR     R1, [R0]
CPSID   I
SUB     SP,#0x10
PUSH    {R0-R3}
ADD     SP,#0x20
MRS     R3, xPSR
LDR     R2, =CM0_THUMB_CTL
ORRS    R3, R2
MOVS     R2, #0x01
;MOV R2, LR
MOV     R1, LR
ORRS    R2, R1
MOV R1, R2
MOV     R0, R12
PUSH    {R0-R3}
SUB     SP, #0x10
MOV R0, R8
MOV R1, R9
MOV R2, R10
MOV R3, R11
PUSH    {R0-R7}
;    LDR     R0, __OS_CPU_CtxSw                                  ; OS_CPU_CtxSw = TRUE
;    MOVS    R1, #1
;    STRB    R1, [R0]
    MRS     R0, MSP
    LDR     R1, __OS_TCBCur                                     ; OSTCBCur->OSTCBStkPtr = SP;
    LDR     R1, [R1]
    STR     R0, [R1]    
 
    LDR     R0, __OS_TaskSwHook                                 ; OSTaskSwHook();
    BLX     R0
;    POP    {R0}
;    MOV     LR, 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     R0, [R2]                                            ; SP = OSTCBHighRdy->OSTCBStkPtr;
    MSR     MSP, R0                                             
    
;    LDR     R0, __OS_CPU_CtxSw                                  ; OS_CPU_CtxSw = 0;
;    MOVS    R1, #0
;    STRB    R1, [R0] 
                                                               ; RESTORE TASK's CONTEXT
    POP    {R0-R7}                                              ;   Pop new task's R8-R11 (into R0-R3), R4-R7
    MOV     R8,  R0                                              
    MOV     R9,  R1
    MOV     R10, R2
    MOV     R11, R3  
ADD     SP, #0x10
    POP    {R0-R3}                                              ;   Pop new task's R12, PC, LR, PSR into (R0, R1, R2, R3, respectively)
    MOV     R12, R0
    MOV     LR,  R1
    MSR     PSR, R3
    
    PUSH   {R2}                                                 ;   Save PC
    
    SUB     SP, #0x1C                                           
    POP    {R0-R3}                                              ;   Pop new task's R0-R3
    ADD     SP, #0x0C 
    CPSIE   I                                                   ;   Enable interrupts
;CPSID   I
;    BX      LR
    POP    {PC}    
    NOP
;*********************************************************************************************************
;                             PERFORM A CONTEXT SWITCH (From interrupt level)                                
;                                               OSIntCtxSw()                                               
;
; Notes:    1) OSIntCtxSw() is called by OSIntExit() when it determines a context switch is needed as 
;              the result of an interrupt.
;
;           2) This function triggers an IRQ #0, which will perform the context switch.  The variable
;              OS_CPU_CtxSw is set to '1' to indicate that a context switch should be performed.
;*********************************************************************************************************
SysTick_Handler_bak      PROC
                EXPORT  SysTick_Handler_bak
                ;IMPORT  SysTick_Handler_Aux
                ;IMPORT  OSIntExit2  
                MOV R0, LR
                PUSH {R0}
                ;LDR     R0, =SysTick_Handler_Aux
                BLX     R0
                
                CPSID   I
                ;LDR     R0, =OSIntExit2
                BLX     R0
                CMP R0, #0X00
                BEQ HandlerReturn
; B     OSIntCtxSw
ADD     SP,#0x1C
POP     {R0}
MOVS     R2, #0x01
ORRS    R0, R2
PUSH    {R0}
SUB     SP,#0x1C
                POP {R0}
                MOV LR, R0
;; SUB     SP,#0x10
;; PUSH    {R0-R3}
;; ADD     SP,#0x20
;; MRS     R3, PSR
;; MOV R2, LR
;; MOV R1, LR
;; MOV     R0, R12
;; PUSH    {R0-R3}
;; SUB     SP, #0x10
MOV R0, R8
MOV R1, R9
MOV R2, R10
MOV R3, R11
PUSH    {R0-R7}
;    LDR     R0, __OS_CPU_CtxSw                                  ; OS_CPU_CtxSw = TRUE
;    MOVS    R1, #1
;    STRB    R1, [R0]
    MRS     R0, MSP
    LDR     R1, __OS_TCBCur                                     ; OSTCBCur->OSTCBStkPtr = SP;
    LDR     R1, [R1]
    STR     R0, [R1]    
 
MOV R0, LR
PUSH {R0}
    LDR     R0, __OS_TaskSwHook                                 ; OSTaskSwHook();
    BLX     R0
POP {R0}
MOV LR, 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     R0, [R2]                                            ; SP = OSTCBHighRdy->OSTCBStkPtr;
    MSR     MSP, R0  
    POP     {R0-R7}
    MOV     R8,R0
    MOV     R9,R1
    MOV     R10,R2
    MOV     R11,R3
    CPSIE   I
    BX LR
HandlerReturn
                POP {R0}
                MOV LR, R0
                CPSIE   I
                BX LR
                ENDP
OSIntCtxSw
    LDR     R0, =NVIC_INT_CTRL                                  ; Trigger the PendSV exception (causes context switch)
    LDR     R1, =NVIC_PENDSVSET
    STR     R1, [R0]
    BX      LR
 ;   LDR     R0, __OS_CPU_CtxSw                                  ; OS_CPU_CtxSw = TRUE
 ;  MOVS    R1, #1
 ;  STRB    R1, [R0]
    
 ;   LDR     R0, =CM0_SETPEND                                    ; Trigger interrupt
 ;   LDR     R1, =CM0_IRQ0SET
 ;   STR     R1, [R0]
 ;   BX      LR
CPSID   I
SUB     SP,#0x10
PUSH    {R0-R3}
ADD     SP,#0x20
MRS     R3, xPSR
MOV R2, LR
MOV R1, LR
MOV     R0, R12
PUSH    {R0-R3}
SUB     SP, #0x10
MOV R0, R8
MOV R1, R9
MOV R2, R10
MOV R3, R11
PUSH    {R0-R7}
;    LDR     R0, __OS_CPU_CtxSw                                  ; OS_CPU_CtxSw = TRUE
;    MOVS    R1, #1
;    STRB    R1, [R0]
    MRS     R0, MSP
    LDR     R1, __OS_TCBCur                                     ; OSTCBCur->OSTCBStkPtr = SP;
    LDR     R1, [R1]
    STR     R0, [R1]    
 
    LDR     R0, __OS_TaskSwHook                                 ; OSTaskSwHook();
    BLX     R0
;    POP    {R0}
;    MOV     LR, 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     R0, [R2]                                            ; SP = OSTCBHighRdy->OSTCBStkPtr;
    MSR     MSP, R0                                             
    
;    LDR     R0, __OS_CPU_CtxSw                                  ; OS_CPU_CtxSw = 0;
;    MOVS    R1, #0
;    STRB    R1, [R0] 
                                                               ; RESTORE TASK's CONTEXT
    POP    {R0-R7}                                              ;   Pop new task's R8-R11 (into R0-R3), R4-R7
    MOV     R8,  R0                                              
    MOV     R9,  R1
    MOV     R10, R2
    MOV     R11, R3  
ADD     SP, #0x10
    POP    {R0-R3}                                              ;   Pop new task's R12, PC, LR, PSR into (R0, R1, R2, R3, respectively)
    MOV     R12, R0
    MOV     LR,  R1
    MSR     PSR, R3
    
    PUSH   {R2}                                                 ;   Save PC
    
    SUB     SP, #0x1C                                           
    POP    {R0-R3}                                              ;   Pop new task's R0-R3
    ADD     SP, #0x0C 
    CPSIE   I                                                   ;   Enable interrupts
;    BX      LR
    POP    {PC}    
    NOP         
;*********************************************************************************************************
;                                         HANDLE EXTERNAL IRQ #0
;                                        OS_CPU_CM1_ExceptHndlr()                                            
;
; Note(s) : 1) This function handles external IRQ #0.  This port requires that this be the ONLY 
;              external IRQ (though multiple interrupt sources may be multiplexed onto the single vector
;              via an external controller).
;
;           2) A context switch is accomplished by triggering an IRQ from OSCtxSw().  If the exception
;              is going to be used for this purpose, the variable OS_CPU_CtxSw will have been assigned 
;              the value '1' in OSCtxSw().
;*********************************************************************************************************
OS_CPU_CM0_ExceptHndlr    
B .
    CPSID   I
                                                                ; SAVE CONTEXT ONTO TASK STACK:
    MOV     R0, R8                                              
    MOV     R1, R9
    MOV     R2, R10
    MOV     R3, R11
    PUSH   {R0-R7}                                              ;   Push task's R8-R11, R4-R7.
;    LDR     R0, __OS_CPU_CtxSw                                  ; if (OS_CPU_CtxSw == TRUE)
    LDRB    R1, [R0]
    CMP     R1, #1
    BEQ     OS_CPU_CM0_ExceptHndlr_CtxSw
    
    
;*********************************************************************************************************
;                                         HANDLE EXTERNAL IRQ #0
;                                     OS_CPU_CM0_ExceptHndlr_Except()                                            
;
; Note(s) : 1) This function handles external IRQ #0.  This port requires that this be the ONLY 
;              external IRQ (though multiple interrupt sources may be multiplexed onto the single vector
;              via an external controller).
;
;           2) The pseudo-code for OS_CPU_CM1_ExceptHndlr_Except() is:
;              a) Save registers r4-r11 on task stack (which is the current stack);
;              b) OSTCBCur->OSTCBStkPtr = SP;
;              c) OSIntNesting++;
;              d) SP = OS_CPU_ExceptStkBase;
;              e) OS_CPU_ExceptHndlr();
;              f) OSIntExit();
;              g) SP = OSTCBCur->OSTCBStkPtr;
;              h) Restore new task's R4-R11 from new task's stack;
;              i) Perform exception return which will restore R0-R3, R12, LR, PC, PSR.
;
;           3) On entry into this function:
;              a) OS_CPU_CtxSw == 0
;              b) The following have been saved on the task stack (by processor):
;                 xPSR, PC, LR, R12, R0-R3
;              c) The following have been saved on the task stack (by OS_CPU_CM1_ExceptHndlr):
;                 R8-R11, R4-R7
;              d) OSTCBCur points to the OS_TCB of the current task
;*********************************************************************************************************
OS_CPU_CM0_ExceptHndlr_Except
    LDR     R0, __OS_TCBCur                                     ;   OSTCBCur->OSTCBStkPtr = SP;
    LDR     R1,  [R0]
    MRS     R2,  MSP
    STR     R2,  [R1]
                                                                ; HANDLE NESTING COUNTER:
    LDR     R0, __OS_IntNesting                                 ;   OSIntNesting++;
    LDRB    R1, [R0]
    ADDS    R1, #1
    STRB    R1, [R0]
    LDR     R0, __OS_CPU_ExceptStkBase                          ; SP = OS_CPU_ExceptStkBase;
    LDR     R1, [R0]
    MSR     MSP, R1
    
    PUSH   {LR}                                                 ; Push exception return.
    
                                                                ; EXECUTE EXCEPTION HANDLER:
    LDR     R0, __OS_CPU_ExceptHndlr                            ;   OS_CPU_ExceptHndlr()
    BLX     R0
 
    LDR     R0, __OS_IntExit                                    ; OSIntExit()
    BLX     R0
    
    POP    {R0}                                                 ; Pop exception return.
    MOV     LR, R0
    LDR     R0, __OS_TCBCur                                     ; SP = OSTCBCur->OSTCBStkPtr;
    LDR     R1,  [R0]
    LDR     R2,  [R1]
    MSR     MSP,  R2
    
                                                                ; RESTORE TASK's CONTEXT
    POP    {R0-R7}                                              ;   Pop new task's R8-R11 (into R0-R3), R4-R7
    MOV     R8,  R0                                              
    MOV     R9,  R1
    MOV     R10, R2
    MOV     R11, R3    
    CPSIE   I
    BX      LR                                                  ; Exception return restores R0-R3, R12, LR, PC, PSR
    
;*********************************************************************************************************
;                                         EXECUTE CONTEXT SWTICH
;                                      OS_CPU_CM0_ExceptHndlr_CtxSw()                                            
;
; Note(s) : 1) OS_CPU_CM1_ExceptHndlr_CtxSw(), called from OS_CPU_CM1_ExceptHndlr(), is used to cause a
;              context switch, similar to the use of OSPendSV on a Cortex-M3.  Using the exception this way
;              means that context saving and restoring is identical whether it is initiated from a thread 
;              or occurs due to an interrupt or exception. 
;
;           2) The pseudo-code for OS_CPU_CM1_ExceptHndlr_CtxSw() is:
;              b) OSTCBCur->OSTCBStkPtr = SP;
;              c) OSTaskSwHook();
;              d) OSPrioCur    = OSPrioHighRdy;
;              e) OSTCBCur     = OSTCBHighRdy;
;              f) SP           = OSTCBHighRdy->OSTCBStkPtr;
;              g) Restore new task's R4-R11 from new task's stack;
;              h) OS_CPU_CtxSw = 0;
;              i) Perform exception return which will restore R0-R3, R12, LR, PC, PSR.
;
;           3) On entry into this function:
;              a) OS_CPU_CtxSw == 1
;              b) The following have been saved on the task stack (by processor):
;                 xPSR, PC, LR, R12, R0-R3
;              c) The following have been saved on the task stack (by OS_CPU_CM1_ExceptHndlr):
;                 R8-R11, R4-R7
;              d) OSTCBCur     points to the OS_TCB of the task to suspend
;                 OSTCBHighRdy points to the OS_TCB of the task to resume
;*********************************************************************************************************
OS_CPU_CM0_ExceptHndlr_CtxSw
    PUSH   {LR}
    LDR     R0, __OS_TaskSwHook                                 ; OSTaskSwHook();
    BLX     R0
    POP    {R0}
    MOV     LR, R0
    MRS     R0, MSP
    LDR     R1, __OS_TCBCur                                     ; OSTCBCur->OSTCBStkPtr = SP;
    LDR     R1, [R1]
    STR     R0, [R1]    
    
    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     R0, [R2]                                            ; SP = OSTCBHighRdy->OSTCBStkPtr;
    MSR     MSP, R0                                             
    
                                                                ; RESTORE NEW TASK's CONTEXT
    POP    {R0-R7}                                              ;   Pop new task's R8-R11 (into R0-R3), R4-R7
    MOV     R8,  R0                                              
    MOV     R9,  R1
    MOV     R10, R2
    MOV     R11, R3    
    
;    LDR     R0, __OS_CPU_CtxSw                                  ; OS_CPU_CtxSw = 0;
;    MOVS    R1, #0
;    STRB    R1, [R0] 
    
    CPSIE   I
    BX      LR                                                  ; Exception return restores R0-R3, R12, LR, PC, PSR
    
    NOP
    
;*********************************************************************************************************
;                                     POINTERS TO VARIABLES
;*********************************************************************************************************
__OS_CPU_CtxSw
    DCD     OS_CPU_CtxSw
__OS_CPU_ExceptStkBase
    DCD     OS_CPU_ExceptStkBase
    
__OS_CPU_ExceptHndlr
    DCD     OS_CPU_ExceptHndlr
__OS_TaskSwHook
    DCD     OSTaskSwHook
__OS_IntExit
    DCD     OSIntExit
__OS_IntNesting
    DCD     OSIntNesting
__OS_PrioCur
    DCD     OSPrioCur
__OS_PrioHighRdy
    DCD     OSPrioHighRdy
__OS_Running
    DCD     OSRunning
__OS_TCBCur
    DCD     OSTCBCur
__OS_TCBHighRdy
    DCD     OSTCBHighRdy
END

posted on 2018-06-23 10:41 zlf 閱讀(1030) 評論(0)  編輯 收藏 引用

導航

<2018年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

統計

常用鏈接

留言簿(1)

隨筆檔案

文章檔案

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            在线观看欧美成人| 在线亚洲欧美专区二区| 亚洲美女在线看| 亚洲成色777777在线观看影院| 欧美日本不卡| 欧美日韩一区高清| 国产精品高潮呻吟久久av无限| 欧美日韩系列| 国产精品激情电影| 国产日韩精品入口| 韩国三级电影久久久久久| 国产一区美女| 亚洲精品欧美激情| 亚洲欧美日韩第一区| 欧美一区永久视频免费观看| 久久露脸国产精品| 亚洲二区在线| 亚洲精品少妇30p| 99在线精品观看| 香蕉久久夜色精品国产使用方法| 久久久久久亚洲精品不卡4k岛国| 欧美**字幕| 欧美日韩一区二区国产| 国产日韩久久| 91久久精品久久国产性色也91| 中文精品视频| 久久一区二区视频| 99re66热这里只有精品3直播| 亚洲一区二区在线观看视频| 久久天堂成人| 国产麻豆日韩欧美久久| 亚洲人成人99网站| 久久久久成人精品| 亚洲午夜激情网站| 99一区二区| 欧美在线播放视频| 欧美极品在线视频| 国产综合香蕉五月婷在线| 亚洲精品一区二区三区福利| 一区二区日韩伦理片| 久久久久这里只有精品| 亚洲人在线视频| 久久精品国产99国产精品| 欧美啪啪一区| 亚洲大片精品永久免费| 亚洲字幕一区二区| 蜜桃av综合| 午夜在线电影亚洲一区| 亚洲卡通欧美制服中文| 欧美影片第一页| 国产精品xxx在线观看www| 国内精品久久久久影院色| 亚洲日本成人| 久久久久久久波多野高潮日日| 亚洲神马久久| 欧美视频福利| 99国产精品久久久久久久| 嫩草影视亚洲| 久久精品综合一区| 国模大胆一区二区三区| 欧美一区二粉嫩精品国产一线天| 亚洲国内精品在线| 欧美成人久久| 日韩亚洲精品电影| 亚洲精品在线一区二区| 久热这里只精品99re8久| 一区二区欧美精品| 国产精品成人免费视频| 在线中文字幕日韩| 日韩视频一区二区三区在线播放| 久久综合伊人| 极品少妇一区二区三区| 女人色偷偷aa久久天堂| 久久久久国产成人精品亚洲午夜| 国产精品热久久久久夜色精品三区| 99精品国产在热久久婷婷| 欧美福利视频| 欧美激情一区二区三区蜜桃视频 | 久久免费视频在线观看| av成人免费在线| 欧美日韩精品一区二区天天拍小说 | 亚洲精品一区二区三区av| 欧美成人免费网| 欧美久久久久久| 夜夜嗨av色一区二区不卡| 日韩午夜精品| 欧美在线观看视频一区二区三区| 日韩天堂在线观看| 国产精品久久久对白| 欧美在线日韩| 欧美在线www| 亚洲人成免费| 亚洲欧美日韩国产另类专区| 国产视频久久久久久久| 欧美激情第10页| 国产精品美女xx| 欧美激情视频一区二区三区在线播放| 欧美日韩日本网| 久久影院亚洲| 欧美三级电影大全| 久久先锋影音av| 欧美精品在欧美一区二区少妇| 一本一本大道香蕉久在线精品| 亚洲新中文字幕| 亚洲国产精品久久91精品| 日韩一区二区精品葵司在线| 欧美mv日韩mv国产网站app| 亚洲视频碰碰| 麻豆av福利av久久av| 亚洲综合二区| 欧美精品日日鲁夜夜添| 久久久女女女女999久久| 欧美va亚洲va香蕉在线| 久久国产精品网站| 欧美视频日韩视频在线观看| 久久综合激情| 国产欧美日韩一区二区三区在线 | 嫩草国产精品入口| 久久久久久久一区二区| 欧美丝袜一区二区三区| 欧美成va人片在线观看| 国产区在线观看成人精品| 日韩视频久久| 亚洲免费观看高清在线观看 | 久久av一区| 亚洲欧美日韩第一区| 欧美国产一区二区三区激情无套| 久久国产乱子精品免费女 | 在线视频观看日韩| 午夜精品在线| 欧美亚洲在线| 国产精品久久久一区麻豆最新章节| 欧美好吊妞视频| 在线视频成人| 免费日本视频一区| 欧美激情在线狂野欧美精品| 伊人精品成人久久综合软件| 久久黄色小说| 久热精品视频在线观看| 伊人久久婷婷色综合98网| 欧美一区二区三区啪啪| 欧美在线不卡视频| 国产欧美日韩一区二区三区在线观看| 妖精成人www高清在线观看| 一区二区三区欧美在线| 欧美日韩精品福利| 亚洲欧美日韩精品久久| 美女黄毛**国产精品啪啪| 国产三级精品三级| 欧美一激情一区二区三区| 先锋亚洲精品| 国产一区二区三区成人欧美日韩在线观看 | 亚洲欧美怡红院| 欧美伊久线香蕉线新在线| 国产欧美精品一区| 性色av一区二区三区| 另类综合日韩欧美亚洲| 最近中文字幕日韩精品 | 欧美在线国产精品| 欧美a级在线| 一本不卡影院| 国产农村妇女精品一二区| 久久成人免费视频| 亚洲福利视频网| 中国成人黄色视屏| 国产欧美日韩一区二区三区| 久久久久久成人| 亚洲精品日本| 久久久久久久久久久一区| 91久久久在线| 国产欧美日韩视频一区二区| 噜噜噜91成人网| 亚洲午夜一二三区视频| 乱人伦精品视频在线观看| 99日韩精品| 国产一区二区三区四区| 奶水喷射视频一区| 午夜久久99| 最近中文字幕日韩精品| 欧美一区二区三区免费在线看| 亚洲第一视频网站| 国产精品欧美日韩久久| 美脚丝袜一区二区三区在线观看| 一区二区高清视频在线观看| 看欧美日韩国产| 亚洲欧美国产日韩中文字幕| 亚洲国产一区二区a毛片| 国产精品久久久久久久久免费| 久久视频一区| 亚洲欧美在线磁力| 日韩视频中午一区| 亚洲高清精品中出| 久久一区二区精品| 亚洲一区二区三区欧美| 亚洲日本va在线观看| 国产一区二区视频在线观看| 欧美日韩在线播放一区二区| 久久亚洲国产精品一区二区| 亚洲一区二区三区四区五区午夜 | 久久久97精品|