• <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>

            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 閱讀(996) 評論(0)  編輯 收藏 引用

            導航

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            統計

            常用鏈接

            留言簿(1)

            隨筆檔案

            文章檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久精品日日躁夜夜躁欧美| 久久精品国产WWW456C0M| 性高朝久久久久久久久久| 久久久久国产精品麻豆AR影院 | 日韩一区二区久久久久久| AV狠狠色丁香婷婷综合久久 | 久久无码AV中文出轨人妻| 久久综合九色欧美综合狠狠| 久久人人爽人人爽人人av东京热| 久久99国产精品尤物| 蜜桃麻豆www久久| 久久成人小视频| 亚洲综合婷婷久久| 久久WWW免费人成一看片| 人人狠狠综合久久亚洲婷婷| 亚洲精品97久久中文字幕无码| 久久精品aⅴ无码中文字字幕不卡 久久精品aⅴ无码中文字字幕重口 | 国产精品一区二区久久精品涩爱| 久久久久无码精品国产不卡| 久久亚洲中文字幕精品一区四 | 久久久久久国产精品美女 | 久久天堂AV综合合色蜜桃网| 99精品伊人久久久大香线蕉| 婷婷久久久亚洲欧洲日产国码AV | 四虎国产精品免费久久5151| 中文精品久久久久人妻不卡| 久久久国产精品| 99久久国产综合精品网成人影院| 麻豆一区二区99久久久久| 国产亚洲美女精品久久久2020| 国产A级毛片久久久精品毛片| 国产精品美女久久久久| 伊人久久大香线蕉亚洲| 精品久久久久久久久免费影院| 久久久99精品成人片中文字幕| 爱做久久久久久| 91精品国产91久久| 青青青国产精品国产精品久久久久| WWW婷婷AV久久久影片| 久久精品无码专区免费东京热 | 精品久久久久久无码国产|