如果您无法下载资料,请参考说明:
1、部分资料下载需要金币,请确保您的账户上有足够的金币
2、已购买过的文档,再次下载不重复扣费
3、资料包下载后请先用软件解压,在使用对应软件打开
S3C2410之UCOS移植笔记μC/OS-II大部分代码是用移植性很高的ANSIC语言编写的,只包含一小部分汇编语言代码,因此可以很方便地将它移植到各种不同构架的微处理器上。移植μC/OS-II,所用处理器和该处理器所用的C语言编译器必须满足以下条件:1.处理器的C编译器能产生可重入代码;2.处理器支持中断,并且能产生定时中断;3.用C语言就可以开/关中断;4.处理器能支持一定数量的数据存储硬件堆栈;5.处理器有将堆栈指针以及其他CPU寄存器的内容读出、并存储到堆栈或内存中去的指令。首先,由于处理器字长不同为了方便,我们通常要修改下字长定义,s3c2410是32位处理器所以定义如下:#defineU32unsignedint#defineU16unsignedshort#defineS32int#defineS16shortint#defineU8unsignedchar#defineS8signedchar下面我对以上的移植要求一次进行移植分析:1.修改ucos源代码中OS_CPU.S中的代码如下,主要是用开关中断实现代码的可重入要求:EXPORTOSCPUSaveSROSCPUSaveSRmrsr0,CPSRorrr1,r0,#NOINT;屏蔽irq,fiqmsrCPSR_c,r1movpc,lr;跳回EXPORTOSCPURestoreSROSCPURestoreSRmsrCPSR_c,r0movpc,lr2.s32410支持中断,选择一个定时器作为时钟滴答,来对任务做时间片的调度,有关s3c2410的中断介绍可以参考我得另一片文章。产生中断后,代码自动跳转到0x0的中断向量表,然后在从中断向量表中跳到下面的程序,进行中断号的分析,然后利用ucos的中断任务切换到中断服务子程序中。UCOS_IRQHandlerstmfdsp!,{r0-r3,r12,lr};保存现场blOSIntEnter;跳到下面程序,实际上是中断嵌套blC_IRQHandler;计算出中断号blOSIntExit;中断减1,切换最高优先级任务ldrr0,=OSIntCtxSwFlag;判断是否需要中断切换ldrr1,[r0]cmpr1,#1beq_IntCtxSw;调用中断任务切换函数,后面分析ldmfdsp!,{r0-r3,r12,lr};恢复现场subspc,lr,#4voidOSIntEnter(void){if(OSRunning==OS_TRUE){if(OSIntNesting<255u){OSIntNesting++;/*中断记数+1*/}}}voidOSIntExit(void){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr=0;#endifif(OSRunning==OS_TRUE){OS_ENTER_CRITICAL();if(OSIntNesting>0){;中断,中断数-1OSIntNesting--;}if(OSIntNesting==0){;果没有中断的话if(OSLockNesting==0){OS_SchedNew();if(OSPrioHighRdy!=OSPrioCur){OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];#ifOS_TASK_PROFILE_EN>0OSTCBHighRdy->OSTCBCtxSwCtr++;#endifOSCtxSwCtr++;;最高优先级的任务调入OSIntCtxSw();}}}OS_EXIT_CRITICAL();}}voidC_IRQHandler(void){U32wTemp;wTemp=rINTOFFSET<<2;根据中断偏移量判断是什么中断((void(*)(void))(*((U32*)(aISR_EINT0+wTemp))))();关键!跳到相应中断服务程序}其中的UCOS_IRQHandler就是实现中断跳转的关键代码,C语言中将irq中断函数的入口都指向它实现中断跳转到C中对应的服务函数,代码如下:pISR_IRQ=(U32)UCOS_IRQHandler;中断入口挂接然后初始化一个定时器作为时钟滴答,一般选择100ms左右,产生一次中断溢出,进行一次任务调度。3.有关堆栈的设置。因为ucos进行任务切换时,就是相当于模拟的做中断操作。所以在切换任务之前必须先保存任务的现场:包括R0~R12,sp,lr,pc,cprs,sprs。然后用sp从旧的任务堆栈指向新的任务的堆栈。(这个堆栈在任务创建的时候已经分配好了)。在初始化任务堆栈之前,首先要设