UCOSII 252在C8051F020上的移植之.docx
- 文档编号:4360790
- 上传时间:2022-11-30
- 格式:DOCX
- 页数:13
- 大小:20.43KB
UCOSII 252在C8051F020上的移植之.docx
《UCOSII 252在C8051F020上的移植之.docx》由会员分享,可在线阅读,更多相关《UCOSII 252在C8051F020上的移植之.docx(13页珍藏版)》请在冰豆网上搜索。
UCOSII252在C8051F020上的移植之
UCOS-II2.52在C8051F020上的移植之
详细实操步骤及相关重要源码
步骤1:
STARTUP.A51中IDATALEN定义为内部RAM的大小0FFH(理论上大小是256字节,但是后面的初始化程序中要将该长度赋给8位的R0寄存器,所以不能赋100H),XDATALEN为外部RAM大小1000H(4K字节),XBPSTACK为1为large模式下可重入函数堆栈,XBPSTACKTOP为1000H(最高地址加1),在进入C程序之前不调用?
B_SWITCH0函数。
步骤2:
INCLUDES.H中包含应用中需要使用的所有头文件和全局宏定义。
先包含系统头文件,然后定义KCREENTRANT,再顺序包含OS_CPU.H(数据类型的定义(包括OS_STK和OS_CPU_SR)、进出临界区的宏定义,OS_ISR_PROTO_EXT、OS_TASK_SW()、OS_STK_GROWTH宏定义,OSCtxSw函数声明),OS_CFG.H(对系统需要使用的资源进行配置),UCOS_II.H,然后包含用户自己定义的头文件。
步骤3:
UCOS_II.H中将os_tcb结构中的指针变量OSTCBStkPtr、OSTCBNext、OSTCBPrev、OSTCBEventPtr的指针类型定义为xdata类型,如OS_STKxdata*OSTCBStkPtr;将系统的一些变量OSCtxSwCtr、OSIntNesting、OSIntExitY、OSLockNesting、OSPrioCur、OSPrioHighRdy、OSRdyGrp、OSTCBCur、OSTCBFreeList、OSTCBHighRdy、OSTCBList、OSTCBPrioTbl、OSTime定义为data型,如OS_EXTINT8UdataOSCtxSwCtr,存储在内部RAM中,访问速度快。
OSRunning原作者定义的是BOOLEAN型的,此处改为INT8U型的,方便程序设计,为OS_EXTINT8UdataOSRunning。
常量使用code将其存于Flash中,减少RAM占用量,如externINT8UconstcodeOSMapTbl[];externINT8UconstcodeOSUnMapTbl[];在OS_CORE.C中相应定义为INT8UconstcodeOSMapTbl[];INT8UconstcodeOSUnMapTbl[]。
步骤4:
OS_CPU_C.C文件中只有OSTaskStkInit必须实现,其他勾挂函数可以实现也可以不实现,为了不让编译器出警告,在带参数的函数中使用类似ptcb=ptcb;的形式的语句。
其中任务堆栈初始化函数是在任务建立的时候调用,它的实现依据用户的堆栈设计。
用户堆栈从低地址到高地址为:
堆栈长度、任务地址低8位、若无地址高8位、PSW、ACC、B、DPL、DPH、R0、R1、R2、R3、R4、R5、R6、R7、仿真堆栈高地址(?
C_XBP高8位)、仿真堆栈低地址(?
C_XBP低8位)。
仿真堆栈从高地址向低地址生长,从用户堆栈的最顶端开始往下生长。
如果不同任务的堆栈大小不一样,则需要分开处理,所以一般所有任务的堆栈长度都设置成一样,此处主要是初始化仿真堆栈栈顶指针为用户堆栈的最高地址。
仿真堆栈的实现细节不用了解,编译器会自动处理,需要时只需引用变量?
C_XBP(仿真堆栈栈顶指针)即可。
其他文档都说该变量在startup.a51中定义,但是startup.a51中却有EXTRNDATA(?
C_XBP)。
步骤5:
OS_CPU_A.A51主要实现OSStartHighRdy、OSCtxSw、OSIntCtxSw、OSTickISR四个不可重入函数。
其中OSStartHighRdy先调用勾挂函数_?
OSTaskSwHook,再由OSTCBCur指针获得用户堆栈指针OSTCBStkPtr,取得堆栈长度决定循环次数,将用户堆栈中的内容拷贝到硬件堆栈中,恢复堆栈指针SP(SP=长度+#STACK-1),恢复仿真堆栈指针?
C_XBP,置位OSRunning,所有寄存器出栈,开全局中断,执行中断返回指令。
OSCtxSw先将所有寄存器入栈,由OSTCBCur获得用户堆栈指针OSTCBStkPtr,取得堆栈长度决定循环次数,将系统硬件堆栈中的内容拷贝到用户堆栈,保存仿真堆栈指针?
C_XBP,调用勾挂函数_?
OSTaskSwHook,将就绪任务中最高优先级的TCB指针OSTCBHighRdy赋给OSTCBCur,将就绪任务中的最高优先级OSPrioHighRdy赋给OSPrioCur,调用OSStartHighRdy除_?
OSTaskSwHook外的程序。
OSIntCtxSw调整SP指针(去掉在调用OSIntExit(),OSIntCtxSw()过程中压入堆栈的多余内容),将堆栈指针SP减去4,然后调用OSCtxSw除去将所有寄存器入栈的程序。
OSTickISR将所有寄存器入栈,重载计数器的值,清除中断标志位,调用_?
OSIntEnter
、_?
OSTimeTick、_?
OSIntExit,将所有寄存器出栈,执行中断返回指令。
需将OSStartHighRdy、OSCtxSw、OSIntCtxSw、OSTickISR定义为可重定位段,形式为?
PR?
函数名?
模块名。
模块名为NAME指令后的符号名称。
步骤6:
将OS_CORE.C、OS_FLAG.C、OS_MBOX.C、OS_MEM.C、OS_MUTEX.C、OS_Q.C、OS_SEM.C、OS_TASK.C、OS_TIME.C、OS_CPU_C.C中除内部函数和在OS_CPU_A.asm中实现的四个函数(OSStartHighRdy、OSCtxSw、OSIntCtxSw、OSTickISR)外全声明为KCREENTRANT(该宏在INCLUDES.H中被定义为largereentrant,large指明编译模式为large模式(变量存在外部RAM中),reentrant说明该函数为可重入函数(UCOS-II移植的条件之一就是编译器能产生可重入代码))。
由于pdata和data是Keil的关键字,所以必须将所有函数中参数为pdata的都改为ppdata,data改为ddata。
附录1:
OS_CPU_A.A51源代码
;/*
;******************************************************************************
;*uC/OS-II
;*实时内核
;*
;*(c)Copyright1992-1998,JeanJ.Labrosse,Plantation,FL
;*版权所有
;*
;*MCU-51专用代码
;*KEILC51小模式编译
;*
;*文件名:
OS_CPU_A.ASM
;*作者:
JeanJ.Labrosse
;*改编:
杨屹************巨龙公司系统集成开发部2002.09.27
;******************************************************************************
;*/
$NOMOD51
EABIT0A8H.7
SPDATA081H
BDATA0F0H
ACCDATA0E0H
DPHDATA083H
DPLDATA082H
PSWDATA0D0H
TR0BIT088H.4
TF0BIT088H.5
TH0DATA08CH
TL0DATA08AH
NAMEOS_CPU_A;模块名
;定义重定位段
PROSStartHighRdyOS_CPU_ASEGMENTCODE
PROSCtxSwOS_CPU_ASEGMENTCODE
PROSIntCtxSwOS_CPU_ASEGMENTCODE
PROSTickISROS_CPU_ASEGMENTCODE
;声明引用全局变量和外部子程序
EXTRNDATA(?
C_XBP);仿真堆栈指针用于重入局部变量保存
EXTRNIDATA(STACK)
EXTRNDATA(OSTCBCur)
EXTRNDATA(OSTCBHighRdy)
EXTRNDATA(OSRunning)
EXTRNDATA(OSPrioCur)
EXTRNDATA(OSPrioHighRdy)
EXTRNCODE(_?
OSTaskSwHook)
EXTRNCODE(_?
OSIntEnter)
EXTRNCODE(_?
OSIntExit)
EXTRNCODE(_?
OSTimeTick)
;对外声明4个不可重入函数
PUBLICOSStartHighRdy
PUBLICOSCtxSw
PUBLICOSIntCtxSw
PUBLICOSTickISR
;PUBLICSerialISR
;定义压栈出栈宏
;-------------------------------------------------------------------------
PUSHALLMACRO
IRPREG,
PUSHREG
ENDM
ENDM
POPALLMACRO
IRPREG,<7,6,5,4,3,2,1,0,DPH,DPL,B,ACC,PSW>
POPREG
ENDM
ENDM
;子程序
;-------------------------------------------------------------------------
RSEG?
PR?
OSStartHighRdy?
OS_CPU_A
OSStartHighRdy:
;上电后51自动关中断,此处不必用CLREA指令,因为到此处还未开中断,本程序退出后,开中断。
LCALL_?
OSTaskSwHook
OSCtxSw_in:
;OSTCBCur===>DPTR获得当前TCB指针,详见C51.PDF第178页
MOVDPH,(OSTCBCur+1)
MOVDPL,(OSTCBCur+2)
MOVXA,@DPTR;.OSTCBStkPtr是xadta指针
MOVB,A
INCDPTR
MOVXA,@DPTR
MOVDPL,A
MOVDPH,B;此时PDTR指向用户堆栈
;*UserStkPtr===>R5用户堆栈起始地址内容(即用户堆栈长度放在此处)详见文档说明指针用法详见C51.PDF第178页
MOVXA,@DPTR;用户堆栈中是unsignedchar类型数据
MOVR5,A;R5=用户堆栈长度
;恢复现场堆栈内容
MOVR0,#STACK-1
L00:
INCDPTR
INCR0
MOVXA,@DPTR
MOV@R0,A
DJNZR5,L00
;恢复堆栈指针SP
MOVSP,R0
;恢复仿真堆栈指针?
C_XBP
INCDPTR
MOVXA,@DPTR
MOV?
C_XBP,A
INCDPTR
MOVXA,@DPTR
MOV?
C_XBP+1,A
;OSRunning=TRUE
MOVA,#1
MOVOSRunning,A
POPALL
SETBEA;开中断
RETI
;-------------------------------------------------------------------------
RSEG?
PR?
OSCtxSw?
OS_CPU_A
OSCtxSw:
PUSHALL
OSIntCtxSw_in:
;OSTCBCur===>DPTR获得当前TCB指针,详见C51.PDF第178页
MOVDPH,OSTCBCur+1
MOVDPL,(OSTCBCur+2)
;OSTCBCur->OSTCBStkPtr===>DPTR获得用户堆栈指针
MOVXA,@DPTR;.OSTCBStkPtr是void指针
MOVB,A
INCDPTR
MOVXA,@DPTR
MOVDPL,A
MOVDPH,B
;获得堆栈长
MOVA,SP
CLRC
SUBBA,#STACK-1
MOVR5,A
;保存堆栈长度
MOVX@DPTR,A
;获得堆栈起址
MOVR0,#STACK-1
L12:
INCDPTR
INCR0
MOVA,@R0
MOVX@DPTR,A
DJNZR5,L12
;保存C_XBP到堆栈中
INCDPTR
MOVA,?
C_XBP
MOVX@DPTR,A
MOVA,?
C_XBP+1
INCDPTR
MOVX@DPTR,A
;调用用户程序
LCALL_?
OSTaskSwHook
;OSTCBCur=OSTCBHighRdy
MOVA,OSTCBHighRdy
MOVOSTCBCur,A
MOVA,OSTCBHighRdy+1
MOVOSTCBCur+1,A
MOVA,OSTCBHighRdy+2
MOVOSTCBCur+2,A
;OSPrioCur=OSPrioHighRdy使用这两个变量主要目的是为了使指针比较变为字节比较,以便节省时间。
MOVA,OSPrioHighRdy
MOVOSPrioCur,A
LJMPOSCtxSw_in
;-------------------------------------------------------------------------
RSEG?
PR?
OSIntCtxSw?
OS_CPU_A
OSIntCtxSw:
;调整SP指针去掉在调用OSIntExit(),OSIntCtxSw()过程中压入堆栈的多余内容
;SP=SP-4
MOVA,SP
CLRC
SUBBA,#4
MOVSP,A
LJMPOSIntCtxSw_in
;-------------------------------------------------------------------------
CSEGAT000BH;OSTickISR
LJMPOSTickISR;使用定时器0
RSEG?
PR?
OSTickISR?
OS_CPU_A
OSTickISR:
USING0
PUSHALL
MOVA,#70H
MOVTH0,A
MOVA,#00H
MOVTL0,A
CLRTF0
LCALL_?
OSIntEnter
LCALL_?
OSTimeTick
LCALL_?
OSIntExit
POPALL
RETI
;-------------------------------------------------------------------------
END
附录2:
OS_CPU.H源码
#ifndef__OS_CPU_H
#define__OS_CPU_H
#ifdefOS_CPU_GLOBALS
#defineOS_CPU_EXT
#else
#defineOS_CPU_EXTextern
#endif
/*
*******************************************************************************
*DATATYPES
*(CompilerSpecific)
*******************************************************************************
*/
typedefbitBOOLEAN;
typedefunsignedcharINT8U;/*Unsigned8bitquantity*/
typedefsignedcharINT8S;/*Signed8bitquantity*/
typedefunsignedintINT16U;/*Unsigned16bitquantity*/
typedefsignedintINT16S;/*Signed16bitquantity*/
typedefunsignedlongINT32U;/*Unsigned32bitquantity*/
typedefsignedlongINT32S;/*Signed32bitquantity*/
typedeffloatFP32;/*Singleprecisionfloatingpoint*/
typedefunsignedcharOS_STK;/*Eachstackentryis8-bitwide*/
typedefunsignedcharOS_CPU_SR;/*DefinesizeofCPUstatusregister(PSW=8bits)*/
#defineBYTEINT8S/*Definedattypesforbackwardcompatibility...*/
#defineUBYTEINT8U/*...touC/OSV1.xx.Notactuallyneededfor...*/
#defineWORDINT16S/*...uC/OS-II.*/
#defineUWORDINT16U
#defineLONGINT32S
#defineULONGINT32U
/*
*******************************************************************************
*KeilC51ongeneric8051-basedmicrocontroller
*******************************************************************************
*/
#defineOS_CRITICAL_METHOD3/*changefrom1to3byproakis*/
#ifOS_CRITICAL_METHOD==1
#defineOS_ENTER_CRITICAL()EA=0/*Disableinterrupts*/
#defineOS_EXIT_CRITICAL()EA=1/*Enableinterrupts*/
#endif
#ifOS_CRITICAL_METHOD==2
/*Asanundocumentedkeywordofkeilc.__asmissupportedinKeilCv6.20.
.Noothermeanstodefineassemblelanguagecodeinamacro,Ihavetouseithere.Ifyourcompilerdoesnotsupport__asm,usemethod1or3then.*/
/*A2AFMOVC,EA*/
/*C2AFCLREA*/
/*C0D0PUSHPSW*/
#defineOS_ENTER_CRITICAL()__asmDB0A2H,0AFH,0C2H,0AFH,0C0H,0D0H
/*D0D0POPPSW*/
/*92AFMOVEA,C*/
#defineOS_EXIT_CRITICAL()__asmDB0D0H,0D0H,092H,0AFH
#endif
#ifOS_CRITICAL_METHOD==3
#defineOS_ENTER_CRITICAL()cpu_sr=EA;EA=0/*Disableinterrupts*/
#defineOS_EXIT_CRITICAL()EA=cpu_sr/*Enableinterrupts*/
#endif
#defineOS_STK_GROWTH0/*StackgrowsfromLOWtoHIGHmemoryonforlargemode*/
#defineOS_TASK_SW()OSCtxSw()
#defineOS_ISR_PROTO_EXT1
voidOSCtxSw(void);
#endif
附录3:
OSTaskStkInit源码
OS_STK*OSTaskStkInit(void(*task)(void*pd),void*pdat,OS_STK*ptos,INT16Uprio)KCREENTRANT
{
OS_STK*stk;
pdat=pdat;
stk=ptos;//用户堆栈最低有效地址
*stk++=15;//用户堆栈长度
*stk++=(INT16U)task&0xFF;//任务地址低8位
*stk++=(INT16U)task>>8;//任务地址高8位
*stk++=0x00;//PSW
*stk++=0x0A;//ACC
*stk++=0x0B;//B
*stk++=0x00;//DPL
*stk++=0x00;//DPH
*stk++=0x00;//R0
*stk++=0x01;//R1
*stk++=0x02;//R2
*stk++=0x03;//R3
*stk++=0x04;//R4
*stk++=0x05;//R5
*stk++=0x06;//R6
*stk++=0x07;//R7
if(prio==OS_LOWEST_PRIO){
*stk++=(INT16U)(ptos+OS_TASK_IDLE_STK_SIZE)>>8;//?
C_xBP+1
*stk++=(INT16U)(ptos+OS_TASK_IDLE
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- UCOSII 252在C8051F020上的移植之 252 C8051F020 移植