《基于单片机的嵌入式实时OS平台的研究与实现毕业论文.doc》由会员分享,可在线阅读,更多相关《基于单片机的嵌入式实时OS平台的研究与实现毕业论文.doc(38页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、目 录摘 要1Abstract11 绪论21.1 引言21.2 实时操作系统的发展与现状21.3 选题的背景与意义41.4 论文主要研究的内容与论文结构52 嵌入式实时操作系统C/OS-内核分析52.1 C/OS-简介52.2 C/OS-的内核结构72.2.1 临界段的处理72.2.2 任务82.2.3 任务状态82.2.4 任务控制块92.2.5 就绪表112.2.6 任务调度112.2.7 中断和时钟节拍122.2.8 C/OS-初始化及启动123 C/OS-在STC89C52单片机上的移植133.1 STC89C52单片机片简介133.2 C/OS-源文件结构143.2.1 与处理器无关
2、代码153.2.2 与应用相关代码153.2.3 与处理器相关代码163.3 与移植相关代码的修改173.3.1 OS_CPU.H的修改173.3.2 OS_CPU_C.C的修改193.3.3 OS_CPU_A.ASM的修改213.4 C/OS-在STC89C52上的移植223.4.1 Keil C51编译器简介223.4.2 移植测试程序234 基于C/OS-的应用系统设计264.1 基于C/OS-扩展RTOS的体系结构264.2 实时温度控制系统的设计284.2.1 整体设计284.2.2 硬件模块设计284.2.3 系统程序的设计29总结31参考文献32致谢35 基于单片机的嵌入式实时O
3、S平台的研究与实现 摘 要:嵌入式系统融合了微电子、计算机软/硬件、通信和电子工程等多种技术,广泛应用于航空、航天、仪器仪表、工业控制等领域,它已经成为了科技创新的重要途径。而RTOS(Real-Time Operating System)使得在嵌入式操作系统上编程比在传统意义上编程有着更大的优势,随着不断的发展在更多的场合能够发挥其优势和作用。进行嵌入式实时操作系统开发平台的讨论和研究具有非凡的现实意义。论文首先从实时操作系统的整体概念进行论述,对实时操作系统RTOS的发展现状和发展趋势等方面进行了简单综述,然后在第二个章节重点分析了操作系统C/OS-内核结构,如:代码临界断、任务、时钟和中
4、断等。再在第三个章节中,以8位单片机STC89C52为微处理器,以C/OS-内核为嵌入式实时操作系统,以Keil C51为编译环境搭建了一个嵌入式实时操作系统的开发平台。在最后一个章节中,完成了实时温度控制系统的设计。关键词:嵌入式实时操作系统;C/OS-;STC89C52 The Research and Implementation of the Embedded Real-Time Operating System based on MCU Abstract:Embedded System involves much technology, including micro-electro
5、nics,electronic engineering, the software&hardware of computer, communication, and so on. It has been used in aviation, spaceflight, instrument, industrial-control and so on.It is a important method of science and technology innovation. Embedded operation-system has its advantage of programme mode t
6、han traditions owing to RTOS(Real-Time Operating System).The article first talks about the conception of RTOS and introduces the current situation of the development of RTOS and development trend. In the second chapter,the article talks about the kernel particularly of the real-time operation system
7、 C/OS-, for instance, task, clock and interrupt. In third chapter, the article designs the platform of embedded operation system, which regards STC89C52 as control object, reaving kernel C/OS- as operation system, Keil C51 as code warrior. In last chapter the article completes the design of real-tim
8、e temperature control system. Key Words: embedded Real-Time Operation System; C/OS-; STC89C521 绪论1.1 引言 在嵌入式系统的早期时代,应用程序直接控制CPU和各个接口,因此嵌入式系统开发人员需要做出大量的工作与硬件与软件的结合上。硬件只要发生简单的变化,软件就要作大量的改动,应用程序对硬件的依赖性很强。而操作系统的出现,使得硬件与软件在一定程度上分离开来,这为嵌入式软件开发人员节省了大量的时间。操作系统在系统层面上,进行CPU的各种运算执行和资源管理,就是资源管理器;在应用层面上,它为开发人员提供
9、了函数库,便于对硬件进行操作。在现在嵌入式系统中,操作系统的引入,使得大部分不确定的因素得到减少,极大的保证了整个应用系统的稳定性。而对于嵌入式开发人员来说,他们也能够专注于应用系统的开发,不再进行控制CPU的繁杂工作和控制硬件的工作。1.2 实时操作系统的发展与现状 实时操作系统(RTOS)是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统作出快速响应,并控制所有实时任务协调一致运行的操作系统。因而,提供及时响应和高可靠性是其主要特点。纵观其发展,大致可分以下3个阶段:简单的实时操作系统 早期的实时操作系统小而简单的,运行
10、相对快速,带有一定专用型的软件,功能相对单一,不能说是真正的RTOS而是一种监控程序。它一般为用户提供系统初始化管理以及简单的实时时钟管理。这个时间应用较简单,实时性也要求不高,应用程序、实时监控程序和硬件运行平台往往是紧密联系在一起的。 专有的实时操作系统这类操作系统在国外称为Real-Time Operating System Developed in House。它是在当时用户为了满足自身应用需求而开发的,它并不适用于所有的硬件环境,只适用于特殊的硬件条件,因此移植性也不好。随着各个行业的应用发展,早期简单的RTOS已经越来越显出功能单一等各方面的不足。而RTOS的开发者为了满足这种快速
11、发展的应用需求,开发了与之相符合的专有的实时操作系统。通用型实时操作系统 在各种专用RTOS中,一些多任务的机制如优先级的调度、实时时钟管理、任务间的通讯、同步互斥机构基本上是相同的,不同的是面向各自硬件环境与应用目标。实际上,相同的多任务机制是能够共享的,因而可以把这部分很好的组织起来,形成以个通用的实时操作系统.一方面,在RTOS内核的最底层将不同的硬件特性屏蔽掉;另一方面,对不同的应用环境提供标准的、可裁剪的系统服务组件。这使得用户可以根据不同的实时应用要求及硬件环境选择不同的组件,也使得实时操作系统开发商在开发的过程中减少重复性工作。嵌入式实时操作系统的技术经过多年发展已经逐渐走向成熟
12、。嵌入式实时操作系统已广泛应用于家庭、通讯、商业、工业、国防领域,拥有非常多的不同品种的各类产品,例如数码相机、数字电视、掌上机顶盒、电脑PDA、手机、航天飞机、太空飞行器中都应用了嵌入式实时操作系统。目前占据市场的主要有论文所研究的C/OS-以及VxWorks、CLinux等。1.3 选题的背景与意义在嵌入式实时操作系统开发平台之上,开发人员不需要对操作系统的内核实现有详细的了解就能够进行一些嵌入式控制器的开发工作。控制领域的专业人员在利用平台开发嵌入式系统的时候,可以在一定程度上绕开操作系统这个专业壁垒。有嵌入式实时操作系统的开发平台作为基础,开发者只需要将精力集中在各个功能模块的编写之上
13、,模块之间的联系都遵循同样的接口协议。这样不同开发者就可以很方便的进行协作开发,提高开发的效率,而且各个开发者开发的模块也可以相互利用,很好的做到资源共享。这样的开发平台,势必对嵌入式系统在工业控制领域内的应用起到促进作用。C/OS-是由Jean.labrasse于1992年编写的一个嵌入式实时多任务操作系统。最早这个系统叫做C/OS,后来经过10年的应用和修改,在1999年Jean.labrasse推出了C/OS-,并在2000年得到了美国联邦航空管理局对于应用飞机的、符合RTCA DO-178B的标准认证,从而证明了C/OS-具有足够的稳定性和安全性。该操作系统是用C语言和汇编语言编写的,
14、其中大部分代码都是用C语言编写的,只有极少部分与处理器密切相关的代码是用汇编语言编写,所以用户只需做很少的工作可以很方便的移植到各类8位、16位、32位嵌入式处理器上。该操作系统结构简洁精练,可读性强,并具有较强的可扩展性。1.4 论文主要研究的内容与论文结构论文研究的目的是在基于STC89C52单片机的硬件平台上搭建一个C/OS-的应用平台,平台由硬件系统和软件系统两个部分组成:硬件系统:基于STC89C52芯片的硬件系统。软件系统:基于C/OS-内核的嵌入式实时操作系统。论文的主要工作有:C/OS-内核结构介绍与分析。以STC89C52为嵌入式处理器,以Keil C51为编译环境,完成C/
15、OS-嵌入式实时操作系统的移植。基于C/OS-内核扩展RTOS的体系结构,在搭建的平台上完成实时温度控制系统的设计。 2 嵌入式实时操作系统C/OS-内核分析2.1 C/OS-简介C/OS-是一个完整的,可移植、固化、裁剪的占先式实时多任务内核。C/OS-是专为嵌入式应用设计的,可移植在8位、16位、32位单片机或DSP中。C/OS-的主要特点有:源代码开放 全部源代码约5500行,清晰易读,结构协调。可移植性 C/OS-源代码绝大部分是用移植性很强的ANSI C写的,与微处理器硬件相关的部分是用汇编语言写的,便于移植到其他微处理器上。可裁剪 通过条件编译,可以实现C/OS-的裁剪,只使用C/
16、OS-中应用程序需要的服务。 可固化 C/OS-是为嵌入式应用而设计的,这就意味着,只要具备合适的系列软件工具,就可以将C/OS-嵌入到产品中作为产品的一部分。多任务 C/OS-可以管理64个任务,留给用户的应用程序最多可有56个任务,赋予每个任务不同的优先级。可剥夺性 C/OS-是完全可剥夺型的实时内核,总是运行就绪条件下优先级最高的任务。系统服务 C/OS-提供很多系统服务,例如信号量、互斥型信号量、时间标志、消息邮箱、消息队列、块大小固定的内存的申请与释放及时间管理函数等。 中断管理 中断可以使正在执行的任务暂时挂起。如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后
17、立即执行,中断嵌套层数可达255层。可确定性 绝大多数C/OS-的函数调用和服务的执行时间具有可确定性。任务栈 C/OS-允许每个任务有不同的栈空间,以便压低应用程序对RAM的需求。2.2 C/OS-的内核结构2.2.1 临界段的处理C/OS-为了处理临界段代码,须关中断,处理完毕后,再开中断。关中断使得C/OS-能够避免同时有其他任务或中断服务进入临界段代码。C/OS-定义2个宏调用来关中断和开中断,分别是:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。因为这2个宏定义取决于使用的微处理器,故在文件OS_CPU.H中可以找到相应的宏定义。OS_ENTER_CR
18、ITICAL()和OS_EXIT_CRITICAL()总是成对使用的,把临界段代码包起来。2.2.2 任务C/OS-可以管理多达64个任务,有2个任务已经被系统占用。必须个每个任务赋以不同的优先级,所以优先级从0到OS_LOWEST_PRIO-2优先级号越低,任务的优先级越高。 在C/OS-中任务通常是一个无限的循环。看起来就像其他C函数一样,有函数返回类型,但是绝对不会返回的,故返回参数必须定义成void。2.2.3 任务状态下图是C/OS-任务状态转换图,在任一给定的时间,任务状态一定是在以下5种状态之一: 图2.1 任务状态睡眠态 指任务驻留在程序空间,还没有交给C/OS-来管理。就绪态
19、 任务一旦建立,这个任务就进入了就绪态,准备运行。运行态 任务占有CPU,正在运行。等待状态 等待除CPU以外的其它资源或条件(如信号量),不能运行。中断服务态 正在运行的任务被中断,进入中断服务子程序。2.2.4 任务控制块任务控制块是一个数据结构,它与任务一一对应的。在操作系统初始化时,系统申请了一块RAM空间来存储空闲任务块。一旦任务建立,系统就会分配一个任务控制块OS_TCB(task control blocks)给该任务。当任务的CPU使用权被剥夺时,C/OS-用它来保存该任务的状态,当任务重新得到CPU的使用权时,任务控制块能确保任务从断点处继续执行下去。OS_TCB全部驻留在R
20、AM中,在任务建立时,OS_TCB被初始化。数据结构如下:typedef struct os_tcb OS_STK *OSTCBStkPtr;#if OS_TASK_CREATE_EXT_EN0 void *OSTCBExtPtr; OS_STK *OSTCBStkBottom; INT32U OSTCBStkSize; INT16U OSTCBOpt; INT16U OSTCBId;#endif struct os_tcb *OSTCBNext; struct os_tcb *OSTCBPrev;#if (OS_Q_EN0)&(OS_MAX_QS0)|(OS_MBOX_EN0)| (OS_S
21、EM0)|(OS_MUTEX_EN0) OS_EVENT *OSTCBEventPtr;#endif#if (OS_Q_EN0)&(OS_MAX_QS0)|(OS_MBOX_EN0) void *OSTCBMsg;#endif#if (OS_VERSION=251)&(OS_FLAG_EN0)&(OS_MAX_FLAGS0)#if OS_TASK_DEL_EN0 OS_FLAG_NODE *OSTCBFlagNode;#endif OS_FLAGS OSTCBFlagsRdy;#endif INT16U OSTCBDly; INT8U OSTCBStat; INT8U OSTCBPrio; I
22、NT8U OSTCBX; INT8U OSTCBY; INT8U OSTCBBitX; INT8U OSTCBBitY:#if OS_TASK_DEL_EN0 BOOLEAN OSTCBDelReq;#endifOS_TCB2.2.5 就绪表C/OS-中每个就绪的任务都放在就绪表中,就绪表中有2个变量,OSRdyGrp和OSRdyTb1。在OSRdyGrp中,任务按优先级分组,8个任务为一组。OSRdyGrp中的每一位表示8组任务中每一组是否有进入就绪态的任务。任务进入就绪态时,就绪表OSRdyTb1中的相应元素的相应位也置为1。2.2.6 任务调度在多任务系统中,令CPU中止当前正在运行的任
23、务而转去运行另外一个任务的工作叫做任务的切换,而按照某种规则进行任务切换的工作叫做任务的调度。在C/OS-中,任务调度是由任务调度器来完成的。任务调度器的主要工作有两项:一是在任务就绪表中查找具有最高优先级别的就绪任务;二是实现任务的切换。C/OS-有两种调度器一种是任务及的调度器;另一种是中断级的调度器。任务级的调度器由函数OSSched()来实现,而中断级的调度器由函数OSIntExt()来实现。调度器把任务切换工作分为两个步骤:第一是获得待运行任务的TCB指针:第二是进行断点数据的切换。2.2.7 中断和时钟节拍C/OS-中,中断服务子程序是用汇编来写的,下面是中断处理程序一般处理过程的
24、示意代码:用户中断服务子程序: 保存全部CPU寄存器; 调用OSIntEnter或OSIntNesting直接加1; 执行用户代码做中断服务; 调用OSIntExit(); 恢复所有CPU寄存器; 执行中断返回指令;时钟节拍是周期性发生的特殊中断(时钟中断),这个中断可视为系统心脏的跳动。操作系统通过时钟中断来确定时间间隔,实现时间延时及确定超时。时钟中断的频率越高,系统的额外负荷越多。通常将频率设置在10到100Hz之间。用户必须在多任务系统启动以后再启动时钟节拍源计时也就是在调用OSStart()之后。如果在之前调用,时钟节拍中断可能在C/OS-启动第一个任务之前发生,此时C/OS-是处在
25、一个不确定的状态之中,用户应用程序可能崩溃。2.2.8 C/OS-初始化及启动在调用C/OS-的任何其他服务之前,C/OS-要求用户首先调用系统初始化函数OSInit()。OSInit()初花C/OS-所有的变量和数据结构。OSInit()将建立空闲任务OSTaskIdle(),这个任务总是处于就绪态的。空闲任务的优先级为最低,即为OS_LOWST_PRIO。如果使用统计任务OSTaskStat(),则会建立统计任务并让其进入就绪态,其优先级总是为OS_LOWST_PRIO-1。C/OS-还初始化了4个空数据结构缓冲区。每个缓冲区都是单向链表,允许C/OS-从缓冲区中迅速得到或释放一个缓冲区中
26、的元素。C/OS-多任务的启动是用户通过调用OSStart()实现的,在启动之前,用户至少要建立一个应用任务。OSStart()是从任务就绪表中构造出优先级最高的任务,然后调用高优先级就绪任务启动函数OSStartHighRdy(),这是一个跟处理器相关的函数,可以用汇编语言来实现。OSStartHighRdy()将永远不返回到OSStart()。3 C/OS-在STC89C52单片机上的移植3.1 STC89C52单片机片简介MCS-51系列单片机是美国Intel公司在1980年推出的高性能8位单片机微型计算机,较原来的MCS-48系列结构更为新进,功能增强,它包括51和52两个系列。全球各
27、单片机生产厂商在MCS51内核基础上,派生了大量的51内核系列单片机,是极大地丰富了MCS51的种群。其中,STC公司推出了STC89系列单片机,增加了大量的新功能,提高了51单片机的性能。STC89C52单片机是MCS-51系列单片机的派生产品。它在指令系统、硬件结构和片内资源上与标准的8051单片机完全兼容。其主要特性如下: 增强型6时钟/机器周期,12时钟/机器周期8051核心处理单 元。3.4V-5.5V工作电压,工作频率范围:0-40MHZ。 8K字节片内程序存储器ROM;片上集成512字节RAM;通用I/O口32个,复位后为:P1/P2/P3是准双向口,P0口是开漏输出,作为总线扩
28、展时用,不用加上拉电阻,作为I/O口用时,需加上拉电阻;可编程看门狗定时器(WDT)。3个16位定时器/计数器,其中定时器0还刻意当成2个8位 定时器;外部中断4路,下降沿中断或低电平出发中断。SPI(串行外围接口)和增强型UART。3.2 C/OS-源文件结构C/OS-的源文件构成如下图所示,C/OS-操作系统由三部分代码组成,主要是与处理器相关的代码、与应用程序有关的代码、与移植相关的代码,如图3.1所示: 图3.1 C/OS-源文件结构3.2.1 与处理器无关代码与处理器无关的代码主要是OS_CORE.C、OS_FLAG.C、OS_MBOX.C、OS_MEM.C、OS_MUTEX.C、O
29、S_Q.C、OS_SEM.C、OS_TASK.C、OS_TIME.CuCOS_II.C、uCOS_II.H。这些代码大致分为一下几个部分:内核结构部分、任务管理部分、时间控制块、时间管理部分、信号管理部分、信号量管理、互斥信号量管理、时间标志组管理、消息邮箱管理以及消息队列管理。3.2.2 与应用相关代码与应用相关的代码主要是两个文件:OS_CFG.H、INCLUDES.H。 OS_CFG.H文件主要功能是实现操作系统的裁剪功能。包含了许多C/OS-的初始化配置选项。在C/OS-中每个函数只有当通过文件OS_CFG.H中的对应项“置1”,才刻意使用该函数,该函数是否使用是通过条件编译实现的。I
30、NCLUDES.H文件是一个主头文件,它出现在每个.C文件的第一行。使用INCLUDES.H的好处是所有的.C文件都只包含一个头文件,程序简洁,可读性强。缺点是.C文件可能会包含一些它并不需要的头文件,额外的增加编译时间。用户刻意改写INCLUDES.H文件,增加自己的头文件,但必须加在文件末尾。3.2.3 与处理器相关代码这是移植中最关键的部分,内核将应用系统和底层硬件有机的结合成一个实时系统,要使同一个内核能适用于不同的硬件体系,就需要在内核和硬件之间有一个中间层,这就是与处理器相关的代码。处理器不同,这部分代码也不同。与处理器相关的代码是OS_CPU.H、OS_CPU_A.ASM、OS_
31、CPU_C.C。OS_CPU.H包括了用#defines定义的与处理器相关的常量,宏和类型定义。因为不同的处理器有不同的字长,所以C/OS-的移植包括了一系列的类型定义以确保其可移植性。 OS_CPU_C.C文件中共定义了10个函数在该文件中。但是最重要的是OSTaskStkInit()。其他9个函数必须声明,但都是对系统内核的扩展时用的。OSTaskStkInit()是在用户建立任务时被函数OSTaskCreate()和OSTaskCreateExt()调用,是系统内部自己调用的,用来对用户任务的堆栈进行初始化,并使用建立好的进入就绪态任务的堆栈与系统发生中断并且将环境变量保存完毕时的栈结构
32、一致。这样就可以用中断返回指令使就绪的任务运行起来。OS_CPU_A.ASM文件里包含了4个简单的汇编函数。OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()、OSTickISR()。OSStartHighRdy()函数在多任务系统启动函数OSStart()中调用。OSCtxSw()函数实在任务级切换函数中调用的。OSIntCtxSw()在退出中断服务函数OSIntExit()中调用,实现中断级任务切换。OSTickISR()系统时钟节拍中断服务函数,这是一个周期性中断,为内核提供时钟节拍,频率越高系统负荷越重。3.3 与移植相关代码的修改3.3.1 OS_CPU.
33、H的修改修改后的OS_CPU.H代码如下所示:/* 文件名:OS_CPU.H */#ifndef _OS_CPU_H#define _OS_CPU_H#ifdef OS_CPU_GLOBALS#define OS_CPU_EXT#else#define OS_CPU_EXT extern#endif /* 数据类型 */* (编译器相关) */typedef unsigned char BOOLEAN; typedef unsigned char INT8U; typedef signed char INT8S; typedef unsigned int INT16U; typedef sig
34、ned int INT16S; typedef unsigned long INT32U; typedef signed long INT32S; typedef float FP32; typedef double FP64; typedef unsigned char OS_STK; typedef unsigned char OS_CPU_SR; /* 处理器相关代码 */ #define OS_CRITICAL_METHOD 1#if OS_CRITICAL_METHOD = 1#define OS_ENTER_CRITICAL() EA=0 #define OS_EXIT_CRITI
35、CAL() EA=1 #endif #define OS_STK_GROWTH 0 #define OS_TASK_SW() OSCtxSw() #define OS_ISR_PROTO_EXT1void OSCtxSw(void);void InitHardware(void) reentrant; /*/ #endif 首先,文件先定义了整型数据类型。举例来说,INT16U数据类型总是代表16位的无符号整型数。为了方便起见,虽然C/OS-中并不使用浮点数,但还是定义了浮点数据类型。同时,将任务堆栈的宽度定义为8位。其次,OS_CRITICAL_METHOD的值意味着OS_ENTER_CRI
36、TICAL()和OS_EXIT_CRITICAL()两个宏调用的实现方法。在此OS_CPU.H中,将OS_CRITICAL_METHOD的值宏定义为1,即OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()两个宏调用的实现方法为最简单的方法:调用相应处理器指令关中断和开中断(EA=0和EA=1)。最后,文件还通过宏定义指定了OS_STK_GROWTH的值为0。这表明堆栈从下(低地址)往上(高地址)递增。而声明函数OSCtxSw(),是用子程序调用来代替中断调用;声明InitHardware(),该函数用来实现初始化硬件时钟中断等系统初始化工作。3.3.2 OS_CPU_
37、C.C的修改在OS_CPU_C.C文件中,最重要的是OSTaskStkInit()函数,OSTaskStkInit()是在用户建立任务时被函数OSTaskCreate()和OSTaskCreateExt()调用,是系统内部自己调用的,用来对用户任务的堆栈进行初始化,并使用建立好的进入就绪态任务的堆栈与系统发生中断并且将环境变量保存完毕时的栈结构一致。这样就可以用中断返回指令使就绪的任务运行起来。其代码如下:OS_STK *OSTaskStkInit (void (*task)(void *pd) reentrant, void *ppdata, OS_STK *ptos, INT16U opt
38、) reentrant OS_STK *stk; ppdata = ppdata; opt = opt; stk = ptos; /用户堆栈最低有效地址 *stk+ = 15; /用户堆栈长度 *stk+ = (INT16U)task & 0xFF; /任务地址低8位 *stk+ = (INT16U)task 8; /任务地址高8位 *stk+ = 0x0A; /ACC *stk+ = 0x0B; /B *stk+ = 0x00; /DPH *stk+ = 0x00; /DPL *stk+ = 0x00; /PSW *stk+ = 0x00; /R0 *stk+ = (INT16U)ppdat
39、a & 0xFF; /R1 *stk+ = (INT16U)ppdata 8; /R2 *stk+ = 0x01; /R3 *stk+ = 0x04; /R4 *stk+ = 0x05; /R5 *stk+ = 0x06; /R6 *stk+ = 0x07; /R7 *stk+ = (INT16U) (ptos+MaxStkSize) 8; *stk+ = (INT16U) (ptos+MaxStkSize) & 0xFF; return (void *)ptos);3.3.3 OS_CPU_A.ASM的修改移植工作的难点是在OS_CPU_A.ASM文件上,这里用户需要编写4个汇编语言函数:O
40、SStartHighRdy()、OSCtxSw()、OSIntCtxSw()和OSTickISR()。其中,OSTickISR()在OS_CPU_C.C中已经用C语言实现,即用定时器中断处理了程序来代替它。因此,只需要写3个汇编语言函数。OS_CPU_A.ASM部分代码如下: EXTRN DATA (?C_XBP) EXTRN IDATA (OSTCBCur) EXTRN IDATA (OSTCBHighRdy) EXTRN IDATA (OSRunning) EXTRN IDATA (OSPrioCur) EXTRN IDATA (OSPrioHighRdy) EXTRN CODE (_?O
41、STaskSwHook) EXTRN CODE (_?OSIntEnter) EXTRN CODE (_?OSIntExit) EXTRN CODE (_?OSTimeTick)在OS_CPU_A.ASM的首部,声明了引用的全局变量和外部子程序。接着是3个汇编函数OSStartHighRdy()、OSCtxSw()、OSIntCtxSw():调用运行优先级最高的就绪任务函数OSStartHighRdy()。该函数是在操作系统初始化并建立了至少一个任务之后被调用的,它首先找到当前就绪的最高优先级任务,并从该任务控制块OS_TCB中取出堆栈指针,然后从堆栈中弹出全部寄存器,并RET返回。任务切换函
42、数OSCtxSw()。该函数是由于执行进入任务切换宏OS_TASK_SW而进入的,它是一个任务级的切换函数,它的主要任务是保存当前任务的CPU现场并恢复最高优先级任务的CPU现场。中断任务切换函数OSIntCtxSw()。该函数的工作是在中断处理程序退出时进行任务切换。OSIntCtxSw()的代码大部分都与OSCtxSw()相同,仅仅在以下两点有所区别:由于中断已经发生,此处不需要再保存寄存器;OSIntCtxSw()需要调整堆栈指针,去掉堆栈中一些不需要的内容,以使堆栈中止包含任务的运行环境。3.4 C/OS-在STC89C52上的移植3.4.1 Keil C51编译器简介大部分的C/OS
43、-代码是用C语言写的。因此,移植C/OS-需要一个C编译器,此处选择Keil C51作为开发平台。Keil C51是美国Keil Software公司出品的基于80C51内核的微处理器软件开发平台,内嵌多种符合当前工业标准的开发工具,可以完成从工程的建立、管理、软件编译、链接,到目标代码的生成、软件方针和硬件方针等完整的开发流程。尤其C编译工具在产生代码的准确性和效率方面达到了较高的水平,而且刻意附加灵活的控制选项,在开发大型项目时非常理想。原则上我们不用修改与处理器无关的代码,但是由于Keil C51编译器的特殊性,这些代码仍要多出改动。因为Keil C51在缺省情况下,编译的代码不可重入,而多任务系统要求并发操作导致重入,所以要在每个C函数及其声明后标注r