_C_OS_II在C8051F060上的移植
- 格式:pdf
- 大小:149.09 KB
- 文档页数:4
第33卷第7期应用科技V o.l 33, .72006年7月A pp lied Science and T echno l ogyJu.l 2006文章编号:1009-671X (2006)07-0022-04C /OS II 在C8051F060上的移植王学宝,李俊山,闫保中(哈尔滨工程大学自动化学院,黑龙江哈尔滨150001)摘 要:介绍了实时操作系统 C /O S II 在C8051F060上的移植,详细介绍了移植的过程,所用到的方法具有一般意义,对于向其他平台的移植具有参考价值. C /OS II 是一个优秀的嵌入式实时操作系统,对于理解其他嵌入式操作系统有很大的帮助,在此基础上有利于提高应用程序的开发效率,提高稳定性.关键词: C /O S II ;C8051F 060;移植中图分类号:T P316.2 文献标识码:APorti ng C /OS II to C 8051F 060WANG Xue bao,LI Jun shan ,YAN B ao z hong(College o f Autom ati on ,H arb i n Eng i neer i ng U n i versity ,H arbi n 150001,China)Abst ract :The po rting of C /OS II on to C8051F060and porti n g process are i n troduced .The m ethod has genera l si g nificance ,prov i d i n g reference va l u e to porti n g to o t h er platfor m s .C /OS II is an excellent e mbedded real ti m e operati n g syste m,wh ich is he l p fu l to co m prehend other e m bedded syste m and ra ises the deve l o pm ent effic iency of app lication prog ra m and t h e stab ility .K eywords : C /OS II ;C8051F060;porti n g ;e m bedded real ti m e operati n g syste m 收稿日期:2005-07-11.作者简介:王学宝(1981-),男,硕士研究生,主要研究方向:导航、制导与控制,E m ai:l shan318@163.co m.以C8051F060为目标环境,论述实时操作系统 C /OS II 的移植,希望通过这个方式,能够有效地简化嵌入式系统的开发.1 可移植性的分析所谓移植,就是使一个内核能在某个微处理器或微控制器上运行.整个嵌入式系统包括2大层:硬件层和软件层.软件层主要包括4个部分:实时操作系统内核,与处理器相关部分,与应用相关部分,用户的应用系统.1.1 实时操作系统内核应用系统是在实时内核的统一管理下协调工作,能够高效地实现任务切换、任务调度、任务间通讯、同步、互斥、实时时钟管理、中断管理等.移植的时候内核是不变的,开发者根据自己应用系统的需要来选择实时操作系统内核[1].1.2 与处理器相关部分这是整个移植过程中关键的一部分,要使同一个内核能适用于不同的硬件体系,就需要在内核和硬件之间有一个中间层,这就是与处理器相关的代码,处理器不同,这部分代码也不同.在 C /OS II 中,这部分代码包括3个文件:OS_CPU.H,OS_CPU _A.AS M,OS_CPU _C .C [2].1.3 与应用相关部分在这部分中用户根据自己的应用系统来定制合适的内核服务功能,包括2个文件:OS _CFG .H 和I N CLUDES .H.OS_CFG.H 来配置内核,用户根据需要对内核进行定制.I N CLUDES .H 是系统头文件,整个实时系统程序所需要的文件,包括了内核和用户的头文件[2].1.4 用户的应用系统这是整个系统的最高层,用户通过操作系统提供的服务来开发具体程序.以上4点可以通过图1说明.图1 C /OS 的结构及其与硬件的关系使 C /OS 正常运行,必须满足以下要求:1)处理器的C 编译器能产生可重入代码;2)C 语言可以打开和关闭中断;3)处理器支持中断,并且能产生定时中断(通常在10~100H z 之间);4)处理器有将堆栈指针和其他CPU 寄存器读出和存储到堆栈或内存中的指令.C8051F 系列的处理器满足上面的要求.由于受目标系统本身资源的限制,运行的程序往往不是在目标机上开发的,这就引入了交叉编译环境,移植 C /OS 需要用到一个C 编译器,并且是针对用户的CP U 的.因为 C /OS 是一个可剥夺型内核,用户只有通过C 编译器来产生可重入代码,C 编译器还要支持汇编语言程序.文中选用的是KE I L ,选择的编译模式为Lar ge :var i a b les i n XDATA,并结合实际应用在STARTUP.A51修改内存和重入堆栈的初始化.2 移植的具体过程及注意事项为了方便移植,大部分的 C /OS 代码是用C 语言写的,但仍需要用C 和汇编语言写一些与处理器相关的代码,这是因为 C /OS 在读写处理器寄存器时只能通过汇编语言来实现.由于 C /OS 在设计时就已经充分考虑了可移植性,所以 C /OS 的移植相对来说是比较容易的.2.1 新建工程在开发工具KE I L 中新建一个工程加入源码、STARTUP .A51和一个简单的自测主程序,由于C8051F060与8051兼容,故对STARTUP .A51修改以下内容即可:XDATASTART(片外可寻址空间的起始地址),I D ATALEN (片内可寻址的字节长度),XDATALE N (片外可寻址空间的字节长度).以上是3个内存的初始化.倘若修改错误,很可能导致仿真正常,写入芯片后程序异常的问题.例如程序仿真时用到了外部存储器,而实际中没有,这样就会导致烧入后程序跑飞,所以仿真时要与实际的存储器设置一样.前面已说明所用编译模式为Large ,且用户堆栈要设置在XRAM,故对堆栈设置如下:XBPSTAC(用户堆栈的起始地址),XBPSTAC K TOP(用户堆栈的最高地址),系统在这个可用的堆栈区进行多个用户任务的分配.由于单片机内存有限,要合理分配.2.2 OS_CPU.H 文件OS_CPU.H 文件中包含与处理器相关的常量、宏和结构体的定义.数据类型:由于不同的处理器有不同的字长,针对本例 C /OS II 的移植需要重新定义一系列的数据结构.代码临界区:与其他实时系统一样, C /OS II 在进入系统临界代码区之前要关闭中断,等到退出临界区后再打开,从而保护核心数据不被多任务环境下的其他任务或中断破坏. C /OS II 定义了2个宏用来关闭/打开中断:OS _ENTER _CR I T I C AL()和OS_EXI T_CR I TI CAL ().采用直接将这2个宏定义为处理器的关闭(EA =0)和打开(EA =1)中断指令.但这种方法有一个隐患,如果在关闭中断后调用 C /OS II 函数,当函数返回后,中断将被打开.严格意义上的关闭中断应该是执行OS _E NTER _CR I T I CAL()后中断是始终关闭的,这显然不满足要求.但其最大优点是简单,执行速度快(只有1条指令),在此类操作频繁的时候更为突出.如果在任务中并不在意调用函数返回后是否被中断,推荐用户采用该方法.!23!第7期 王学宝,等: C /O S II 在C8051F060上的移植堆栈增长方向:C8051F060处理器的堆栈是由低地址向高地址方向增长的,所以常量OS_STK_ GROWTH必须设置为0,堆栈数据类型OS_STK声明为8位.所有的堆栈都必须用OS_STK声明.OS_TASK_S W():在C/OS II中,就绪任务的堆栈初始化应该模拟一次中断发生后的状态,堆栈中应按入栈次序设置好各个寄存器的内容.OS_ TASK_S W()函数模拟一次中断过程,在中断返回的时候进行任务切换.因为M C U 51没有软中断指令,所以用程序调用代替,模拟中断的发生.2.3 OS_CP U_A.AS M这部分需要对处理器的寄存器进行操作,代码编写可用汇编和C,文中采用汇编. C/OS II的移植需要用户改写OS_CPU_A.AS M中的4个函数: OSS tart H i g hRdy(),OSC txSw(),OSInt C txSw(),OS T i c k I SR().在移植过程中,用户要明白每个函数的作用,这样可以加深对多任务内核的理解.OSS tart H i g hRdy()函数由多任务系统启动函数SStart()函数调用,过程是:设置系统运行标志位OSRunning=TRUE,运行优先级最高的就绪任务,在调用OSStart()之前,用户必须先调用OS I n it(),并且已经至少创建了一个任务.OSS tart H i g hRdy()默认指针OSTCBH ighRdy指向优先级最高就绪任务的任务控制块(OS_TCB),然后将就绪表中最高优先级任务的栈指针Load到SP中,并强制中断返回,这样就绪的最高优先级任务就如同从中断里返回到运行态一样,使得整个系统得以运转.函数原型为vo id OSStart H i g hRdy(vo i d){调用用户定义的OSTaskSwH ook();把就绪的优先级最高的任务堆栈指针赋予SP;设置OSRunn i n g为真;从即将运行的任务堆栈中获得寄存器的值;中断返回;}OSC txSw()函数由任务级任务切换函数调用,是通过模拟中断实现的,ISR的中断向量地址必须指向OSCtxSw().过程是:保存任务的环境变量,将当前SP存入改任务TCB中,保存仿真堆栈指针C_XBP,载入就绪最高优先级任务的SP,恢复就绪最高优先级任务的环境变量,中断返回,这样就完成了任务级的切换.注意在OSC txSw()和用户定义的函数OSTaskSwH ook()的执行过程中,中断是禁止的.函数原型为vo i d OSC txSw(vo i d){保存处理器寄存器;将当前任务的堆栈指针保存到OS_TCB中;调用用户定义的OSTaskSwH ook();OSTCBCur=OSTCB H i g hRdy;OSPrioCur=OSPrio H ighRdy;得到需要恢复的任务的堆栈指针;将所有处理器寄存器从新任务的堆栈中恢复出来;执行中断返回指令;}OS I nt C txSw()在退出中断服务函数OSI nt E x it()中调用时,所有的处理器寄存器都被正确地保存到了被中断的任务的堆栈之中,实现中断级任务切换.过程是:调整指针,因为调用函数会使任务堆栈结构与系统任务切换时堆栈标准结构不一致,然后就同OSC txSw()基本一致.函数原型为vo i d OSI ntCtxSw(vo id){调整堆栈指针;除不需要保存处理器寄存器外,下同OSC txSw()} OST ickI SR()是系统时钟节拍中断服务函数,它是一个由硬件提供的周期性中断函数,为内核提供时钟节拍,频率越高系统负荷越重,其周期的大小决定了内核所能给应用系统提供的最小时间间隔服务,一般只限于m s级(跟MC U有关),对于要求更加苛刻的任务需要用户自己建立中断来解决.过程是:保存寄存器,调用OSI nt E nter(),调用OST i m Tick(),最后调用OSI nt E x it(),恢复寄存器,中断返回.函数原型为vo i d OST ickI SR(vo id){保存处理器寄存器;调用OS I nt E nter()或者直接将OSI nt N esti n g加1;调用OST i m e T ick();调用OS I nt E x it();恢复处理器寄存器;!24!应 用 科 技 第33卷执行中断返回指令;}2.4 OS_CP U _C .CC /OS 的移植实例要求用户编写6个简单的C 函数,但是最重要的是OSTaskStkI nit(),这个函数是在用户建立任务时系统内部自己调用的,对用户任务的堆栈进行初始化,使进入就绪态任务的堆栈与系统发生中断并且将环境变量保存完毕时的堆栈结构一致,在这里要注意堆栈的设计,如图2所示.图2 用户堆栈结构图其他都是对系统内核的扩展时用的,可以在OS _CFG..H 中令OS_CP U _HOOKS_E N 为1或0,从而取舍5个钩子函数.本文中用到了钩子函数,其函数体基本都是空的.函数原型为void *OSTaskS t k I n it (vo id (*task)(vo i d *pd),vo i d *ppdata ,vo i d *ptos ,I N T16U opt){保存堆栈和任务地址;保存寄存器的值;保存仿真堆栈指针;返回用户有效地址,本文返回最低地址;}2.5 建立用户的主程序在该程序中,用户可以通过建立几个简单的用户任务,测试移植后的内核运行情况,如果运行正常,然后就可以使用 C /OS 提供的资源和对象.3 结束语对于学习嵌入式系统的软件层,从 C /OS 入手是一个不错的选择,它代码量小,结构清晰.理解多任务实时操作系统的一般原理,对于进一步学习操作系统的知识将有很大的帮助,实践证明,在此基础上进行应用程序的开发,更有利于提高开发效率,增加软件可靠性.参考文献:[1]吕 骏.嵌入式系统设计[M ].北京:电子工业出版社,2004.[2]LA BRO SSE J . C /O S 源代码公开的实时嵌入式操作系统[M ].邵贝贝,译.北京:中国电力出版社,2001.[责任编辑:马兰兰]!25!第7期 王学宝,等: C /O S II 在C8051F060上的移植。