📄 os_cpu_a.asm
字号:
;*
;*
;* OUTPUTS
;*
;* None
;*
;*
;************************************************************************
OS_Timer_Initialize
STMDB sp!,{r0-r1} ; Save on temporary IRQ stack
;*****************************
;* Begin Board Specific Code *
;*****************************
;set timer, the source clock is 50.7M Hz
LDR r0, =0x51000000 ; Load the PWM Timer Base
LDR r1, =0x00003F18 ; Set clock Prescaler0 is 25, Prescaler1 is 64
STR r1, [r0,#0] ; Set timer config 0
LDR r1, =0x00000000 ; set clock divider is 1/2
STR r1, [r0,#4] ; Set timer config 1
LDR r1, =0x000007b4 ; set clock count is 1972
STR r1, [r0,#0x18] ; Set timer count register
LDR r1, [r0,#8] ; load timer control register
ORR r1, r1, #0xB00 ; change status for timer1
STR r1, [r0,#8] ; start the timer1
BIC r1, r1, #0x200 ; change status for timer1
STR r1, [r0,#8] ; start the timer1
; enable the timer1 interrupt
LDR r0, =0x4A000000 ; Load interrupt base
LDR r1, [r0,#8] ; get interrupt mask regist
BIC r1, r1, #0x800 ; clear the timer1 interrupt
STR r1, [r0,#8] ; enable the timer1 interrupt
;*****************************
;* End Board Specific Code *
;*****************************
LDMIA sp!,{r0-r1} ; Restore reg's
BX lr ; Return to caller
;*********************************************************************************************************
; 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); */
; :
; :
; }
;*********************************************************************************************************
; AREA CODE, CODE, READONLY
; CODE32
OS_CPU_SR_Save
MRS R0, CPSR
ORR R1, R0, #OS_CPU_ARM_CONTROL_INT_DIS ; Set IRQ and FIQ bits in CPSR to disable all interrupts.
MSR CPSR_c, R1
BX LR ; Disabled, return the original CPSR contents in R0.
OS_CPU_SR_Restore
MSR CPSR_c, R0
BX LR
;*********************************************************************************************************
; START MULTITASKING
; void OSStartHighRdy(void)
;
; Note(s) : 1) OSStartHighRdy() MUST:
; a) Call OSTaskSwHook() then,
; b) Set OSRunning to TRUE,
; c) Switch to the highest priority task.
;*********************************************************************************************************
; AREA CODE, CODE, READONLY
; CODE32
OSStartHighRdy
; Change to SVC mode.
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC)
LDR R0, __OS_TaskSwHook ; OSTaskSwHook();
MOV LR, PC
BX R0
LDR R0, __OS_Running ; OSRunning = TRUE;
MOV R1, #1
STRB R1, [R0]
; SWITCH TO HIGHEST PRIORITY TASK:
LDR R0, __OS_TCBHighRdy ; Get highest priority task TCB address,
LDR R0, [R0] ; Get stack pointer,
LDR SP, [R0] ; Switch to the new stack,
LDR R0, [SP], #4 ; Pop new task's CPSR,
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context.
;*********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From task level) - OSCtxSw()
;
; Note(s) : 1) OSCtxSw() is called in SVC mode with BOTH FIQ and IRQ interrupts DISABLED.
;
; 2) The pseudo-code for OSCtxSw() is:
; a) Save the current task's context onto the current task's stack,
; b) OSTCBCur->OSTCBStkPtr = SP;
; c) OSTaskSwHook();
; d) OSPrioCur = OSPrioHighRdy;
; e) OSTCBCur = OSTCBHighRdy;
; f) SP = OSTCBHighRdy->OSTCBStkPtr;
; g) Restore the new task's context from the new task's stack,
; h) Return to new task's code.
;
; 3) Upon entry:
; OSTCBCur points to the OS_TCB of the task to suspend,
; OSTCBHighRdy points to the OS_TCB of the task to resume.
;*********************************************************************************************************
; AREA CODE, CODE, READONLY
; CODE32
OSCtxSw
; SAVE CURRENT TASK'S CONTEXT:
STMFD SP!, {LR} ; Push return address,
STMFD SP!, {LR}
STMFD SP!, {R0-R12} ; Push registers,
MRS R0, CPSR ; Push current CPSR,
TST LR, #1 ; See if called from Thumb mode,
ORRNE R0, R0, #OS_CPU_ARM_CONTROL_THUMB ; If yes, set the T-bit.
STMFD SP!, {R0}
LDR R0, __OS_TCBCur ; OSTCBCur->OSTCBStkPtr = SP;
LDR R1, [R0]
STR SP, [R1]
LDR R0, __OS_TaskSwHook ; OSTaskSwHook();
MOV LR, PC
BX R0
LDR R0, __OS_PrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, __OS_PrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, __OS_TCBCur ; OSTCBCur = OSTCBHighRdy;
LDR R1, __OS_TCBHighRdy
LDR R2, [R1]
STR R2, [R0]
LDR SP, [R2] ; SP = OSTCBHighRdy->OSTCBStkPtr;
; RESTORE NEW TASK'S CONTEXT:
LDMFD SP!, {R0} ; Pop new task's CPSR,
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context.
;*********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw()
;
; Note(s) : 1) OSIntCtxSw() is called in SVC mode with BOTH FIQ and IRQ interrupts DISABLED.
;
; 2) The pseudo-code for OSCtxSw() is:
; a) OSTaskSwHook();
; b) OSPrioCur = OSPrioHighRdy;
; c) OSTCBCur = OSTCBHighRdy;
; d) SP = OSTCBHighRdy->OSTCBStkPtr;
; e) Restore the new task's context from the new task's stack,
; f) Return to new task's code.
;
; 3) Upon entry:
; OSTCBCur points to the OS_TCB of the task to suspend,
; OSTCBHighRdy points to the OS_TCB of the task to resume.
;*********************************************************************************************************
; AREA CODE, CODE, READONLY
; CODE32
OSIntCtxSw
LDR R0, __OS_TaskSwHook ; OSTaskSwHook();
MOV LR, PC
BX R0
LDR R0, __OS_PrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, __OS_PrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, __OS_TCBCur ; OSTCBCur = OSTCBHighRdy;
LDR R1, __OS_TCBHighRdy
LDR R2, [R1]
STR R2, [R0]
LDR SP, [R2] ; SP = OSTCBHighRdy->OSTCBStkPtr;
; RESTORE NEW TASK'S CONTEXT:
LDMFD SP!, {R0} ; Pop new task's CPSR,
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context.
;********************************************************************************************************
; RESET EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2
; R3 Return PC
;********************************************************************************************************
; AREA CODE, CODE, READONLY
; CODE32
OS_CPU_ARM_ExceptResetHndlr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -