📄 ucos-ii的移植代码 for 8051.txt
字号:
;?STACK:
Stack:
DS 40
EXTRN BIT (OSRunning)
EXTRN XDATA (OSIntNesting)
; EXTRN XDATA (OSTickDOSCtr)
EXTRN XDATA (OSPrioHighRdy)
EXTRN XDATA (OSPrioCur)
EXTRN XDATA (OSTCBCur)
EXTRN XDATA (OSTCBHighRdy)
;*******************************************************************************
*************************
; MACRO DEFINE
;*******************************************************************************
*************************
PUSHALL MACRO
;PUSH PC
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
PUSH PSW
IRP REG, <R7, R6, R5, R4, R3, R2, R1, R0>
MOV A, REG
PUSH ACC
ENDM
ENDM
POPALL MACRO
IRP REG, <R0, R1, R2, R3, R4, R5, R6, R7>
POP ACC
MOV REG, A
ENDM
POP PSW
POP DPL
POP DPH
POP B
POP ACC
;RET/RETI
ENDM
OS_ENTER_CRITICAL MACRO
MOV B,IE ;因为所有程序没有使用
B寄存器,所以使用了B寄存器作为IE暂存
CLR EA
ENDM
OS_EXIT_CRITICAL MACRO
MOV IE,B ;因为所有程序没有使用
B寄存器,所以使用了B寄存器作为IE暂存
ENDM
;*******************************************************************************
*************************
; 供外部使用的函数
;*******************************************************************************
*************************
PUBLIC _?OSTickISR
PUBLIC _?OSStartHighRdy
PUBLIC _?OSCtxSw
PUBLIC _?OSIntCtxSw
/*$PAGE*/
;*******************************************************************************
*************************
; 函数体段
;*******************************************************************************
*************************
;*******************************************************************************
**************************
; 用户中断程序区 之 定时器中断
1 OSISR_T1()
;*******************************************************************************
**************************
IF OS_ISR_T1_EN <> 0
CSEG AT 001BH ;设置T0中断向量
LJMP _OSISR_T1
?PR?_OSISR_T1?OS_CPU_A SEGMENT CODE
RSEG ?PR?_OSISR_T1?OS_CPU_A
_OSISR_T1:
OS_ENTER_CRITICAL
;(1)保存处理器寄存器 先PUSH到SP在COPY到?C_XBP
PUSHALL
LCALL _CopySPtoC_XBP ;COPY SP 的内容到?
C_XBP
;(2)记忆中断的嵌套层OSIntNesting++ 进入中断
;(3) if (OSIntNesting == 1)
; OSTCBCur->OSTCBStkPtr <= ?C_XBP
LCALL _Enter_INT
OS_EXIT_CRITICAL
;(4)调用中断服务外挂
LCALL _?OSISR_T1HOOK ;在这里进行中断服务
OS_ENTER_CRITICAL
;(5) Call OSTimeTick();
LCALL _?OSTimeTick
;(6) Call OSIntExit();
LCALL _?OSIntExit
;(7) 恢复处理器寄存器 ;没有高优先级任务在就
绪队列中
;LCALL _ComCtxSw2
LCALL _CopyC_XBPtoSP
POPALL
OS_EXIT_CRITICAL
RETI
ENDIF
;*******************************************************************************
**************************
; 用户中断程序区 之 外部中断0
OSISR_INT0()
;*******************************************************************************
**************************
IF OS_ISR_INT0_EN <> 0
CSEG AT 0003H ;设置T0中断向量
LJMP _OSISR_INT0
?PR?_OSISR_INT0?OS_CPU_A SEGMENT CODE
RSEG ?PR?_OSISR_INT0?OS_CPU_A
_OSISR_INT0:
OS_ENTER_CRITICAL
;(1)保存处理器寄存器 先PUSH到SP在COPY到?C_XBP
PUSHALL
LCALL _CopySPtoC_XBP ;COPY SP 的内容到?
C_XBP
;(2)记忆中断的嵌套层OSIntNesting++ 进入中断
;(3) if (OSIntNesting == 1)
; OSTCBCur->OSTCBStkPtr <= ?C_XBP
LCALL _Enter_INT
OS_EXIT_CRITICAL
;(4)调用中断服务外挂
LCALL _?OSISR_INT0HOOK ;在这里进行中断服务
OS_ENTER_CRITICAL
;(5) Call OSTimeTick();
LCALL _?OSTimeTick
;(6) Call OSIntExit();
LCALL _?OSIntExit
;(7) 恢复处理器寄存器 ;没有高优先级任务在就绪队列中
;LCALL _ComCtxSw2
LCALL _CopyC_XBPtoSP
POPALL
OS_EXIT_CRITICAL
RETI
ENDIF
;*******************************************************************************
**************************
; 用户中断程序区 之 外部中断1
OSISR_INT1()
;*******************************************************************************
**************************
IF OS_ISR_INT1_EN <> 0
CSEG AT 0013H ;设置T0中断向量
LJMP _OSISR_INT1
?PR?_OSISR_INT1?OS_CPU_A SEGMENT CODE
RSEG ?PR?_OSISR_INT1?OS_CPU_A
_OSISR_INT1:
OS_ENTER_CRITICAL
;(1)保存处理器寄存器 先PUSH到SP在COPY到?C_XBP
PUSHALL
LCALL _CopySPtoC_XBP ;COPY SP 的内容到?
C_XBP
;(2)记忆中断的嵌套层OSIntNesting++ 进入中断
;(3) if (OSIntNesting == 1)
; OSTCBCur->OSTCBStkPtr <= ?C_XBP
LCALL _Enter_INT
OS_EXIT_CRITICAL
;(4)调用中断服务外挂
LCALL _?OSISR_INT1HOOK ;在这里进行中断服务
OS_ENTER_CRITICAL
;(5) Call OSTimeTick();
LCALL _?OSTimeTick
;(6) Call OSIntExit();
LCALL _?OSIntExit
;(7) 恢复处理器寄存器 ;没有高优先级任务在就绪队列中
;LCALL _ComCtxSw2
LCALL _CopyC_XBPtoSP
POPALL
OS_EXIT_CRITICAL
RETI
ENDIF
;*******************************************************************************
**************************
; 用户中断程序区 之 串口中断0
OSISR_S0()
;*******************************************************************************
**************************
IF OS_ISR_S0_EN <> 0
CSEG AT 0023H ;设置T0中断向量
LJMP _OSISR_S0
?PR?_OSISR_S0?OS_CPU_A SEGMENT CODE
RSEG ?PR?_OSISR_S0?OS_CPU_A
_OSISR_S0:
OS_ENTER_CRITICAL
;(1)保存处理器寄存器 先PUSH到SP在COPY到?C_XBP
PUSHALL
LCALL _CopySPtoC_XBP ;COPY SP 的内容到?
C_XBP
;(2)记忆中断的嵌套层OSIntNesting++ 进入中断
;(3) if (OSIntNesting == 1)
; OSTCBCur->OSTCBStkPtr <= ?C_XBP
LCALL _Enter_INT
OS_EXIT_CRITICAL
;(4)调用中断服务外挂
LCALL _?OSISR_S0HOOK ;在这里进行中断服务
OS_ENTER_CRITICAL
;(5) Call OSTimeTick();
LCALL _?OSTimeTick
;(6) Call OSIntExit();
LCALL _?OSIntExit
;(7) 恢复处理器寄存器 ;没有高优先级任务在就绪队列中
;LCALL _ComCtxSw2
LCALL _CopyC_XBPtoSP
POPALL
OS_EXIT_CRITICAL
RETI
ENDIF
[dvnews_page=OS_CPU_A.ASM之的内核代码部分1]
;*******************************************************************************
**************************
; START MULTITASKING
; void OSStartHighRdy(void) LG_REENTRANT
;出栈后就意味着启动了第一个任务
; The stack frame is assumed to look as follows:
;
; 出 /\ 出栈:task
底\高 (高内存)
; 栈 || 出栈:ACC
; 顺 || 出栈:B
; 序 || 出栈:DPH
//暂时忽略第二指针
; | || | 出栈:DPL
; | | 出栈:PSW
; |______________| 出栈:R7-R4
; 出栈:
os_pdata(R3,R2,R1)用寄存器传递os_pdata
; OSTCBHighRdy->OSTCBStkPtr --> 出栈:R0
(底内存)
;
; Note : OSStartHighRdy() MUST:
; a) Call OSTaskSwHook() then,
; b) Set OSRunning to TRUE,
; c) Switch to the highest priority task.
;*******************************************************************************
**************************
?PR?_?OSStartHighRdy?OS_CPU_A SEGMENT CODE
;第3个问号表示重入函
数
RSEG ?PR?_?OSStartHighRdy?OS_CPU_A ;函数体段
_?OSStartHighRdy:
USING 0
;OS_ENTER_CRITICAL
LCALL _?OSTaskSwHook ;调用OSTaskSwHook();
SETB OSRunning ;OSRunning= TRUE;
;切换到最高优先级的任务
JMP CtxSw ;MOV ?C_XBP,0
;*******************************************************************************
**************************
; PERFORM A CONTEXT SWITCH (From task level)
; void OSCtxSw(void)
;
; 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 -> OFFSET of task to suspend (Low memory)
; SEGMENT of task to suspend
; PSW of task to suspend (High memory)
;
; 3) The stack frame of the task to resume looks as follows:
;
; 出 /\ 用RET 出栈:task底\高地址 (高内存)
; 栈 || 出栈:ACC
; 顺 || 出栈:B
; 序 || 出栈:DPH
//暂时忽略第二指针
; | || | 出栈:DPL
; | | 出栈:PSW
; |______________| 出栈:R0
; 出栈:os_pdata
(R1,R2,R3)用寄存器传递os_pdata
; OSTCBHighRdy->OSTCBStkPtr --> 出栈:R4-R7
(底内存)
; Flags to load in
PSW (High memory)
;任务级切换:
;1:PUSHALL
;2:?C_BXP<=(SP)
;3:OSTCBCur->OSTCBStkPtr<=?C_BXP
;4: ...
;5:?C_BXP<=OSTCBHighRdy->OSTCBStkPtr
;6:(SP)<=?C_BXP
;7:POPALL
;8:RET
;*******************************************************************************
**************************
?PR?_?OSCtxSw?OS_CPU_A SEGMENT CODE
RSEG ?PR?_?OSCtxSw?OS_CPU_A
_?OSCtxSw:
USING 0
;OS_ENTER_CRITICAL
;(1)保存处理器的寄存器
PUSHALL
;(2)拷贝SP(系统)堆栈中的内容到?C_XBP, SP 满向上
;然后清空它(即MOV SP,#?STACK-1) ?C_XBP 满向下
LCALL _CopySPtoC_XBP ;COPY SP 的内容到?
C_XBP
;(3)在当前任务的任务控制块中保存当前任务(旧任务)的堆栈指针
;OSTCBCur->OSTCBStkPtr=?C_XBP
MOV DPH,#HIGH(OSTCBCur)
MOV DPL, #LOW(OSTCBCur)
INC DPTR ;指针是3字节的
把我害死了
MOVX A,@DPTR
MOV R1,A
INC DPTR
MOVX A,@DPTR
MOV DPH,R1
MOV DPL,A
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -