📄 os_cpu_a.s
字号:
;/* os_cpu.h
; *
; * Motorola Coldfire MCF5307 port to MicroC/OS-II
; *
; * Ross Berteig
; * Cheshire Engineering Corp
; * 650 Sierra Madre Villa, Suite 201
; * Pasadena CA 91107
; * +1-626-351-5493 +1-626-351-8645 FAX
; * Ross@CheshireEng.com, www.CheshireEng.com
; *
; * Copyright (C) 1998 Cheshire Engineering Corporation.
; * Based on a port to uCOS version 1.x by David Fiddes.
; * Portions Copyright (C) 1997 David Fiddes, D.J.Fiddes@hw.ac.uk
; * Anything that no longer works is probably not his fault.
; */
;
;
; A note for the interested:
;
; David uses the movem.l (a7),d0-d7/a0-a6, lea 60(a7)a7
; construct in place of the traditional 68xxx
; movem.l (a7)+,d0-d7/a0-a6. It is perfectly in order to
; push/pop individual registers using movem.l (a7)+,d2 , etc.
; but it's a bit slower (and more verbose)
;
; The lea instruction is required because the ColdFire can't
; push multiple registers directly to the stack...
;
.text
.global _OSStartHighRdy
.global _OSCtxSw
.global _OSIntCtxSw
.global _OSTickISR
.global _CPUFormatError
.extern _OSIntEnter
.extern _OSIntExit
.extern _OSTimeTick
.extern _OSTCBCur
.extern _OSTCBHighRdy
.extern _OSPrioCur
.extern _OSPrioHighRdy
.extern _OSTaskSwHook
.extern _OSRunning
.extern ___MBAR
; Procedure : OSStartHighRdy
;
; The procedure gets the highest priority task then loads its
; stack before restoring all of the registers and doing an RTE
; to actually start the task. Called directly from uC/OS
;
_OSStartHighRdy:
jsr _OSTaskSwHook ;Call the hook proc
moveq #1,d0
move.b d0,(_OSRunning)
move.l (_OSTCBHighRdy),a1 ;Get highest prio. task
move.l (a1),a7 ;Get ptr to top of stack
movem.l (a7),d0-d7/a0-a6 ;Store all the regs
lea 60(a7),a7 ;Advance the stack pointer
rte ;Return to task
; Procedure : OSIntCtxSw
;
; The procedure is called by when the uC/OS wants to return to
; a different task at interrupt time. Used primarily within the
; timer tick interrupt.
;
; Offset the stack pointer to get back to an exception frame, then
; simply jump to OSCtxSw() to do the rest of the details. We skip the
; register save at the top of OSCtxSw() because the interrupt routine
; itself has already saved all the registers in the right spot after
; the exception frame.
;
; The stack adjustment compensates for the following:
;
; OSIntExit call 4
; OSIntExit stack frame adjust 4 <- goes to 0 for -O2
; OSIntCtxSw call 4
; ---
; 12 or 8
; The DiabData compiler option -X36=1 will force the use of stack
; frames regardless of the optimization settings. The default if
; any optimizations are on is to avoid a stack frame in any function
; with no local variables on the stack.
_OSIntCtxSw:
adda.l #12,a7 ; Compensate stack pointer
bra CtxSwTail ; Handle the context switch,
; Procedure : OSCtxSw
;
; The procedure is installed as an interrupt handler and called
; using a TRAP instruction within the uC/OS scheduler to swap
; contexts at the task level.
;
; Initialization must insert this routine into the vector table at
; vector 46 (offset 0xb8) to correspond to the definition of the
; OS_TASK_SW() macro in os_cpu.h as TRAP #14.
_OSCtxSw:
lea -60(a7),a7
movem.l d0-d7/a0-a6,(a7)
CtxSwTail:
move.l (_OSTCBCur),a1 ;Save stack ptr in TCB
move.l a7,(a1)
jsr _OSTaskSwHook ; Call the hook proc
move.l (_OSTCBHighRdy),a1 ;Point to HI Prio. Task Rdy
move.l a1,(_OSTCBCur) ;This is now current TCB
move.b (_OSPrioHighRdy),d0 ;And track the hi prio value
move.b d0,(_OSPrioCur) ; as well for faster compares
move.l (a1),A7 ;Get new task's stack ptr
movem.l (a7),d0-d7/a0-a6
lea 60(a7),a7
rte ;Return to new task
; Procedure : OSTickISR
;
; The procedure is installed as the timer tick ISR and called
; each time TIMER1 on the MCF5307 reaches it's reference value.
; It stores the current context before calling the uC/OS int
; nesting logic and timer tick routine which can cause the
; context to change. Use this as an example of how to write
; ISRs in uC/OS.
;
; Notice that all ISRs *must* leave the same stack context
; at the time of the call to OSIntExit() since if a context
; switch does occur, OSIntCtxSw() must be able to find this
; frame. This probably means that other ISRs which have
; local variables and do more work should follow this model of
; calling a worker function similar to OSTimeTick() so that
; the exception stack frame is left undisturbed.
;
; Initialization must insert this routine into the vector table at
; the vector 24+level (offset 0x64 + 4*level) where level is the
; irq priority level assigned to the timer tick. For example,
; assigning the timer to level 5 would correspond to vector 29
; at offset 0x74 in the table. The level is assigned with the
; ICR1 register in the SIM module.
_OSTickISR:
lea -60(a7),a7
movem.l d0-d7/a0-a6,(a7)
;Reset the timer chip (hard coded Timer1.TER reg value - bad)
move.l #___MBAR+0x151,a0
move.b #0x03,(a0)
jsr _OSIntEnter
jsr _OSTimeTick
jsr _OSIntExit
movem.l (a7),d0-d7/a0-a6
lea 60(a7),a7
rte
; Procedure: CPUFormatError
;
; Exception handler for frame format errors, which should never
; happen unless some ISR fails to follow the rules and a context
; switch attempts to do an RTE with A7 pointing to the wrong place.
;
; This version simply halts the CPU. A better response would be
; to figure out the context of the fault and produce a diagnostic
; message somewhere, but we are an embedded system...
;
; Initialization must insert this routine into the vector table at
; vector 14 (offset 0x38).
_CPUFormatError:
nop ; breakpoint or patch fodder
nop
nop
nop
halt ; nothing else to do here
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -