📄 os_cpu_a.s
字号:
;********************************************************************************************************
; uC/OS-II
; The Real-Time Kernel
;
; (c) Copyright 1998, Jean J. Labrosse, Plantation, FL
; All Rights Reserved
;
;
; M68HC912DG128A Specific code
; (MetroWerks C/C++ V4.1)
;
; File : OS_CPU_A.S
; By : Jean J. Labrosse
; Port Version : V1.01
; Ported to MC68HC912DG128A : Robert F. Heslar
;********************************************************************************************************
;********************************************************************************************************
; CONFIGURATION CONSTANTS
;********************************************************************************************************
OS_TICK_OC: equ 7 ; We will use Output Compare #7 to generate tick interrupts
OS_TICK_OC_CNTS: equ 5000 ; 100 Hz tick rate (assumes Free Running Timer runs at 500 KHz)
; OS_TICK_OC_CNTS = CPU_FRT_FREQ / OS_TICKS_PER_SEC
;********************************************************************************************************
; I/O PORT ADDRESSES
;********************************************************************************************************
TFLG1: equ $004E ; I/O port addresses. Assumes all 68HC12 I/Os start at 0x0000
TC0: equ $0050
TC1: equ $0052
TC2: equ $0054
TC3: equ $0056
TC4: equ $0058
TC5: equ $005A
TC6: equ $005C
TC7: equ $005E
;********************************************************************************************************
; PUBLIC DECLARATIONS
;********************************************************************************************************
xdef OSStartHighRdy
xdef OSCtxSw
xdef OSIntCtxSw
xdef OSTickISR
xdef _Null
;********************************************************************************************************
; EXTERNAL DECLARATIONS
;********************************************************************************************************
xref OSIntExit
xref OSIntNesting
xref OSPrioCur
xref OSPrioHighRdy
xref OSRunning
xref OSTaskSwHook
xref OSTCBCur
xref OSTCBHighRdy
xref OSTimeTick
;********************************************************************************************************
; START HIGHEST PRIORITY TASK READY-TO-RUN
;
; Description : This function is called by OSStart() to start the highest priority task that was created
; by your application before calling OSStart().
;
; Arguments : none
;
; Note(s) : 1) The stack frame is assumed to look as follows:
;
; OSTCBHighRdy->OSTCBStkPtr + 0 --> CCR
; + 1 B
; + 2 A
; + 3 X (H)
; + 4 X (L)
; + 5 Y (H)
; + 6 Y (L)
; + 7 PC(H)
; + 8 PC(L)
;
; 2) OSStartHighRdy() MUST:
; a) Call OSTaskSwHook() then,
; b) Set OSRunning to TRUE,
; c) Switch to the highest priority task.
;********************************************************************************************************
OSStartHighRdy:
jsr OSTaskSwHook ; 4~, Invoke user defined context switch hook
inc OSRunning ; 4~, Indicate that we are multitasking
ldx OSTCBHighRdy ; 3~, Point to TCB of highest priority task ready to run
stx OSTCBCur
lds 0,x ; 3~, Load SP into 68HC12
rti ; 8~, Run task
;********************************************************************************************************
; TASK LEVEL CONTEXT SWITCH
;
; Description : This function is called when a task makes a higher priority task ready-to-run.
;
; Arguments : none
;
; Note(s) : 1) Upon entry,
; OSTCBCur points to the OS_TCB of the task to suspend
; OSTCBHighRdy points to the OS_TCB of the task to resume
;
; 2) The stack frame of the task to suspend looks as follows:
;
; SP + 0 --> CCR
; + 1 B
; + 2 A
; + 3 X (H)
; + 4 X (L)
; + 5 Y (H)
; + 6 Y (L)
; + 7 PC(H)
; + 8 PC(L)
;
; 3) The stack frame of the task to resume looks as follows:
;
; OSTCBHighRdy->OSTCBStkPtr + 0 --> CCR
; + 1 B
; + 2 A
; + 3 X (H)
; + 4 X (L)
; + 5 Y (H)
; + 6 Y (L)
; + 7 PC(H)
; + 8 PC(L)
;********************************************************************************************************
OSCtxSw:
ldx OSTCBCur ; 3~, Point to current task's TCB
sts 0,x ; 3~, Save stack pointer in preempted task's TCB
jsr OSTaskSwHook ; 4~, Call user task switch hook
ldx OSTCBHighRdy ; 3~, OSTCBCur = OSTCBHighRdy
stx OSTCBCur ; 3~
ldab OSPrioHighRdy ; 3~, OSPrioCur = OSPrioHighRdy
stab OSPrioCur ; 3~
lds 0,x ; 3~, Load SP into 68HC12
rti ; 8~, Run task
;********************************************************************************************************
; INTERRUPT LEVEL CONTEXT SWITCH
;
; Description : This function is called by OSIntExit() to perform a context switch to a task that has
; been made ready-to-run by an ISR.
;
; Arguments : none
;
; Note(s) : 1) Stack frame upon entry (Assuming OS_CRITICAL_METHOD is 1):
;
; ---- SP + 0 -> PC(H) \ Return address from call to OSIntCtxSw()
; SP Adjustment | SP + 1 -> PC(L) /
; (+4) | SP + 2 -> PC(H) \ Return address from call to OSIntExit()
; | SP + 3 -> PC(L) /
; --> SP + 4 -> CCR \
; SP + 5 -> B |
; SP + 6 -> A |
; SP + 7 -> X(H) | Stack frame from interrupt stacking.
; SP + 8 -> X(L) |
; SP + 9 -> Y(H) |
; SP + 10 -> Y(L) |
; SP + 11 -> PC(H) |
; SP + 12 -> PC(L) /
;********************************************************************************************************
OSIntCtxSw:
leas 4,sp ; 2~, Clean up stack (Uncomment if OS_CRITICAL_METHOD is 1)
; leas 5,sp ; 2~, Clean up stack (Uncomment if OS_CRITICAL_METHOD is 2)
ldx OSTCBCur ; 3~, OSTCBCur->OSTCBStkPtr = Stack Pointer
sts 0,x ; 3~,
jsr OSTaskSwHook ; 4~, Call user task switch hook
ldx OSTCBHighRdy ; 3~, OSTCBCur = OSTCBHighRdy
stx OSTCBCur ; 3~
ldab OSPrioHighRdy ; 3~, OSPrioCur = OSPrioHighRdy
stab OSPrioCur ; 3~
lds 0,x ; 3~, Load SP into 68HC12
rti ; 8~, Run task
;********************************************************************************************************
; SYSTEM TICK ISR
;
; Description : This function is the ISR used to notify uC/OS-II that a system tick has occurred. You
; must setup the 68HC12's interrupt vector table so that an OUTPUT COMPARE interrupt
; vectors to this function.
;
; Arguments : none
;
; Notes : 1) The 'tick ISR' assumes the we are using the Output Compare specified by OS_TICK_OC
; (see OS_CFG.H and this file) to generate a tick that occurs every OS_TICK_OC_CNTS
; (see OS_CFG.H and this file) which corresponds to the number of FRT (Free Running
; Timer) counts to the next interrupt.
;
; 2) You must specify which output compare will be used by the tick ISR as follows:
; Set OS_TICK_OC in OS_CFG.H (AND in this file) to 0 to use OUTPUT COMPARE #0
; Set OS_TICK_OC in OS_CFG.H (AND in this file) to 1 to use OUTPUT COMPARE #1
; Set OS_TICK_OC in OS_CFG.H (AND in this file) to 2 to use OUTPUT COMPARE #2
; Set OS_TICK_OC in OS_CFG.H (AND in this file) to 3 to use OUTPUT COMPARE #3
; Set OS_TICK_OC in OS_CFG.H (AND in this file) to 4 to use OUTPUT COMPARE #4
; Set OS_TICK_OC in OS_CFG.H (AND in this file) to 5 to use OUTPUT COMPARE #5
; Set OS_TICK_OC in OS_CFG.H (AND in this file) to 6 to use OUTPUT COMPARE #6
; Set OS_TICK_OC in OS_CFG.H (AND in this file) to 7 to use OUTPUT COMPARE #7
;
; 3) TFLG1, TC0 ... TC7 are defined in this file.
;********************************************************************************************************
OSTickISR:
inc OSIntNesting ; 4~, Notify uC/OS-II about ISR
if OS_TICK_OC == 0
ldab #$01 ; 2~, Clear C0F interrupt flag (bit 0)
stab TFLG1 ; 4~
ldd TC0 ; 5~, Set TC0 to present time + desired counts to next ISR
addd #OS_TICK_OC_CNTS ; 4~
std TC0 ; 5~
endif
if OS_TICK_OC == 1
ldab #$02 ; 2~, Clear C1F interrupt flag (bit 1)
stab TFLG1 ; 4~
ldd TC1 ; 5~, Set TC1 to present time + desired counts to next ISR
addd #OS_TICK_OC_CNTS ; 4~
std TC1 ; 5~
endif
if OS_TICK_OC == 2
ldab #$04 ; 2~, Clear C2F interrupt flag (bit 2)
stab TFLG1 ; 4~
ldd TC2 ; 5~, Set TC2 to present time + desired counts to next ISR
addd #OS_TICK_OC_CNTS ; 4~
std TC2 ; 5~
endif
if OS_TICK_OC == 3
ldab #$08 ; 2~, Clear C3F interrupt flag (bit 3)
stab TFLG1 ; 4~
ldd TC3 ; 5~, Set TC3 to present time + desired counts to next ISR
addd #OS_TICK_OC_CNTS ; 4~
std TC3 ; 5~
endif
if OS_TICK_OC == 4
ldab #$10 ; 2~, Clear C4F interrupt flag (bit 4)
stab TFLG1 ; 4~
ldd TC4 ; 5~, Set TC4 to present time + desired counts to next ISR
addd #OS_TICK_OC_CNTS ; 4~
std TC4 ; 5~
endif
if OS_TICK_OC == 5
ldab #$20 ; 2~, Clear C5F interrupt flag (bit 5)
stab TFLG1 ; 4~
ldd TC5 ; 5~, Set TC5 to present time + desired counts to next ISR
addd #OS_TICK_OC_CNTS ; 4~
std TC5 ; 5~
endif
if OS_TICK_OC == 6
ldab #$40 ; 2~, Clear C6F interrupt flag (bit 6)
stab TFLG1 ; 4~
ldd TC6 ; 5~, Set TC6 to present time + desired counts to next ISR
addd #OS_TICK_OC_CNTS ; 4~
std TC6 ; 5~
endif
if OS_TICK_OC == 7
ldab #$80 ; 2~, Clear C7F interrupt flag (bit 7)
stab TFLG1 ; 4~
ldd TC7 ; 5~, Set TC7 to present time + desired counts to next ISR
addd #OS_TICK_OC_CNTS ; 4~
std TC7 ; 5~
endif
cli ; 2~, Enable interrupts to allow interrupt nesting
jsr OSTimeTick ; 6~+, Call uC/OS-II's tick updating function
jsr OSIntExit ; 6~+, Notify uC/OS-II about end of ISR
rti ; 12~, Return from interrupt, no higher priority tasks ready.
_Null
stop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -