移植UCOS之前,你首要应该做好三件事:
1.弄懂UCOS,这是谁都知道的哦 ^_^
2. 弄懂你想要移植到的硬件渠道
3. 清楚你运用的编译器是怎么处理函数的局部变量和怎么样处理函数间的参数传递
这儿多废话几句第三点:在UCOS里边,一切函数都要求具有重入性(除了OSSTAR()外,只需这个函数我觉得是不需求的,它只是运用了一次);重入性是多使命的根底,而所谓重入性从函数而言便是它的变量的保存问题,在中止这个函数的履行时它运用的变量需求得到保存,以便回来后的履行是正确的,就我运用的编译器而言,它经过仓库传递函数参数,
重入性问题就很简单处理拉,在中止使命时,它的参数已经在仓库里边了,只需你保存好CPU寄存器和仓库指针SP就好
而假如你运用的是KEIL的话就比较复杂拉,首要KEIL是51单片机的东西,51只需很少的存储空间,KEIL的重入性是经过建立模仿栈完结的,当使命中止履行时,你不只需求保存CPU寄存器,还要保存模仿栈的内容,特别是51的SP寻址才能不强,只需8位,不能在64K的空间自移动,而UCOS比较大,KEIL编译时只能用大规模方法,这就意味着一切的全局变量都会保存在片外空间,而SP无法访问到,你需求建立一个公共的体系栈,保存正在运转的使命的数据,在使命切换时把这个体系栈的内容拷贝到它的使命栈里,操作比较繁琐
留意体系的初始化问题,我在第一个使命里调用了体系初始化函数,在里边开中止答应.
使命可所以关中止时被挂起,也可所以开中止时被挂起,那么在使命切换回来后怎么确保它的中止情况呢?问题能够经过给每个使命设置一个中止计数器处理,并初始化为 0,记载每个使命的开关中止次数,关一次中止加 1,开一次中止减 1, 在使命调度的时分保存当前使命的中止计数器,切换到新使命时检查新使命的中止计数器,假如为 0就开中止回来,否则就直接回来(使命级切换是在关中止下进行的);而关于中止级使命调度,肯定是发生在开中止情况下的,就要检查是否需求关中止处理
现在开端说我的移植:我移植到的渠道是凌阳公司的SPCE061A 16位单片机,它有2K的RAM,32K的ROM空间,基本上够用,但不能有太多功用,我在研讨了这款片子的材料后,才开端自己的移植,主要是学了一下它的汇编语言和混合编程以及CPU得硬件方面;在仓库的问题上我发现凌阳的SP是16位的,能够寻址64K的空间,不需求建立体系栈. 在OS_CPU_C.C中留意仓库的初始化,必定要在使命切换时严格遵守你的初始化时假定的寄存器次序.
下面开端移植最重要的三个文件:
OS_CPU_C.C:
OSTaskStkInit():
stk=(OS_STK *)ptos;
*stk–=*((INT16U*)task+1);/*使命首地址 (PC)*/
*stk–=0x0000;/*SR(R6) */
*stk–=0x0000;/*BP(R5) */
*stk–=0x0000;/*R4*/
*stk–=0x0000;/*R3*/
*stk–=0x0000;/*R2*/
*stk–=0x0000;/*R1*/
*stk–=0x0000;/*该使命的中止情况计数器*/
return((void *)stk);
其他便是空函数,比较简单,这儿省略
这个文件比较简单,仅有要留意的是仓库初始化函数,像刚刚提到的,你假定的仓库内容有必要在使命切换时严格遵守.还有便是界说几个空函数
OS_CPU_A.ASM:
这个文件呢是移植的要害,需求用汇编语言编写,(我有个同学很能喷,以为汇编语言纯属没用,像这种话千万不要信任!),在这个文件里,你需求完结UCOS的中心代码!
首要是OSStartHighRdy():
该函数在体系开端时使最高优先级使命运转,代码如下:
_OSStartHighRdy:
CALL_OSTaskSwHook
R1=0x0001
[_OSRunning]=R1
R1=[_OSTCBCur]
SP=[R1]
POP R1 FROM [SP]
[_InterruptC]=R1//弹出使命中止情况计数器
POP R1,R5 FROM [SP]
RETI
接着是OSCtxSw():
完结使命切换,代码如下:
_OSCtxSw:
PUSH R1,R5 TO [SP]
R1=[_InterruptC]
PUSH R1 TO [SP]//保存使命中止情况
R2=[_OSTCBCur]
[R2]=SP
CALL _OSTaskSwHook
//OSUCBCur=OSTCBHighRdy
R1=_OSTCBCur
R2=[_OSTCBHighRdy]
[R1]=R2
//OSPrioCur=OSPrioHighRdy
R1=[_OSPrioHighRdy]
[_OSPrioCur]=R1
R1=[_OSTCBHighRdy]
SP=[R1]
POP R1 FROM [SP]
[_InterruptC]=R1//弹出使命中止情况
CMP R1,0//检查是否需求开中止
JNE KAI
INT IRQ
KAI: POP R1,R5 FROM [SP]
RETI
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/changshang/257553.html