📄 本人改写的在c8051f124上运行的ucos源码,大家交流一下--电子门.htm
字号:
register<BR>EA BIT 0A8H.7<BR>SP DATA 081H<BR>B DATA 0F0H<BR>ACC DATA 0E0H<BR>DPH DATA 083H<BR>DPL DATA 082H<BR>PSW DATA 0D0H<BR>TR0 BIT 088H.4<BR>TF0 BIT 088H.5<BR>TH0 DATA 08CH<BR>TL0 DATA 08AH<BR>PSBANK DATA 0B1H<BR><BR>SFRPAGE DATA 084H<BR><BR> NAME
OS_CPU_A ;模块名<BR> <BR>;定义重定位段<BR>?PR?OSStartHighRdy?OS_CPU_A SEGMENT
CODE<BR>?PR?OSCtxSw?OS_CPU_A SEGMENT
CODE<BR>?PR?OSIntCtxSw?OS_CPU_A SEGMENT
CODE<BR>?PR?OSTickISR?OS_CPU_A SEGMENT
CODE<BR><BR> <BR>;声明引用全局变量和外部子程序<BR> EXTRN
DATA (?C_XBP) ;仿真堆栈指针用于重入局部变量保存<BR><BR> EXTRN
IDATA
(OSTCBCur)<BR> EXTRN
IDATA
(OSTCBHighRdy)<BR> EXTRN
IDATA
(OSRunning)<BR> EXTRN
IDATA
(OSPrioCur)<BR> EXTRN
IDATA
(OSPrioHighRdy)<BR>; extrn data(__SP) ;
CC51 Virtual Stack
Pointer<BR><BR> EXTRN
CODE (_?OSTaskSwHook)<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> <BR>;分配堆栈空间。只关心大小,堆栈起点由keil决定,通过标号可以获得keil分配的SP起点。<BR>?STACK
SEGMENT
IDATA ;
?STACK goes into idata
ram<BR> RSEG
?STACK ;
switch to ?STACK
segment<BR>OSStack:<BR> DS
40H ;
reserve 40H bytes for stack space<BR>OSStkStart
IDATA
OSStack-1<BR><BR>;定义压栈出栈宏<BR>PUSHALL MACRO<BR> PUSH
PSBANK<BR> PUSH
SFRPAGE<BR> PUSH
PSW<BR> PUSH
ACC<BR> PUSH
B<BR> PUSH
DPL<BR> PUSH
DPH<BR><BR> PUSH
AR0<BR> PUSH
AR1<BR> PUSH
AR2<BR> PUSH
AR3<BR> PUSH
AR4<BR> PUSH
AR5<BR> PUSH
AR6<BR> PUSH
AR7<BR><BR><BR><BR> ENDM<BR> <BR>POPALL MACRO<BR><BR> POP AR7<BR> POP AR6<BR> POP AR5<BR> POP AR4<BR> POP AR3<BR> POP AR2<BR> POP AR1<BR> POP AR0<BR><BR><BR> POP DPH<BR> POP DPL<BR> POP B<BR> POP ACC<BR> POP PSW<BR> POP SFRPAGE<BR> POP PSBANK<BR> ENDM<BR> <BR><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第178页 <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> ;恢复仿真堆栈指针?C_XBP <BR> INC DPTR<BR> MOVX
A,@DPTR<BR> MOV ?C_XBP,A ;?C_XBP
仿真堆栈指针高8位<BR> INC DPTR<BR> MOVX
A,@DPTR<BR> MOV ?C_XBP+1,A ;?C_XBP
仿真堆栈指针低8位<BR> <BR> ;OSRunning=TRUE<BR> MOV R0,#LOW
(OSRunning)<BR> MOV @R0,#01<BR> <BR> POPALL<BR> SETB
EA ;开中断<BR> RETI<BR><BR><BR><BR><BR><BR><BR>;-------------------------------------------------------------------------<BR> RSEG
?PR?OSCtxSw?OS_CPU_A<BR>OSCtxSw: <BR> nop<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> ;保存仿真堆栈指针?C_XBP<BR> INC DPTR<BR> MOV A,?C_XBP ;?C_XBP
仿真堆栈指针高8位<BR> MOVX
@DPTR,A<BR> INC DPTR<BR> MOV A,?C_XBP+1 ;?C_XBP
仿真堆栈指针低8位<BR> MOVX
@DPTR,A <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> <BR> LJMP
OSIntCtxSw_in<BR><BR><BR><BR>;-------------------------------------------------------------------------<BR> CSEG
AT
000BH ;OSTickISR<BR> LJMP
OSTickISR ;使用定时器0<BR> RSEG
?PR?OSTickISR?OS_CPU_A<BR><BR>OSTickISR: <BR> <BR> USING
0 <BR> PUSHALL<BR><BR> PUSH
SFRPAGE<BR> MOV SFRPAGE,
#0<BR> CLR TR0<BR> MOV TH0,#70H ;定义Tick=50次/秒(即0.02秒/次)<BR> MOV TL0,#00H ;OS_CPU_C.C 和 OS_TICKS_PER_SEC<BR> CLR TF0<BR> SETB
TR0<BR> POP SFRPAGE<BR> <BR> LCALL
_?OSIntEnter<BR> LCALL
_?OSTimeTick<BR> LCALL
_?OSIntExit ;
在这里判断是否调用OSIntCtxSw,详见OSIntExit函数<BR> POPALL <BR> RETI<BR><BR><BR><BR><BR><BR>;-------------------------------------------------------------------------<BR> END<BR>;-------------------------------------------------------------------------<BR><BR><BR><BR>OS_CPU_C.c:<BR>/*<BR>*********************************************************************************************************<BR>* uC/OS-II<BR>* 实时内核<BR>*<BR>* (c)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -