Demo程序经Keil701编译后,代码量为7-8K,可直接在KeilC51上仿真运行。 编译时要将OS_CPU_C.C、UCOS_II.C、OS_CPU_A.ASM、YY.C加入项目 以上是我这次移植uCOS51的一些心得,写出来只是让准备在51上运行操作系统的同行们少走弯路并增强使用信心。我强烈推荐大家在自己的51系统中使用uCOS这个简单实用的自己的操作系统。它的大小应该不是问题,性能上的提高却是显著的。但愿此文能对朋友们有所帮助,错误在所难免,希望各位大虾指正,诸位高手们见笑了! 注:全部源码可来信索要(asdjf@163.com),以下仅为关键代码部分。 文件名 : OS_CPU_A.ASM $NOMOD51 EA BIT 0A8H.7 SP DATA 081H B DATA 0F0H ACC DATA 0E0H DPH DATA 083H DPL DATA 082H PSW DATA 0D0H TR0 BIT 088H.4 TH0 DATA 08CH TL0 DATA 08AH NAME OS_CPU_A ;模块名 ;定义重定位段 ?PR?OSStartHighRdy?OS_CPU_A SEGMENT CODE ?PR?OSCtxSw?OS_CPU_A SEGMENT CODE ?PR?OSIntCtxSw?OS_CPU_A SEGMENT CODE ?PR?OSTickISR?OS_CPU_A SEGMENT CODE ?PR?_?serial?OS_CPU_A SEGMENT CODE ;声明引用全局变量和外部子程序 EXTRN IDATA (OSTCBCur) EXTRN IDATA (OSTCBHighRdy) EXTRN IDATA (OSRunning) EXTRN IDATA (OSPrioCur) EXTRN IDATA (OSPrioHighRdy) EXTRN CODE (_?OSTaskSwHook) EXTRN CODE (_?serial) EXTRN CODE (_?OSIntEnter) EXTRN CODE (_?OSIntExit) EXTRN CODE (_?OSTimeTick) ;对外声明4个不可重入函数 PUBLIC OSStartHighRdy PUBLIC OSCtxSw PUBLIC OSIntCtxSw PUBLIC OSTickISR ;PUBLIC SerialISR ;分配堆栈空间。只关心大小,堆栈起点由keil决定,通过标号可以获得keil分配的SP起点。 ?STACK SEGMENT IDATA RSEG ?STACK OSStack: DS 40H OSStkStart IDATA OSStack-1 ;定义压栈出栈宏 PUSHALL MACRO PUSH PSW PUSH ACC PUSH B PUSH DPL PUSH DPH MOV A,R0 ;R0-R7入栈 PUSH ACC MOV A,R1 PUSH ACC MOV A,R2 PUSH ACC MOV A,R3 PUSH ACC MOV A,R4 PUSH ACC MOV A,R5 PUSH ACC MOV A,R6 PUSH ACC MOV A,R7 PUSH ACC ;PUSH SP ;不必保存SP,任务切换时由相应程序调整 ENDM POPALL MACRO ;POP ACC ;不必保存SP,任务切换时由相应程序调整 POP ACC ;R0-R7出栈 MOV R7,A POP ACC MOV R6,A POP ACC MOV R5,A POP ACC MOV R4,A POP ACC MOV R3,A POP ACC MOV R2,A POP ACC MOV R1,A POP ACC MOV R0,A POP DPH POP DPL POP B POP ACC POP PSW ENDM ;子程序 ;------------------------------------------------------------------------- RSEG ?PR?OSStartHighRdy?OS_CPU_A OSStartHighRdy: USING 0 ;上电后51自动关中断,此处不必用CLR EA指令,因为到此处还未开中断,本程序退出后,开中断。 LCALL _?OSTaskSwHook OSCtxSw_in: ;OSTCBCur ===> DPTR 获得当前TCB指针,详见C51.PDF第178页 MOV R0,#LOW (OSTCBCur) ;获得OSTCBCur指针低地址,指针占3字节。+0类型+1高8位数据+2低8位数据 INC R0 MOV DPH,@R0 ;全局变量OSTCBCur在IDATA中 INC R0 MOV DPL,@R0 ;OSTCBCur->OSTCBStkPtr ===> DPTR 获得用户堆栈指针 INC DPTR ;指针占3字节。+0类型+1高8位数据+2低8位数据 MOVX A,@DPTR ;.OSTCBStkPtr是void指针 MOV R0,A INC DPTR MOVX A,@DPTR MOV R1,A MOV DPH,R0 MOV DPL,R1 ;*UserStkPtr ===> R5 用户堆栈起始地址内容(即用户堆栈长度放在此处) 详见文档说明 指针用法详见C51.PDF第169页 MOVX A,@DPTR ;用户堆栈中是unsigned char类型数据 MOV R5,A ;R5=用户堆栈长度 ;恢复现场堆栈内容 MOV R0,#OSStkStart restore_stack: INC DPTR INC R0 MOVX A,@DPTR MOV @R0,A DJNZ R5,restore_stack ;恢复堆栈指针SP MOV SP,R0 ;OSRunning=TRUE MOV R0,#LOW (OSRunning) MOV @R0,#01 POPALL SETB EA ;开中断 RETI ;------------------------------------------------------------------------- RSEG ?PR?OSCtxSw?OS_CPU_A OSCtxSw: PUSHALL OSIntCtxSw_in: ;获得堆栈长度和起址 MOV A,SP CLR C SUBB A,#OSStkStart MOV R5,A ;获得堆栈长度 ;OSTCBCur ===> DPTR 获得当前TCB指针,详见C51.PDF第178页 MOV R0,#LOW (OSTCBCur) ;获得OSTCBCur指针低地址,指针占3字节。+0类型+1高8位数据+2低8位数据 INC R0 MOV DPH,@R0 ;全局变量OSTCBCur在IDATA中 INC R0 MOV DPL,@R0 ;OSTCBCur->OSTCBStkPtr ===> DPTR 获得用户堆栈指针 INC DPTR ;指针占3字节。+0类型+1高8位数据+2低8位数据 MOVX A,@DPTR ;.OSTCBStkPtr是void指针 MOV R0,A INC DPTR MOVX A,@DPTR MOV R1,A MOV DPH,R0 MOV DPL,R1 ;保存堆栈长度 MOV A,R5 MOVX @DPTR,A MOV R0,#OSStkStart ;获得堆栈起址 save_stack: INC DPTR INC R0 MOV A,@R0 MOVX @DPTR,A DJNZ R5,save_stack ;调用用户程序 LCALL _?OSTaskSwHook ;OSTCBCur = OSTCBHighRdy MOV R0,#OSTCBCur MOV R1,#OSTCBHighRdy MOV A,@R1 MOV @R0,A INC R0 INC R1 MOV A,@R1 MOV @R0,A INC R0 INC R1 MO 上一页 [1] [2] [3] [4] 下一页
Tags:
|