📄 ucos51移植心得.htm
字号:
CODE<BR>?PR?OSTickISR?OS_CPU_A SEGMENT
CODE<BR><BR>?PR?_?serial?OS_CPU_A SEGMENT
CODE<BR> <BR>;声明引用全局变量和外部子程序<BR> EXTRN
IDATA (OSTCBCur)<BR> EXTRN
IDATA
(OSTCBHighRdy)<BR> EXTRN
IDATA (OSRunning)<BR> EXTRN
IDATA (OSPrioCur)<BR> EXTRN
IDATA
(OSPrioHighRdy)<BR> <BR> EXTRN
CODE (_?OSTaskSwHook)<BR> EXTRN
CODE (_?serial)<BR> EXTRN
CODE (_?OSIntEnter)<BR> EXTRN
CODE (_?OSIntExit)<BR> EXTRN
CODE (_?OSTimeTick) <BR> <BR>;对外声明4个不可重入函数<BR> PUBLIC
OSStartHighRdy<BR> PUBLIC
OSCtxSw<BR> PUBLIC
OSIntCtxSw<BR> PUBLIC
OSTickISR<BR> <BR> ;PUBLIC
SerialISR <BR> <BR>;分配堆栈空间。只关心大小,堆栈起点由keil决定,通过标号可以获得keil分配的SP起点。<BR>?STACK
SEGMENT IDATA<BR> RSEG
?STACK<BR>OSStack:<BR> DS
40H<BR>OSStkStart IDATA
OSStack-1<BR><BR>;定义压栈出栈宏<BR>PUSHALL MACRO<BR> PUSH
PSW<BR> PUSH
ACC<BR> PUSH
B<BR> PUSH
DPL<BR> PUSH
DPH<BR> MOV A,R0 ;R0-R7入栈<BR> PUSH
ACC<BR> MOV A,R1<BR> PUSH
ACC<BR> MOV A,R2<BR> PUSH
ACC<BR> MOV A,R3<BR> PUSH
ACC<BR> MOV A,R4<BR> PUSH
ACC<BR> MOV A,R5<BR> PUSH
ACC<BR> MOV A,R6<BR> PUSH
ACC<BR> MOV A,R7<BR> PUSH
ACC<BR> ;PUSH
SP ;不必保存SP,任务切换时由相应程序调整<BR> ENDM<BR> <BR>POPALL MACRO<BR> ;POP ACC ;不必保存SP,任务切换时由相应程序调整<BR> POP ACC ;R0-R7出栈<BR> MOV R7,A<BR> POP ACC<BR> MOV R6,A<BR> POP ACC<BR> MOV R5,A<BR> POP ACC<BR> MOV R4,A<BR> POP ACC<BR> MOV R3,A<BR> POP ACC<BR> MOV R2,A<BR> POP ACC<BR> MOV R1,A<BR> POP ACC<BR> MOV R0,A<BR> POP DPH<BR> POP DPL<BR> POP B<BR> POP ACC<BR> POP PSW<BR> ENDM<BR> <BR>;子程序<BR>;-------------------------------------------------------------------------<BR> RSEG
?PR?OSStartHighRdy?OS_CPU_A<BR>OSStartHighRdy:<BR> USING
0 ;上电后51自动关中断,此处不必用CLR
EA指令,因为到此处还未开中断,本程序退出后,开中断。<BR> LCALL
_?OSTaskSwHook<BR><BR>OSCtxSw_in:<BR> <BR> ;OSTCBCur
===>
DPTR 获得当前TCB指针,详见C51.PDF第178页<BR> MOV R0,#LOW
(OSTCBCur)
;获得OSTCBCur指针低地址,指针占3字节。+0类型+1高8位数据+2低8位数据<BR> INC R0<BR> MOV DPH,@R0 ;全局变量OSTCBCur在IDATA中<BR> INC R0<BR> MOV DPL,@R0<BR> <BR> ;OSTCBCur->OSTCBStkPtr
===>
DPTR 获得用户堆栈指针<BR> INC DPTR ;指针占3字节。+0类型+1高8位数据+2低8位数据<BR> MOVX
A,@DPTR ;.OSTCBStkPtr是void指针<BR> MOV R0,A<BR> INC DPTR<BR> MOVX
A,@DPTR<BR> MOV R1,A<BR> MOV DPH,R0<BR> MOV DPL,R1<BR> <BR> ;*UserStkPtr
===>
R5 用户堆栈起始地址内容(即用户堆栈长度放在此处) 详见文档说明 指针用法详见C51.PDF第169页 <BR> MOVX
A,@DPTR ;用户堆栈中是unsigned
char类型数据<BR> MOV R5,A ;R5=用户堆栈长度<BR> <BR> ;恢复现场堆栈内容<BR> MOV R0,#OSStkStart<BR> <BR>restore_stack:<BR> <BR> INC DPTR<BR> INC R0<BR> MOVX
A,@DPTR<BR> MOV @R0,A<BR> DJNZ
R5,restore_stack<BR> <BR> ;恢复堆栈指针SP<BR> MOV SP,R0<BR> <BR> ;OSRunning=TRUE<BR> MOV R0,#LOW
(OSRunning)<BR> MOV @R0,#01<BR> <BR> POPALL<BR> SETB
EA ;开中断<BR> RETI<BR>;-------------------------------------------------------------------------<BR> RSEG
?PR?OSCtxSw?OS_CPU_A<BR>OSCtxSw: <BR> PUSHALL<BR> <BR>OSIntCtxSw_in:<BR> <BR> ;获得堆栈长度和起址<BR> MOV A,SP<BR> CLR C<BR> SUBB
A,#OSStkStart<BR> MOV R5,A ;获得堆栈长度 <BR> <BR> ;OSTCBCur
===>
DPTR 获得当前TCB指针,详见C51.PDF第178页<BR> MOV R0,#LOW
(OSTCBCur)
;获得OSTCBCur指针低地址,指针占3字节。+0类型+1高8位数据+2低8位数据<BR> INC R0<BR> MOV DPH,@R0 ;全局变量OSTCBCur在IDATA中<BR> INC R0<BR> MOV DPL,@R0<BR> <BR> ;OSTCBCur->OSTCBStkPtr
===>
DPTR 获得用户堆栈指针<BR> INC DPTR ;指针占3字节。+0类型+1高8位数据+2低8位数据<BR> MOVX
A,@DPTR ;.OSTCBStkPtr是void指针<BR> MOV R0,A<BR> INC DPTR<BR> MOVX
A,@DPTR<BR> MOV R1,A<BR> MOV DPH,R0<BR> MOV DPL,R1<BR> <BR> ;保存堆栈长度<BR> MOV A,R5<BR> MOVX
@DPTR,A<BR> <BR> MOV R0,#OSStkStart ;获得堆栈起址<BR>save_stack:<BR> <BR> INC DPTR<BR> INC R0<BR> MOV A,@R0<BR> MOVX
@DPTR,A<BR> DJNZ
R5,save_stack<BR> <BR> ;调用用户程序<BR> LCALL
_?OSTaskSwHook<BR> <BR> ;OSTCBCur
=
OSTCBHighRdy<BR> MOV R0,#OSTCBCur<BR> MOV R1,#OSTCBHighRdy<BR> MOV A,@R1<BR> MOV @R0,A<BR> INC R0<BR> INC R1<BR> MOV A,@R1<BR> MOV @R0,A<BR> INC R0<BR> INC R1<BR> MOV A,@R1<BR> MOV @R0,A<BR> <BR> ;OSPrioCur
=
OSPrioHighRdy 使用这两个变量主要目的是为了使指针比较变为字节比较,以便节省时间。<BR> MOV R0,#OSPrioCur<BR> MOV R1,#OSPrioHighRdy<BR> MOV A,@R1<BR> MOV @R0,A<BR> <BR> LJMP
OSCtxSw_in<BR>;-------------------------------------------------------------------------<BR> RSEG
?PR?OSIntCtxSw?OS_CPU_A<BR> <BR>OSIntCtxSw:<BR><BR> ;调整SP指针去掉在调用OSIntExit(),OSIntCtxSw()过程中压入堆栈的多余内容<BR> ;SP=SP-4<BR><BR> MOV A,SP<BR> CLR C<BR> SUBB
A,#4<BR> MOV SP,A<BR> <BR> LJMP
OSIntCtxSw_in<BR>;-------------------------------------------------------------------------<BR> CSEG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -