|
cortex移植ucOS II主要在于os_cpu_a.asm的改寫
M3的os_cpu_a.asm在Micrium有官方移植例程
M0的當(dāng)時(shí)沒找到,不知現(xiàn)在有沒有
附件是我寫的os_cpu_a.asm,M3版本改寫的
寫了兩個(gè)版本MSP和PSP,一般用PSP的
M0和M3的指令集有差異,需要修改STM和LDM的用法,參考PendSV_Handler的中文注釋
- ;********************************************************************************************************
- ; uC/OS-II
- ; The Real-Time Kernel
- ;
- ; (c) Copyright 1992-2006, Micrium, Weston, FL
- ; All Rights Reserved
- ;
- ; ARM Cortex-M3 Port
- ;
- ; File : OS_CPU_A.ASM
- ; Version : V2.89
- ; By : Jean J. Labrosse
- ; Brian Nagel
- ;
- ; For : ARMv7M Cortex-M3
- ; Mode : Thumb2
- ; Toolchain : IAR EWARM
- ;********************************************************************************************************
- ;********************************************************************************************************
- ; PUBLIC FUNCTIONS
- ;********************************************************************************************************
- ; External references.
- EXTERN OSRunning
- EXTERN OSPrioCur
- EXTERN OSPrioHighRdy
- EXTERN OSTCBCur
- EXTERN OSTCBHighRdy
- EXTERN OSIntNesting
- EXTERN OSIntExit
- EXTERN OSTaskSwHook
- ; EXTERN __vector_table
- ; Functions declared in this file.
- PUBLIC OS_CPU_SR_Save
- PUBLIC OS_CPU_SR_Restore
- PUBLIC OSStartHighRdy
- PUBLIC OSCtxSw
- PUBLIC OSIntCtxSw
- PUBLIC PendSV_Handler
- ;********************************************************************************************************
- ; EQUATES
- ;********************************************************************************************************
- NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control state register.
- NVIC_SYSPRI14 EQU 0xE000ED22 ; System priority register (priority 14).
- NVIC_PENDSV_PRI EQU 0xFF ; PendSV priority value (lowest).
- NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
- ;********************************************************************************************************
- ; CODE GENERATION DIRECTIVES
- ;********************************************************************************************************
- RSEG CSTACK:DATA:NOROOT(2)
- RSEG CODE:CODE:NOROOT(2)
- THUMB
- ;*********************************************************************************************************
- ; 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 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); */
- ; :
- ; :
- ; }
- ;*********************************************************************************************************
- 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.
- ;*********************************************************************************************************
- OSStartHighRdy
- CPSID I ; Prevent interruption during OSStartHighRdy
- LDR R0, =0xE000ED20 ; Set the PendSV exception priority, must lowest
- LDR R1, =0x00FF0000
- LDR R2, [R0]
- ORRS R2, R2, R1
- STR R2, [R0]
- LDR R0, =OSRunning ; OSRunning = TRUE
- MOVS R1, #1
- STRB R1, [R0]
-
- LDR R0, =OSTaskSwHook ; OSTaskSwHook();
- BLX 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;
- MSR PSP, R0 ; PSP = R0
- MOVS R0, #2
- MSR CONTROL, R0 ; SP used PSP
- ISB
-
- LDR R0, =SFE(CSTACK)
- ; LDR R0, =__vector_table
- ; LDR R0, [R0]
- MSR MSP, R0 ; MSP = CSTACK
-
- POP {R0-R7} ; R8-R11, R4-R7
- MOV R8, R0
- MOV R9, R1
- MOV R10,R2
- MOV R11,R3
- ADD SP, SP, #0x10 ; R12, LR, PC, PSR
- POP {R0-R3}
- MOV R12,R0
- MOV LR, R1
- MSR PSR,R3
- ISB
-
- PUSH {R2} ; PUSH PC
-
- SUB SP, SP, #0x1C ; R0-R3
- POP {R0-R3}
- ADD SP, SP, #0x0C
-
- CPSIE I
- POP {PC}
- OSStartHang
- B OSStartHang ; Should never get here
- ;********************************************************************************************************
- ; PERFORM A CONTEXT SWITCH (From task level)
- ; void OSCtxSw(void)
- ;
- ; Note(s) : 1) OSCtxSw() is called when OS wants to perform a task context switch. This function
- ; triggers the PendSV exception which is where the real work is done.
- ;********************************************************************************************************
- OSCtxSw
- LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
- LDR R1, =NVIC_PENDSVSET
- STR R1, [R0]
- BX LR
- ;********************************************************************************************************
- ; PERFORM A CONTEXT SWITCH (From interrupt level)
- ; void OSIntCtxSw(void)
- ;
- ; Notes: 1) OSIntCtxSw() is called by OSIntExit() when it determines a context switch is needed as
- ; the result of an interrupt. This function simply triggers a PendSV exception which will
- ; be handled when there are no more interrupts active and interrupts are enabled.
- ;********************************************************************************************************
- OSIntCtxSw
- LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
- LDR R1, =NVIC_PENDSVSET
- STR R1, [R0]
- BX LR
- ;********************************************************************************************************
- ; HANDLE PendSV EXCEPTION
- ; void PendSV_Handler(void)
- ;
- ; Note(s) : 1) PendSV is used to cause a context switch. This is a recommended method for performing
- ; context switches with Cortex-M0. This is because the Cortex-M0 auto-saves half of the
- ; processor context on any exception, and restores same on return from exception. So only
- ; saving of R4-R11 is required and fixing up the stack pointers. Using the PendSV 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) Pseudo-code is:
- ; a) Get the process SP, if 0 then skip (goto d) the saving part (first context switch);
- ; b) Save remaining regs r4-r11 on process stack;
- ; c) Save the process SP in its TCB, OSTCBCur->OSTCBStkPtr = SP;
- ; d) Call OSTaskSwHook();
- ; e) Get current high priority, OSPrioCur = OSPrioHighRdy;
- ; f) Get current ready thread TCB, OSTCBCur = OSTCBHighRdy;
- ; g) Get new process SP from TCB, SP = OSTCBHighRdy->OSTCBStkPtr;
- ; h) Restore R4-R11 from new process stack;
- ; i) Perform exception return which will restore remaining context.
- ;
- ; 3) On entry into PendSV handler:
- ; a) The following have been saved on the process stack (by processor):
- ; xPSR, PC, LR, R12, R0-R3
- ; b) Processor mode is switched to Handler mode (from Thread mode)
- ; c) Stack is Main stack (switched from Process stack)
- ; d) OSTCBCur points to the OS_TCB of the task to suspend
- ; OSTCBHighRdy points to the OS_TCB of the task to resume
- ;
- ; 4) Since PendSV is set to lowest priority in the system (by OSStartHighRdy() above), we
- ; know that it will only be run when no other exception or interrupt is active, and
- ; therefore safe to assume that context being switched out was using the process stack (PSP).
- ;
- ; 2) b) save remaining regs r4-r11 on process stack;
- ; 先將PSP賦給R0作為目標(biāo)地址
- ; 方法一:
- ; 先偏移4個(gè)字,傳輸R4-R7;繼續(xù)偏移8個(gè)字,傳輸R8-R11
- ; SUBS R0, R0, #0x10 ; Save remaining regs r4-11 on process stack
- ; STM R0!, {R4-R7}
- ; SUBS R0, R0, #0x20
- ; MOV R4, R8
- ; MOV R5, R9
- ; MOV R6, R10
- ; MOV R7, R11
- ; STM R0!, {R4-R7}
- ; SUBS R0, R0, #0x10
- ; 方法二:
- ; 先偏移8個(gè)字,借助R1傳輸R8;借助R1-R3,傳輸R9-R11,R4-R7
- ; SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack
- ; MOV R1, R8
- ; STM R0!, {R1}
- ; MOV R1, R9
- ; MOV R2, R10
- ; MOV R3, R11
- ; STM R0!, {R1-R7}
- ; SUBS R0, R0, #0x20
- ;********************************************************************************************************
- PendSV_Handler
- CPSID I ; Prevent interruption during context switch
- PUSH {LR} ; Save LR exc_return value
-
- MRS R0, PSP ; PSP is process stack pointer
- SUBS R0, R0, #0x20
- LDR R1, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP;
- LDR R1, [R1]
- STR R0, [R1] ; R0 is SP of process being switched out
-
- MOV R1, R8 ; Save remaining regs r4-11 on process stack
- STM R0!, {R1}
- MOV R1, R9
- MOV R2, R10
- MOV R3, R11
- STM R0!, {R1-R7}
- SUBS R0, R0, #0x20
-
- ; LDR R0, =OSTaskSwHook ; OSTaskSwHook();
- ; BLX 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 R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
- LDM R0!,{R1} ; Restore R8-11, R4-7 from new process stack
- MOV R8, R1
- LDM R0!,{R1-R7}
- MOV R9, R1
- MOV R10,R2
- MOV R11,R3
- MSR PSP, R0 ; Load PSP with new process SP
- CPSIE I
- POP {PC} ; Exception return will restore remaining context
- END
復(fù)制代碼
|
-
-
os_cpu_a.rar
2019-3-19 10:17 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
4.4 KB, 下載次數(shù): 8, 下載積分: 黑幣 -5
os_cpu_a.asm MSP及PSP版本
|