📄 os_cpu_a.s
字号:
;***************************************************
; $Workfile: Os_cpu_a.s $
; $Revision: 1.1.1.1 $
; $Author: yangfan
; $Date: 2006-10-22 14:45
; **************************************************
;********************************************************************/
AREA yff, CODE, READONLY
;/***********************************************************************
;
; Function: OSStartHighRdy
;
; Purpose:
; To start the task with the highest priority during OS startup
;
; Processing:
; See uC/OS-II Task Level Context Switch flow chart
;
; Parameters: void
;
; Outputs: None
;
; Returns: void
;
; Notes:
; Called once during OSStart()
;
;*********************************************************************/
GET ..\2440_CODE\option.inc
GET ..\2440_CODE\2440addr.inc
EXPORT OSStartHighRdy
IMPORT OSTaskSwHook
IMPORT OSTCBHighRdy
IMPORT OSRunning
IMPORT OSIntEnter
IMPORT OSTimeTick
IMPORT OSIntExit
IMPORT OSIntCtxSwFlag
IMPORT OSTCBCur
EXPORT OSCtxSw
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
IMPORT OSTCBCur
GBLL __DEBUG
__DEBUG SETL {TRUE}
OSStartHighRdy
BL OSTaskSwHook ; Call user-defined hook function
LDR r4,=OSRunning ; Indicate that multitasking has started
MOV r5, #1
STRB r5, [r4] ; OSRunning = true
LDR r4, =OSTCBHighRdy ; Get highest priority task TCB address
LDR r4, [r4] ; get stack pointer
LDR sp, [r4] ; switch to the new stack
LDMFD sp!, {r4} ; pop new task s spsr_cxsf
MSR spsr_cxsf, r4
LDMFD sp!, {r0-r12,lr,pc}^ ; pop new task s r0-r12,lr & pc
;/***********************************************************************
;
; Function: OS_TASK_SW
;
; Purpose:
; To perform a context switch from the Task Level.
;
; Processing:
; See uC/OS-II Task Level Context Switch flow chart
;
; Parameters: void
;
; Outputs: None
;
; Returns: void
;
; Notes:
; On entry, OSTCBCur and OSPrioCur hold the current TCB and priority
; and OSTCBHighRdy and OSPrioHighRdy contain the same for the task
; to be switched to.
;
; The following code assumes that the virtual memory is directly
; mapped into physical memory. If this is not true, the cache must
; be flushed at context switch to avoid address aliasing.
;
;*********************************************************************/
OSCtxSw
STMFD SP!, {LR}
STMFD sp!, {r0-r12,LR} ; push lr & register file
MRS r4, CPSR ; protect reg to task stack if use sp_svc
STMFD sp!, {r4} ; push current psr
_OSCtxSw
LDR r4, =OSPrioCur ; OSPrioCur = OSPrioHighRdy
LDR r5, =OSPrioHighRdy
LDRB r6, [r5]
STRB r6, [r4]
LDR r4, =OSTCBCur ; Get current task TCB address
LDR r5, [r4]
STR sp, [r5] ; store sp in preempted tasks s TCB
;[ __DEBUG
; IMPORT Print
; MOV R0,SP
; BL Print
;]
BL OSTaskSwHook ; call Task Switch Hook
LDR r6, =OSTCBHighRdy ; Get highest priority task TCB address
LDR r6, [r6]
LDR sp, [r6] ; get new task s stack pointer
STR r6, [r4] ; set new current task TCB address
LDMFD sp!, {r4} ; pop new task spsr_cxsf
MSR spsr_cxsf, r4
LDMFD sp!, {r0-r12,LR,pc}^ ; pop new task r0-r12,lr & pc
;***********************************************************************
;
; Function: OSIntCtxSw
;
; Purpose:
; To perform a context switch from the interrupt level.
;
; Processing:
; See uC/OS-II Interrupt Level Context Switch flow chart
;
; Parameters: void
;
; Outputs: None
;
; Returns: void
;
; Notes:
; Sets up the stacks and registers to call the task level
; context switch
;
;*********************************************************************/
EXPORT OSIntCtxSw
IMPORT OSIntCtxSwFlag
; MOV pc, lr ; return
OSIntCtxSw
ADD SP ,SP, #12 ;调整SP指针的位置,
;因为之前调用了OSIntExit(),OSIntCtxSw(),OS_ENTER_CRITICAL();
;指针加了 4*2 + 4*0(OSIntCtxSw是汇编函数没有返回地址的入栈)+4*1cpsr入栈
B _OSCtxSw ; jump to _OSCtxSw
;/***********************************************************************
;
; Functions: ARMDisableInt
; ARMEnableInt
;
; Purpose:
; Disable and enable IRQ and FIQ preserving current CPU mode.
;
; Processing:
; Push the cpsr onto the stack
; Disable IRQ and FIQ interrupts
; Return
;
; Parameters: void
;
; Outputs: None
;
; Returns: void
;
; Notes:
; (1) Can be called from SVC mode to protect Critical Sections.
; (2) Do not use these calls at interrupt level.
; (3) Used in pairs within the same function level;
; (4) Will restore interrupt state when called; i.e., if interrupts
; are disabled when DisableInt is called, interrupts will still
; still be disabled when the matching EnableInt is called.
; (5) Uses the method described by Labrosse as "Method 2".
;
;*********************************************************************/
EXPORT ARMDisableInt
ARMDisableInt
MRS r0, cpsr
STMFD sp!, {r0} ; push current PSR
ORR r0, r0, #0xC0
MSR cpsr_c, r0 ; disable IRQ Int s
MOV pc, lr
;------------------------------------------------------------------------
EXPORT ARMEnableInt
ARMEnableInt
LDMFD sp!, {r0} ; pop current PSR
MSR cpsr_c, r0 ; restore original cpsr
MOV pc, lr
;------------------------------------------------------------------------
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -