




已阅读5页,还剩8页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
uCOS C51移植心得 转载2005版uCOSC51移植心得1 0推荐uCOS- C51移植笔记(1)实时系统和前/后台系统;前/后台系统:一个大循环,循环查询各种标志位。如果标志位置位,就执行相应的服务程序。标志位就是标志事件的发生,事件响应延时处于不可预测状态。最坏的情况是循环中所有其他的事件服务程序执行完,才响应当前事件。中断服务虽然能即时/优先响应,但是它们和主循环的通讯,也是通过置主循环中相应的标志位来完成的。实时系统(uCOS):整个程序分成一个个看起来好象是并行的任务,每个任务都在等待事件的发生。因为uCOS不支持时间片轮转,除了最低优先级任务(在uCOS中是IDLE任务)是死循环以外,其他的任务都不能死循环,只能在驱动事件驱动下工作。任何驱动事件的产生,都使优先级最高的就绪任务运行。任务和任务/任务和中断的通讯,是通过相应事件驱动来完成的。驱动事件:不论是什么系统,CPU不可能一直在工作。CPU的工作是在各种驱动事件的驱动下工作的。CPU在完成一次驱动事件事件服务程序以后,进入IDLE模式等待新的驱动事件的发生。包括实时系统和前/后台系统都是在驱动事件的驱动下运行的。按照uCOS中的观点,驱动事件分为三类:1、事件 (Event)。包括信号量(Semaphores)、事件标志组(Flag)、邮箱(Message Box)、邮箱队列(Message Queue)。2、时间(Time Tick)。包括时间延时和事件超时。3、中断(Interrupt)。可以发出各种event。由于第1种事件,通常都是在第2、3种状态下发出的,所以其实事件的驱动只有两种:时间(定时)和中断(各种异步中断)。时间实际上也是中断的一种,可以说程序的驱动事件只有一种,就是:中断。前/后台系统中还有一种驱动事件的产生,在主循环中不断的查询。有别与一般的定时查询,这种查询是为了将事件的响应时间降到最低,也可以将其归纳于定时(时间)事件。(2)uCOS C51移植的准备工作;2004年8月份,我在书城买了一本uCOS- 第2版,准备学习RTOS。因为以前没有玩过RTOS,在工作之余断断续续的看了3、4章。一直到12月初的时候,公司要重新设计一个项目,恰好要把uCOS移植到c51上。我的RTOS学习才正式开始。因为对OS向往以久,我并不想在网上Down一个现成的移植OS程序,做一个OS的应用者。揭开OS的神秘面纱,了解OS的内部运行机制,这才是我想要做的。本文的主要目的是讨论uCOS的移植,希望对即将进行uCOS c51移植的兄弟有些帮助。对于OS的内部运行机制,由于东西比较多,在这里不想太展开。如果以后有时间,也想写一篇文章来讨论讨论。最开始,我的计划就是看书,看uCOS- 第2版。看完这本几百页的大本本,花了我2个半星期。因为是工作需要,我才可以这样心安理得的在那里看呀看书_,辛苦呀9。在这期间,为了自己的思想不受别人的影响,我坚决没有从网上下任何uCOS的资料,我手头的资料就是uCOS-的书和附带光盘,这些就是最权威的资料了。在看书的时候,我都坚持做笔记,把每天的重点,明白的东西和心中的疑问都随时记录下来。对付这种大本本,前后的知识又相互关联,光靠我们的大脑是搞不定啊。弄懂了uCOS的内核,下一本书应该是单片机高级语言C51Windows环境编程与应用。对于Keil C我还是很熟的,还是花了2、3天来复习。这里的重点是C51对汇编的转换结构,例于数据/系统堆栈的使用,C&Asm混合编程。我想对于任何CPU的uCOS移植,C语言的实现机制,你都是要了解的。这里也是要花大把时间的。uCOS- 第2版和单片机高级语言C51Windows环境编程与应用这两本书网上都可以下电子档的,我这里也有(大家需要可以来信索取)。uCOS和C51的书都看完了。我就下载了一堆uCOS的C51移植资料。其中的源程序有很多个版本的,不过详细的移植文档只有一个版本:巨龙一位大虾的uCOS C51移植心得,相信很多人都看过。这些资料的作者都是我移植过程中的老师,有了这些资料,我才能把心中的朦胧想法变成源程序。但是我也发现这些资料中大多都有一些错误和遗漏,当然这是难免的。这也正是驱使我写这篇文章的原因,希望在前辈的基础上有所进步。欢迎大家来批评!真正的源代码移植,我花了大概一个星期时间。(3)uCOS C51的移植概况;1、工具:uCOS 2.52版;Keil C V6.23a。2、uCOS V2.52的文件结构与移植所需要的修改:A、与处理器无关的文件:OS_CORE.COS_FLAG.COS_MBOX.COS_MEM.COS_MUTEX.COS_Q.COS_SEM.COS_TASK.COS_TIME.CuCOS_II.CuCOS_II.H这些文件在c51的移植过程中,只需要给函数加上重入属性即可。B、与应用相关的文件:INCLUDES.H: 包含C51的标准库头文件;对pdata等c51关键字的重定义OS_CFG.H: OS_TICKS_PER_SEC、 OS_FLAGS注意可能需要修改。C、与处理器相关的文件:OS_CPU.H: 数据类型、关中断方法、任务堆栈方向、任务切换的宏定义都需要修改。OS_CPU_A.ASM: OSTickISR()、OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()这几个函数的编写,是整个移植的关键。OS_CPU_C.C:OSTaskStkInit()函数的编写。(4)uCOS C51具体的移植过程;1、C51的堆栈结构;这是整个移植过程中的重中之重,所以特别详细介绍。A、 系统堆栈;c51中,系统堆栈的栈底地址是?STACK,栈顶指针就是SP拉,栈的生长方向是向上的,栈空间分配在51的内部RAM(idata)中。?STACK分配在所有内部RAM数据段的最后面,所以系统堆栈的范围是从?STACK到内部RAM的最高位(0x80或者0xFF)。B、 数据堆栈;c51中,由于我们使用OS,采用的LARGE编译模式,所以数据堆栈的指针是?C_XBP, 栈的生长方向是向下的,栈空间分配在51的外部RAM(xdata)中。C、 C51中断中堆栈的保护;研究中断中堆栈的保护的意义在于,因为uCOS中的任务切换,本身就是模拟一次中断的发生:保护Task1的CPU寄存器,SP切换到Task2的堆栈,弹出Task2的CPU寄存器。用C51写中断函数的时候,编译器会自动保护CPU的寄存器,所以中断返回时任务调度OSIntCtxSw(),就不用重新保护寄存器。C51中断中调用函数可以分为四种情况(中断函数本身不设为reentrant):一、没有函数调用;二、调用非reentrant函数,函数中没有嵌套调用其他函数;三、调用非reentrant函数,函数中嵌套调用其他函数;四、调用reentrant函数。t0_isr:PUSHACCPUSHBPUSHDPHPUSHDPLPUSHPSWMOV PSW,#00HPUSHAR0PUSHAR1PUSHAR2PUSHAR3PUSHAR4PUSHAR5PUSHAR6PUSHAR7用户代码POP AR7POP AR6POP AR5POP AR4POP AR3POP AR2POP AR1POP AR0POP PSWPOP DPLPOP DPHPOP BPOP ACCRETI因为uCOS中所有的函数都必须是重入函数,因此我们只需要研究第四种情况下的堆栈保护,对于其他情况有兴趣可以在c51中看看。(注意:可能因为c51编译器的版本不同,上述压栈的顺序可能不同。)2、uCOS C51任务切换时的堆栈操作;每个任务都有一个独立的数据堆栈,系统堆栈是公用空间。保护Task1的CPU寄存器: 首先将CPU寄存器按上例压进Task1系统堆栈,再将整个Task1系统堆栈压进Task1数据堆栈;SP切换:?C_XBP = Task2 的数据堆栈栈顶地址。弹出Task2的CPU寄存器:从Task2的数据堆栈重新恢复整个系统堆栈,然后再从Task2系统堆栈中恢复CPU寄存器值。实现的方法有很多种,只要遵循uCOS任务切换的原理就可以了。3、INCLUDES.H的移植;重点:pdata是C51关键字,所以要重新定义源代码:i ncludei ncludei ncludei ncludei ncludei nclude#define TASK_REENTRANTlarge reentrant#define KCREENTRANT large reentranti ncludeos_cpu.hi ncludeos_cfg.h#define dataucos51_data#define idata ucos51_idata#define pdata ucos51_pdata#define xdata ucos51_xdatai ncludeucos_ii.h4、OS_CPU.H的移植;typedef unsigned charBOOLEAN;typedef unsigned charINT8U;typedef signed charINT8S;typedef unsigned int INT16U; typedef signed int INT16S; typedef unsigned longINT32U; typedef signed longINT32S; typedef floatFP32; typedef unsigned charOS_STK; #define BYTE INT8S #define UBYTEINT8U #define WORD INT16S#define UWORDINT16U#define LONG INT32S#define ULONGINT32UC51编程:uCOS51移植心得uCOS51移植心得2002/10/03前一段时间,我参与了一个SNMP网管板的项目,我负责硬件设计和单板软件开发。该板的硬件由MCS51+RTL8019AS组成,有64KFLASH和64KSRAM。软件部分有操作系统和TCPIP协议栈。硬件比较简单,用了一个月就搞定了,协议栈我参考了老古开发板的部分程序又上网找了SNMP源代码也很快完成了,但是测试时发现当使用较低时钟频率的CPU时(为了降低成本),由于ASN.1编解码部分过于庞大,而我的程序又是一个大循环,AGENT的响应速度受到严重影响,用户界面也反应迟钝。更坏的消息是公司为了适应市场需求,还要在上面跑PPP和HTTP。那样的话,我就得用40MHz的AT89C51RD2或者人为的把程序断成几部分然后用状态机的方法在运行时再把它们连接起来。不过,我不想增加成本,也不想把程序搞乱,迫不得已,只好使用操作系统。说实在的,一开始我也不是很有把握,一来我不清楚51的FLASH是否装得下这么多代码,二来我只做过OS应用开发,对于它的移植想都不敢想。不过,我在BBS上搜索了一阵儿后还是有了一些头绪。我找到了几个OS的源代码(我喜欢用现成的),按照代码大小、实时性、使用人数、众人口碑等标准,最后选定了uCOS2。我感觉它的实时性有保障,延时可预测,代码据说可小到2K,网上讨论这个话题的人也比较多,而且它的网站上有针对KEILC51的移植实例。经过一番查找,我得到了5个版本。其中3个是用KEIL编译的。本来我想直接把OS代码嵌到应用程序中,但后来发现没有一个可以直接使用。有的无法用KEIL直接编译,有的需要修改DLL在软件仿真下使用。而我需要的是能在串口输入输出,不需要修改任何无关软件,能在软件仿真和硬件上运行的实时多任务操作系统。没有办法,我只好硬着头皮去改编。我分析了自己的劣势:1。KEIL刚开始使用,不太熟悉;2。混合编程以前从没有作过;3。时间紧迫,要在1个月内搞定。而我的优势就是有5个移植实例可供参考,可以上网查资料。一开始,我用“堆栈”、“混合编程”、“汇编”、“ucos”等关键字在C51BBS和老古论坛上检索相关信息并逐条阅读,读过之后,头脑中的思路逐渐清晰了。我了解到在KEIL的HLP目录下有A51.PDF和C51.PDF非常全面的介绍了汇编和C51,是KEIL的权威用户手册;SP初始化、内存清0等操作在STARTUP.A51文件中实现,用户可以改写它;KEIL的变量,子程序等的分配信息可以在.M51文件里查到;KEIL自己的论坛里有很多疑难问题的解答通过阅读并经过思考,解决了堆栈起点、堆栈空间大小的设定等关键问题。论坛里的问题有些是我没有想到的,这使我发现了自己的疏漏。在网上获得大量信息后,我开始阅读uCOSII中文版,一共读了3遍。第一遍是浏览,了解到uCOSII包括任务调度、时间管理、内存管理、资源管理(信号量、邮箱、消息队列)四大部分,没有文件系统、网络接口、输入输出界面。它的移植只与4个文件相关:汇编文件(OS_CPU_A.ASM)、处理器相关C文件(OS_CPU.H、OS_CPU_C.C)和配置文件(OS_CFG.H)。有64个优先级,系统占用8个,用户可创建56个任务,不支持时间片轮转。第二遍主要是把整个工作过程在头脑里过了一下,不懂地方有针对性的查书,重点是思考工作原理和流程。我发现其实它的思路挺简单的。就是“近似地每时每刻总是让优先级最高的任务处于运行状态”。为了保证这一点,它在调用系统API函数、中断结束、定时中断结束时总是执行调度算法。原作者通过事先计算好数据,简化了运算量,通过精心设计就绪表结构,使得延时可预知。任务的切换是通过模拟一次中断实现的。第三遍重点看了移植部分的内容。对照实例,研究了代码的具体实现方法。前期准备用了20几天,真正编写代码只用了1.5天,调试用了2天。具体过程如下:(1)拷贝书后附赠光盘sourcecode目录下的内容到C:YY下,删除不必要的文件和EX1L.C,只剩下p187(uCOSII)上列出的文件。(2)改写最简单的OS_CPU.H数据类型的设定见C51.PDF第176页。注意BOOLEAN要定义成unsignedchar类型,因为bit类型为C51特有,不能用在结构体里。EA=0关中断;EA=1开中断。这样定义即减少了程序行数,又避免了退出临界区后关中断造成的死机。MCU-51堆栈从下往上增长(1=向下,0=向上),OS_STK_GROWTH定义为0#defineOS_TASK_SW()OSCtxSw()因为MCU-51没有软中断指令,所以用程序调用代替。两者的堆栈格式相同,RETI指令复位中断系统,RET则没有。实践表明,对于MCU-51,用子程序调用入栈,用中断返回指令RETI出栈是没有问题的,反之中断入栈RET出栈则不行。总之,对于入栈,子程序调用与中断调用效果是一样的,可以混用。在没有中断发生的情况下复位中断系统也不会影响系统正常运行。详见uC/OS-II第八章193页第12行(3)改写OS_CPU_C.C我设计的堆栈结构如下图所示:*-*|OSTCBCur|*-*|*|-*-|OSTCBCur-OSTCBStkPtr|SP-|*-*|*|-*|.|*|-|.|*|.|*|-|-*|.|长度|+1*|.|-*|.|OSStack-|0*|-|-*|OSStkStart-|不关心|-1低地址*|-*-|长度|低地址系统堆栈*-*用户堆栈长度=SP-OSStkStart*TCB结构体中OSTCBStkPtr总是指向用户堆栈最低地址,该地址空间内存放用户堆栈长度,其上空间存放系统堆栈映像,即:用户堆栈空间大小=系统堆栈空间大小+1。SP总是先加1再存数据,因此,SP初始时指向系统堆栈起始地址(OSStack)减1处(OSStkStart)。很明显系统堆栈存储空间大小=SP-OSStkStart。任务切换时,先保存当前任务堆栈内容。方法是:用SP-OSStkStart得出保存字节数,将其写入用户堆栈最低地址内,以用户堆栈最低地址为起址,以OSStkStart为系统堆栈起址,由系统栈向用户栈拷贝数据,循环SP-OSStkStart次,每次拷贝前先将各自栈指针增1。其次,恢复最高优先级任务系统堆栈。方法是:获得最高优先级任务用户堆栈最低地址,从中取出“长度”,以最高优先级任务用户堆栈最低地址为起址,以OSStkStart为系统堆栈起址,由用户栈向系统栈拷贝数据,循环“长度”数值指示的次数,每次拷贝前先将各自栈指针增1。用户堆栈初始化时从下向上依次保存:用户堆栈长度(15),PCL,PCH,PSW,ACC,B,DPL,DPH,R0,R1,R2,R3,R4,R5,R6,R7。不保存SP,任务切换时根据用户堆栈长度计算得出。OSTaskStkInit函数总是返回用户栈最低地址。操作系统tick时钟我使用了51单片机的T0定时器,它的初始化代码用C写在了本文件中。最后还有几点必须注意的事项。本来原则上我们不用修改与处理器无关的代码,但是由于KEIL编译器的特殊性,这些代码仍要多处改动。因为KEIL缺省情况下编译的代码不可重入,而多任务系统要求并发操作导致重入,所以要在每个C函数及其声明后标注reentrant关键字。另外,“pdata”、“data”在uCOS中用做一些函数的形参,但它同时又是KEIL的关键字,会导致编译错误,我通过把“pdata”改成“ppdata”,“data”改成“ddata”解决了此问题。OSTCBCur、OSTCBHighRdy、OSRunning、OSPrioCur、OSPrioHighRdy这几个变量在汇编程序中用到了,为了使用Ri访问而不用DPTR,应该用KEIL扩展关键字IDATA将它们定义在内部RAM中。(4)重写OS_CPU_A.ASMA51宏汇编的大致结构如下:NAME模块名;与文件名无关;定义重定位段必须按照C51格式定义,汇编遵守C51规范。段名格式为:?PR?函数名?模块名;声明引用全局变量和外部子程序注意关键字为“EXTRN”没有E全局变量名直接引用无参数/无寄存器参数函数FUNC带寄存器参数函数_FUNC重入函数_?FUNC;分配堆栈空间只关心大小,堆栈起点由keil决定,通过标号可以获得keil分配的SP起点。切莫自己分配堆栈起点,只要用DS通知KEIL预留堆栈空间即可。?STACK段名与STARTUP.A51中的段名相同,这意味着KEIL在LINK时将把两个同名段拼在一起,我预留了40H个字节,STARTUP.A51预留了1个字节,LINK完成后堆栈段总长为41H。查看yy.m51知KEIL将堆栈起点定在21H,长度41H,处于内部RAM中。;定义宏宏名MACRO实体ENDM;子程序OSStartHighRdyOSCtxSwOSIntCtxSwOSTickISRSerialISREND;声明汇编源文件结束一般指针占3字节。+0类型+1高8位数据+2低8位数据详见C51.PDF第178页低位地址存高8位值,高位地址存低8位值。例如0x1234,基址+0:0x12基址+1:0x34(5)移植串口驱动程序在此之前我写过基于中断
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 建筑工程总平面设计合同标准范本
- 影视制作项目预算合同范本
- 二零二五年度农产品冷链仓储与物流服务合同
- 二零二五年度高端美容美发服务合同
- 二零二五年度农田土地承包经营权流转合同
- 二零二五年度城市地下停车场建设合同
- 二零二五年度房屋抵押贷款期限调整合同示例
- 二零二五年度家具电商平台合作运营合同书
- 二零二五年度房屋过户与装修工程验收合同范本
- 二零二五年度小产权房买卖合同产权交易纠纷调解及和解合同
- 2024届吉林省高考冲刺生物模拟试题含解析
- 全套电子课件:基础会计(第五版)
- 民事起诉状(网购虚假宣传)律师拟定版本
- 精神发育迟滞的护理查房
- 《中式面点》课程标准
- 门面租房合同
- 北师大版一年级数学上册全册教案及教学反思
- 简易施工方案模板范本
- 2023年青海省新华发行集团限公司招聘3人(共500题含答案解析)笔试历年难、易错考点试题含答案附详解
- 中车南京浦镇车辆有限公司
- 0201010204 螺旋锚基础施工
评论
0/150
提交评论