uC_OS-II实验指导书_第1页
uC_OS-II实验指导书_第2页
uC_OS-II实验指导书_第3页
uC_OS-II实验指导书_第4页
uC_OS-II实验指导书_第5页
已阅读5页,还剩82页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C_OS-II实验指导书电子科技大学嵌入式软件工程中心北京科银京成技术有限公司目录第一部分 实验系统简介及入门51 实验系统的目的52 实验系统的构成53 操作系统简介53.1 C/OS-II概述53.2 C/OS-II的特点63.3 C/OS-II主要源代码文件介绍74 LambdaTOOL集成开发环境简介75 C/OS-II实验内容简介85.1 任务管理实验85.2 优先级反转实验85.3 优先级继承实验95.4 哲学家就餐实验95.5 内存管理实验95.6 时钟中断实验95.7 消息队列实验96 预备实验:嵌入式开发环境的建立96.1 目的96.2 实验步骤及说明10第二部分 C/OS-II实验24实验1 任务的基本管理241 实验目的242 实验原理及程序结构242.1 实验设计242.2 操作系统配置252.3 源程序说明273 运行及观察应用输出信息294 本实验中所用到的C/OS-II相关函数314.1 OSTaskCreate()314.2 OSTaskSuspend()314.3 OSTaskResume()32实验2 优先级反转331 实验目的332 原理及程序结构332.1 实验设计332.2 操作系统配置352.3 源程序说明363 运行及观察应用输出信息394 本实验中所用到的C/OS-II相关函数394.1 OSSemCreate()394.2 OSSemPend()404.3 OSemPost()404.4 OSTimeDly()41实验3 优先级继承421 实验目的422 原理及程序结构422.1实验设计422.2 操作系统配置453 运行及观察应用输出信息464 本实验中所用到的C/OS-II相关函数474.1 OSMutexCreate()474.2 OSMutexPend()474.3 OSMutexPost()485 应用调试过程49实验4 信号量:哲学家就餐问题的实现511 实验目的512 原理及程序结构512.1 实验设计512.2 操作系统配置523运行及观察应用输出信息534 本实验中所用到的C/OS-II相关函数55实验5 C/OS-II的内存管理561 实验目的562 原理及程序结构562.1实验设计562.2 操作系统配置623 本实验中所用到的C/OS-II相关函数633.1 OSMemCreate()633.2 OSMemGet()643.3 OSMemPut()643.4 OSMemQuery()65实验6 时钟中断661 实验目的662 原理及程序结构662.1 实验设计662.2 操作系统配置683 运行及观察应用输出信息704 本实验中所用到的C/OS-II相关函数71实验7 消息队列721 实验目的722 原理及程序结构722.1 实验设计722.2 源程序说明722.3 操作系统配置773 运行及观察应用输出信息784 本实验中所用到的C/OS-II相关函数824.1 OSQCreate()824.2 OSQPend()824.3 OSQPostFront()834.4 OSQPost()834.5 OSQFlush ()844.6 OSQQuery()844.7 OSQDel()854.8 OSTimeDlyHMSM()85第一部分 实验系统简介及入门1 实验系统的目的通过此实验系统,读者可以了解嵌入式实时操作系统C_OS-II的内核机制和运行原理。本实验系统展示了COS-II各方面的管理功能,包括信号量、队列、内存、时钟等。在各个实验中具体介绍了COS-II的相关函数。读者在做实验的同时能够结合理论知识加以分析,了解各个函数的作用和嵌入式应用程序的设计方法,最终对整个Cos和嵌入式操作系统的应用有较为清楚的认识。2 实验系统的构成本实验系统由以下各部分组成:1 COS-II嵌入式实时操作系统。这个操作系统是开放源代码的; 2 LambdaTOOL。一个开发嵌入式软件的集成开发环境;3 BSP。针对特定嵌入式硬件平台的板级支持包,提供板级初始化代码和一些基本的驱动程序;4 实验用例程序。基于特定的嵌入式操作系统(在本实验系统中是COS-II)的应用程序代码。3 操作系统简介3.1 C/OS-II概述C/OS-II是一个抢占式实时多任务内核。C/OS-II是用ANSI的C语言编写的,包含一小部分汇编语言代码,使之可以提供给不同架构的微处理器使用。至今,从8位到64位,C/OS-II已经在40多种不同架构的微处理器上使用。世界上已经有数千人在各个领域中使用C/OS,这些领域包括:照相机行业、航空业、医疗器械、网络设备、自动提款机以及工业机器人等。C/OS-II全部以源代码的方式提供给读者,大约有5500行。CPU相关的部分使用的是针对Intel80x86微处理器的代码。虽然C/OS-II可以在PC机上开发和测试,但是可以很容易地移植到不同架构的嵌入式微处理器上。3.2 C/OS-II的特点1、源代码:C/OS-II全部以源代码的方式提供给使用者(约5500行)。该源码清晰易读,结构协调,且注解详尽,组织有序;2、可移植(portable): C/OS-II的源代码绝大部分是用移植性很强的ANSI C写的,与微处理器硬件相关的部分是用汇编语言写的。C/OS-II可以移植到许许多多不同的微处理器上,条件是:该微处理器具有堆栈指针,具有CPU内部寄存器入栈、出栈指令,使用的C编译器必须支持内嵌汇编,或者该C语言可扩展和可链接汇编模块,使得关中断和开中断能在C语言程序中实现;3、可固化(ROMable): C/OS-II是为嵌入式应用而设计的,意味着只要具备合适的系列软件工具(C编译、汇编、链接以及下载/固化)就可以将C/OS-II嵌入到产品中作为产品的一部分;4、可裁减(scalable): 可以只使用C/OS-II中应用程序需要的系统服务。可裁减性是靠条件编译实现的,只需要在用户的应用程序中定义那些C/OS-II中的功能应用程序需要的部分就可以了;5、可抢占性(preemptive): C/OS-II是完全可抢占型的实时内核,即C/OS-II总是运行就绪条件下优先级最高的任务;6、多任务: C/OS-II可以管理64个任务。赋予每个任务的优先级必须是不相同的,这就是说C/OS-II不支持时间片轮转调度法(该调度法适用于调度优先级平等的任务);7、可确定性: 绝大多数C/OS-II的函数调用和服务的执行时间具有可确定性。也就是说用户能知道C/OS-II的函数调用与服务执行了多长时间。进而可以说,除了函数OSTimeTick()和某些事件标志服务,C/OS-II系统服务的执行时间不依赖于用户应用程序任务数目的多少;8、任务栈: 每个任务都有自己单独的栈。C/OS-II允许每个任务有不同的栈空间,以便降低应用程序对RAM的需求;9、系统服务: C/OS-II提供许多系统服务,比如信号量、互斥信号量、事件标志、消息邮箱、消息队列、时间管理等等;10、中断管理: 中断可以使正在执行的任务暂时挂起。如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可以达255层;11、稳定性和可靠性: C/OS-II的每一种功能、每一个函数以及每一行代码都经过了考验和测试,具有足够的安全性与稳定性,能用于与人性命攸关、安全性条件极为苛刻的系统中。3.3 C/OS-II主要源代码文件介绍C/OS-II的源代码具体包括以下的文件:PC.C:源文件PC.H包含了对函数和环境的一些定义。OS_CORE.C OS_FLAG.C OS_MBOX.C OS_MEM.C OS_MUTEX.C OS_Q.C OS_SEM.C OS_TASK.C OS_TIME.C COS-II.C COS-II.H :这些文件是C/OS-II中所有与处理器类型无关部分的源代码。OS_CPU_A.S OS_CPU_C.C OS_CPU.H :这些文件是与处理器类型相关部分的源代码,在本实验系统中是面向80x86处理器的。 INCLUDES.H给整个内核库提供了总体的include文件。OS_CFG.H: C/OS-II的配置文件,定义使用C/OS-II中的哪些功能。4 LambdaTOOL集成开发环境简介LambdaTOOL是一个通用、统一、开放的新一代32位嵌入式软件集成开发环境,支持多种嵌入式操作系统和32位嵌入式处理器,具备先进的新一代交叉开发环境和系统配置工具。本实验系统中提供的LambdaTOOL是其面向教学的免费版本,具备支持嵌入式软件仿真开发的完整功能,具体由下列内容组成:l 编辑环境l 系统配置l 编译环境l 目标机管理l 调试环境在本实验系统中,采用LambdaTOOL提供的一个PC虚拟机作为实验项目运行的仿真目标平台。在LambdaTOOL上项目的开发流程如下图所示:有关开发流程的细节请看后面的“预备实验:嵌入式开发环境的建立”。5 C/OS-II实验内容简介5.1 任务管理实验此实验的目的是让读者理解嵌入式操作系统中任务管理的基本原理,了解任务的各个基本状态及其变迁过程;掌握C/OS-II中任务管理的基本方法(创建、启动、挂起和解挂任务);熟练使用C/OS-II任务管理的基本系统调用。5.2 优先级反转实验通过此实验读者可以了解在基于抢占式嵌入式实时操作系统并有共享资源的应用中,出现优先级反转现象的原理。优先级反转发生在有多个任务共享资源的情况下,高优先级任务被低优先级任务阻塞,并等待低优先级任务执行的现象。5.3 优先级继承实验通过此实验读者可以了解嵌入式实时操作系统C/OS-II解决优先级反转的策略优先级继承的原理,以此解决低优先级任务在占用了共享资源的情况下,被高优先级任务抢占了CPU使用权而导致的优先级反转的问题。5.4 哲学家就餐实验通过经典的哲学家就餐应用,读者可以了解如何利用嵌入式实时操作系统C/OS-II的信号量机制来对共享资源进行互斥访问。5.5 内存管理实验通过此实验读者可以了解嵌入式实时操作系统C/OS-II中的内存管理的原理,包括对内存的分配和回收。5.6 时钟中断实验通过此实验读者可以了解嵌入式实时操作系统C/OS-II中,时钟中断的使用情况。5.7 消息队列实验通过此实验读者可以了解嵌入式实时操作系统C/OS-II中的消息队列机制。读者可以了解一个应用中的任务是如何进行通信的,如何能使它们相互协调工作。6 预备实验:嵌入式开发环境的建立6.1 目的a) 掌握嵌入式软件开发环境的建立过程;b) 初步掌握嵌入式程序的编译和调试过程。6.2 实验步骤及说明1、安装集成开发环境LambdaTOOL3:集成开发环境LambdaTOOL3的安装文件夹为LambdaPRO3.1_edu,其中有一个名为“Setup.exe”的文件,直接双击该文件便可启动安装过程。具体的安装指导请看“LambdaPRO3.1_edu安装手册.doc”文件。(在本指导书后面的描述中,假定LambdaTOOL被安装在了D盘根目录之下,根目录为D:/LambdaPRO。)当LambdaTOOL3安装完毕之后,我们看到的是一个空的界面,现在就开始一步一步地将我们的实验项目建立并运行起来。2、建立项目。想让我们的实验运行起来,需要建立3个项目:两个“静态库项目”和一个“操作系统无关项目”。首先,看看“静态库项目”是如何建立的:到了这里,点击下一步:在上面的窗口中,需要填写你为该项目起的名字(在这里是ucos),并设定项目文件所在的目录。对于刚开始使用LambdaTOOL工具的读者,最好选择缺省设置的目录位置;如果你对工具很熟悉,可以改成自己喜欢的目录。好了,点击下一步,你看到的是如下界面:附加名可暂时空着,由于本实验的目标运行平台是一个PC虚拟机,所以体系结构就选“x86”。 这也是嵌入式软件开发与桌面应用开发的一个不同的地方,我们不可避免地需要考虑硬件方面的问题。在“配置”栏中选择“i386_le_soft”(表示数据在内存中是以小端的方式存放,并使用软浮点库),然后点击“完成”按钮。这样,你就已经建立好了一个静态库项目。我们的工程需要两个静态库项目,所以请按照上面的方法,再建立一个叫uc_bsp的项目。建立“操作系统无关项目”。刚才在建立静态库项目的时候你就已经发现了,有一种叫做“操作系统无关项目”的选项,这次就选择建立这样的一个项目,取名为“appTest”:之后的步骤并不像静态库项目一样简单,多了些选项:内存摸板:D:/LambdaPRO/target/deltaos/bsps/boards/pc386/mtp/tra_debug.mtp(采用目标监控器调试时的内存模板)启动类型:D:/LambdaPRO/target/deltaos/bsps/boards/pc386/start/tra_debug(采用目标监控器调试时的启动方式)3、拷贝项目文件设置完成之后,该实验所需的所有项目都建立好了,不过ucos和uc_bsp的src目录里面都是空的。这时候需要在系统的资源管理器中复制相关的源文件,然后粘贴到相应项目的src目录中就可以了。在uc_bsp项目的src目录中粘贴BSP(Board Support Package,板级支持包)相关的文件(包括driver和syscall子目录);在ucos项目的src目录中粘贴C/OS-II的内核源文件。在你所建立的操作系统无关项目appTest中,已经存在了一个应用源代码文件init.c ,请把这个文件删除,然后把相应的实验用例程序源文件(如:任务管理.c)粘贴到src目录下,下图是粘贴完毕后的结果。4、项目配置uc_bsp和ucos这两个静态库项目的目的是为了生成两个库文件:libuc_bsp.a(板级支持包库)和libucos.a(C/OS-II内核库),而appTest是我们最终的实验项目,它需要调用到libuc_bsp.a和libucos.a的一些功能。因此这3个项目的构建顺序应该是:先使用静态库项目生成应用所需的库文件到指定路径中,然后用appTest项目生成最终应用。1)对于静态库项目uc_bsp和ucos,需要设置生成的库文件的名称和输出路径。将鼠标放在项目名称上并点击右键,在弹出的快捷菜单中点击“属性”,如下图所示:以ucos项目为例,在“属性”中的“构建构建设置输出路径”中进行如下设置: 库文件名:libucos 输出路径:D:/LambdaPRO/target/deltaos/lib/x86/i386/little2)在构建项目前,我们需要设置一些编译器可能用到的路径(三个项目均需要设置)在“属性”中的“构建工具设置路径”中添加路径,单击工具条()上的增加按钮(第一个按钮),在弹出的窗口中设置如下路径: 对于ucos项目,需设置如下路径:D:/LambdaPRO/host/ide/workspace/ucos/src (系统自动添加) 对于uc_bsp项目,需设置如下路径:D:/LambdaPRO/host/ide/workspace/uc_bsp/src;(系统自动添加) 对于appTest项目,需设置如下路径:D:/LambdaPRO /host/ide/workspace/appTest/src (系统自动添加)D:/LambdaPRO/host/ide/workspace/ucos/src (需手动添加)说明:本实验系统所用的LambdaTOOL会自动添加在本项目的构建过程中可能需要的相关路径,一般不必进行额外的设置,但项目appTest由于要调用src目录下定义的一些头文件,因此必须手动添加上面的路径。3)库搜索路径的设置项目appTest要用到uc_bsp和ucos两个项目产生的库文件,因此需要设置appTest的库搜索路径:在项目appTest的“属性”中的“构建工具设置库”中进行设置:添加uc_bsp和ucos两个库,并在库搜索路径中设置库所在的路径。(由于在前面设置库的生成路径时,设置的是系统默认的搜索路径,因此这里可免除这一步骤。)5、构建项目到此为止,你已经将项目配置得差不多了,再稍加一些东西,就可以运行一个应用项目了。下一个步骤就是构建项目生成可运行的程序了(这个过程包含了编译、链接等操作):之后弹出的对话框显示了构建的进度,可以点击“在后台运行”,以隐藏该对话框。在“构建信息”视图里可以查看项目的构建信息:在“问题”视图里可以查看项目构建的问题记录。如果在这些问题中没有出现“错误”而只是一些“警告”或“信息”,则表明构建是成功的。注意:ucos和uc_bsp项目必须先于appTest构建,以生成相关的库文件,这些库文件是可以供所有的实验应用项目使用的。因此当你替换appTest中的应用源代码文件以构建不同的实验应用时,不需要重新构建ucos和uc_bsp项目,只需对appTest重新进行构建。6、配置虚拟机和目标机代理本实验系统所用的目标运行平台是一个运行在桌面系统中的PC虚拟机,为了启动这个虚拟机,需要首先制作它的“启动盘”。1)制作X86启动盘在LambdaTOOL中选择“文件新建其它Lambada制作X86启动盘制作虚拟机TA启动映像”,对启动盘进行一些参数设置后(如下图所示),系统将自动为你生成一个PC虚拟机的启动盘映像。注意:在设置IP地址时,应选择你的PC机所在的局域网中没有被占用的一个IP地址。2)配置虚拟机启动盘制作完成后,选择“虚拟机配置虚拟机”菜单,系统弹出如下对话框:注意:如果在你的计算机上安装有vmware等虚拟机,应事先将其虚拟的网卡禁用,以免产生冲突。3)创建目标机代理配置好虚拟机后,创建目标机代理:点击LambdaTOOL左下方窗口中绿色的十字符号,在弹出的窗口中选择“基于TA的连接方式”,并点击“下一步”。在弹出的窗口中设置连接参数,这些参数应该与你之前制作启动盘时设置的参数一致:基本信息: 名字:输入目标机的名字(缺省是default); 日志:选择No;连接参数: 连接类型:默认选择UDP,不能更改; IP地址:这里输入目标机(在本实验系统中是虚拟机)的IP地址; 端口号:输入目标机的端口(固定为1118); 超时:超时时间的定义。例如,一般输入值为100,表示如果连接超过100ms还未连接成功,则算一次连接超时,重新开始连接; 重试:数据超时重试最大次数。例如,一般输入值为100,表示如果100次超时重试均失败,则退出报错。最后点击“确定”,在目标机管理窗口中,可以看到新增加了一个名为default的目标机节点。7、调试应用1)启动虚拟机虚拟机启动后的画面如下(其中显示的IP地址即为步骤61)中设置的IP地址):2)在“目标机管理”窗口中启动目标机代理:选中之前创建的目标机代理项,并点击绿色的按钮:之后如果成功与目标机建立连接,则原先绿色的按钮会变灰,其旁边红色的按钮会被点亮。3)当成功构建完成appTest后,在该项目的“x86_i386_le_soft_elf_tra_debug”上点击鼠标右键,在弹出的菜单中选择“调试方式调试应用程序”,启动调试器调试生成的程序:程序下载完成后,会弹出一个“确认透视图切换”对话框,选择“是”,切换到调试透视图。4)调试的界面如下:LambdaTOOL中集成的调试器功能强大,比较常用的操作包括查看变量内容、设置程序的断点、观察寄存器的状态等等。具体可参见LambdaTOOL的联机帮助系统。第二部分 C/OS-II实验实验1 任务的基本管理1 实验目的 理解任务管理的基本原理,了解任务的各个基本状态及其变迁过程; 掌握C/OS-II中任务管理的基本方法(创建、启动、挂起、解挂任务); 熟练使用C/OS-II任务管理的基本系统调用。2 实验原理及程序结构2.1 实验设计为了展现任务的各种基本状态及其变迁过程,本实验设计了Task0、Task1两个任务:任务Task0不断地挂起自己,再被任务Task1解挂,两个任务不断地切换执行。通过本实验,读者可以清晰地了解到任务在各个时刻的状态以及状态变迁的原因。起始任务Task0Task1Task0Task0Task1Task1t0 t1 t2 t3 t4 t5 t6 t7 t8 图1-1图1注意:图中的栅格并不代表严格的时间刻度,而仅仅表现各任务启动和执行的相对先后关系。2.1.1 运行流程整个应用的运行流程如图1所示,其描述如下:(1)系统经历一系列的初始化过程后进入boot_card()函数,在其中调用ucBsp_init()进行板级初始化后,调用main()函数;(2)main()函数调用OSInit()函数对C/OS-II内核进行初始化,调用OSTaskCreate创建起始任务TaskStart;(3)main()函数调用函数OSStart()启动C/OS-II内核的运行,开始多任务的调度,执行当前优先级最高的就绪任务TaskStart;(4)TaskStart完成如下工作:a、安装时钟中断并初始化时钟,创建2个应用任务;b、挂起自己(不再被其它任务唤醒),系统切换到当前优先级最高的就绪任务Task0。之后整个系统的运行流程如下:l t1时刻,Task0开始执行,它运行到t2时刻挂起自己;l t2时刻,系统调度处于就绪状态的优先级最高任务Task1执行,它在t3时刻唤醒Task0,后者由于优先级较高而抢占CPU;l Task0执行到t4时刻又挂起自己,内核调度Task1执行;l Task1运行至t5时刻再度唤醒Task0;l 2.1.2 C/OS-中的任务描述一个任务通常是一个无限的循环 ,由于任务的执行是由操作系统内核调度的,因此任务是绝不会返回的,其返回参数必须定义成void。在C/OS-中,当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就会被抢占,高优先级任务会立刻得到CPU的控制权(在系统允许调度和任务切换的前提下)。C/OS-可以管理多达64个任务,但目前版本的C/OS-有两个任务已经被系统占用了(即空闲任务和统计任务)。必须给每个任务赋以不同的优先级,任务的优先级号就是任务编号(ID),优先级可以从0到OS_LOWEST_PR10-2。优先级号越低,任务的优先级越高。C/OS-总是运行进入就绪态的优先级最高的任务。2.2 操作系统配置操作系统配置的目的在于根据应用的需要,对操作系统的功能和规模进行设置,以便优化对系统存储空间的使用。配置的方法为修改uC_OS-II源代码目录中的OS_CFG.h文件:#define OS_MAX_EVENTS 10 /*最多可以有10个事件*/#define OS_MAX_FLAGS 5 /*最多可以有5个事件标志*/#define OS_MAX_MEM_PART 5 /*最多可以划分5个内存块*/#define OS_MAX_QS 2 /*最多可以使用2个队列*/#define OS_MAX_TASKS 3 /*最多可以创建3个任务*/#define OS_LOWEST_PRIO 14 /*任务优先级不可以大于14*/#define OS_TASK_IDLE_STK_SIZE 1024 /*空闲任务堆栈大小*/#define OS_TASK_STAT_EN 1 /*是否允许使用统计任务*/#define OS_TASK_STAT_STK_SIZE 1024 /*统计任务堆栈大小*/#define OS_FLAG_EN 0 /*是否允许使用事件标志功能*/#define OS_FLAG_WAIT_CLR_EN 1 /*是否允许等待清除事件标志*/#define OS_FLAG_ACCEPT_EN 1 /*是否允许使用OSFlagAccept()*/#define OS_FLAG_DEL_EN 1 /*是否允许使用OSFlagDel()*/#define OS_FLAG_QUERY_EN 1 /*是否允许使用OSFlagQuery()*/#define OS_MBOX_EN 0 /*是否允许使用邮箱功能*/#define OS_MBOX_ACCEPT_EN 1 /*是否允许使用 OSMboxAccept() */#define OS_MBOX_DEL_EN 1 /*是否允许使用 OSMboxDel()*/#define OS_MBOX_POST_EN 1 /*是否允许使用OSMboxPost()*/#define OS_MBOX_POST_OPT_EN 1 /*是否允许使用OSMboxPostOpt() */#define OS_MBOX_QUERY_EN 1 /*是否允许使用OSMboxQuery()*/#define OS_MEM_EN 0 /*是否允许使用内存管理的功能*/#define OS_MEM_QUERY_EN 1 /*是否允许使用OSMemQuery()*/#define OS_MUTEX_EN 0 /*是否允许使用互斥信号量的功能*/#define OS_MUTEX_ACCEPT_EN 1 /*是否允许使用OSMutexAccept()*/#define OS_MUTEX_DEL_EN 1 /*是否允许使用OSMutexDel()*/#define OS_MUTEX_QUERY_EN 1 /*是否允许使用OSMutexQuery()*/#define OS_Q_EN 0 /*是否允许使用队列功能*/#define OS_Q_ACCEPT_EN 1 /*是否允许使用OSQAccept()*/#define OS_Q_DEL_EN 1 /*是否允许使用OSQDel()*/#define OS_Q_FLUSH_EN 1 /*是否允许使用 OSQFlush()*/#define OS_Q_POST_EN 1 /*是否允许使用 OSQPost()*/#define OS_Q_POST_FRONT_EN 1 /*是否允许使用OSQPostFront()*/#define OS_Q_POST_OPT_EN 1 /*是否允许使用OSQPostOpt()*/#define OS_Q_QUERY_EN 1 /*是否允许使用OSQQuery()*/#define OS_SEM_EN 0 /*是否允许使用信号量功能*/#define OS_SEM_ACCEPT_EN 1 /*是否允许使用OSSemAccept()*/#define OS_SEM_DEL_EN 1 /*是否允许使用 OSSemDel() */#define OS_SEM_QUERY_EN 1 /*是否允许使用 OSSemQuery()*/#define OS_TASK_CHANGE_PRIO_EN 0 /*是否允许使用 OSTaskChangePrio()*/#define OS_TASK_CREATE_EN 1 /*是否允许使用OSTaskCreate()*/#define OS_TASK_CREATE_EXT_EN 1 /*是否允许使用OSTaskCreateExt()*/#define OS_TASK_DEL_EN 1 /*是否允许使用OSTaskDel()*/#define OS_TASK_SUSPEND_EN 1 /*是否允许使用OSTaskSuspend() and OSTaskResume()*/#define OS_TASK_QUERY_EN 1 /*是否允许使用OSTaskQuery()*/#define OS_TIME_DLY_HMSM_EN 0 /*是否允许使用OSTimeDlyHMSM()*/#define OS_TIME_DLY_RESUME_EN 1 /*是否允许使用OSTimeDlyResume()*/#define OS_TIME_GET_SET_EN 1 /*是否允许使用OSTimeGet() 和 OSTimeSet()*/#define OS_SCHED_LOCK_EN 1 /*是否允许使用OSSchedLock()和OSSchedUnlock()*/#define OS_TICKS_PER_SEC 200 /*设置每秒之内的时钟节拍数目*/2.3 源程序说明系统启动后,经历一系列的初始化过程,进入main()函数,这是我们编写实现应用程序的起点。首先需要在main()函数里创建起始任务TaskStart:OSTaskCreate(TaskStart, (void *)0, &TaskStartStkTASK_STK_SIZE - 1, 4); TaskStart任务TaskStart任务负责安装操作系统的时钟中断服务例程、初始化操作系统时钟,并创建所有的应用任务:ucos_x86_idt_set_handler(0x20,(void *)OSTickISR,0x8e00); /* Install uC/OS-IIs clock tick ISR */ucos_timer_init(); /*Timer 初始化*/ TaskStartCreateTasks(); /* Create all the application tasks */ OSTaskSuspend(OS_PRIO_SELF);具体负责应用任务创建的TaskStartCreateTasks函数代码如下,它创建了两个应用任务Task0和Task1:static void TaskStartCreateTasks (void) INT8U i;for (i = 0; i N_TASKS; i+) /* Create N_TASKS identical tasks */ TaskDatai = i; /* Each task will display its own letter */ OSTaskCreate(Task0, (void *)&TaskDatai, &TaskStkiTASK_STK_SIZE - 1, 5); OSTaskCreate(Task1, (void *)&TaskDatai, &TaskStk1TASK_STK_SIZE - 1, 6); TaskStart任务完成上述操作后将自己挂起,操作系统将调度当前优先级最高的应用任务Task0运行。应用任务应用任务Task0运行后将自己挂起,之后操作系统就会调度处于就绪状态的优先级最高的任务,具体代码如下:void Task0 (void *pdata)INT8U i;INT8U err;i=*(int *)pdata; for (;) /*此处为输出信息,显示任务运行的状态 */err=OSTaskSuspend(5); /* suspend itself */ 应用任务Task1运行后将Task0唤醒,使其进入到就绪队列中:void Task1 (void *pdata) INT8U i; INT8U err; i=*(int *)pdata;for (;) OSTimeDly(150); /*此处为输出信息,显示任务运行的状态 */OSTimeDly(150); err=OSTaskResume(5); /* resume task0 */ 3 运行及观察应用输出信息按照本实验手册第一部分所描述的方法建立应用项目并完成构建,当我们在LambdaTOOL调试器的控制下运行构建好的程序后,将看到在C/OS-内核的调度管理下,两个应用任务不断切换执行的情形:T1时刻的截图T2时刻的截图T3时刻的截图T4时刻的截图4 本实验中所用到的C/OS-II相关函数4.1 OSTaskCreate()建立一个新任务。任务的建立可以在多任务环境启动之前,也可以在正在运行的任务中建立。中断处理程序中不能建立任务。一个任务可以为无限循环的结构。函数原型:INT8U OSTaskCreate(void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio);参数说明:task是指向任务代码首地址的指针。Pdata指向一个数据结构,该结构用来在建立任务时向任务传递参数。返回值:OSTaskCreate()的返回值为下述之一:l OS_NO_ERR:函数调用成功。l OS_PRIO_EXIST:具有该优先级的任务已经存在。l OS_PRIO_INVALID:参数指定的优先级大于OS_LOWEST_PRIO。l OS_NO_MORE_TCB:系统中没有OS_TCB可以分配给任务了。4.2 OSTaskSuspend()无条件挂起一个任务。调用此函数的任务也可以传递参数OS_PRIO_SELF,挂起调用任务本身。当前任务挂起后,只有其他任务才能唤醒被挂起的任务。任务挂起后,系统会重新进行任务调度,运行下一个优先级最高的就绪任务。唤醒挂起任务需要调用函数OSTaskResume()。任务的挂起是可以叠加到其他操作上的。例如,任务被挂起时正在进行延时操作,那么任务的唤醒就需要两个条件:延时的结束以及其他任务的唤醒操作。又如,任务被挂起时正在等待信号量,当任务从信号量的等待对列中清除后也不能立即运行,而必须等到被唤醒后。函数原型:INT8U OSTaskSuspend ( INT8U prio);参数说明:prio为指定要获取挂起的任务优先级,也可以指定参数OS_PRIO_SELF,挂起任务本身。此时,下一个优先级最高的就绪任务将运行。返回值:OSTaskSuspend()的返回值为下述之一:l OS_NO_ERR:函数调用成功。l OS_TASK_ SUSPEND_IDLE:试图挂起C/OS-II中的空闲任务(Idle task)。此为非法操作。l OS_PRIO_INVALID:参数指定的优先级大于OS_LOWEST_PRIO或没有设定OS_PRIO_SELF的值。l OS_TASK_ SUSPEND _PRIO:要挂起的任务不存在。4.3 OSTaskResume()唤醒一个用OSTaskSuspend()函数挂起的任务。OSTaskResume()也是唯一能“解挂”挂起任务的函数。函数原型:NT8U OSTaskResume ( INT8U prio);参数说明:prio指定要唤醒任务的优先级。返回值:OSTaskResume ()的返回值为下述之一:l OS_NO_ERR:函数调用成功。l OS_TASK_RESUME_PRIO:要唤醒的任务不存在。l OS_TASK_NOT_SUSPENDED:要唤醒的任务不在挂起状态。l OS_PRIO_INVALID:参数指定的优先级大于或等于OS_LOWEST_PRIO。实验2 优先级反转1 实验目的掌握在基于优先级的可抢占嵌入式实时操作系统的应用中,出现优先级反转现象的原理。2 原理及程序结构2.1 实验设计2.1.1 优先级反转原理在本实验中,要体现嵌入式实时内核的优先级抢占调度的策略,并显现由于共享资源的互斥访问而出现的优先级反转现象。优先级反转发生在有多个任务需要使用共享资源的情况下,可能会出现高优先级任务被低优先级任务阻塞,并等待低优先级任务执行的现象。高优先级任务需要等待低优先级任务释放资源,而低优先级任务又正在等待中等优先级任务,这种现象就被称为优先级反转。两个任务都试图访问共享资源是出现优先级反转最通常的情况。为了保证一致性,这种访问应该是顺序进行的。如果高优先级任务首先访问共享资源,则会保持共享资源访问的合适的任务优先级顺序;但如果是低优先级任务首先获得共享资源的访问,然后高优先级任务请求对共享资源的访问,则高优先级任务被阻塞,直到低优先级任务完成对共享资源的访问。2.1.2 设计要点1)设计了3个应用任务TA0TA2,其优先级逐渐降低,任务TA0的优先级最高。2)除任务TA1外,其它应用任务都要使用同一种资源,该资源必须被互斥使用。为此,创建一个二值信号量mutex来模拟该资源。虽然C/OS-在创建信号量时可以选择采用防止优先级反转的策略,但在本实验中我们不使用这种策略。3)应用任务的执行情况如图2-1所示:t1t2t4t5t6t7t8t9t10t117优先级65t123100120 任务2: 任务1: 任务0: 图2-1注意:图中的栅格并不代表严格的时间刻度,而仅仅表现各个任务启动和执行的相对先后关系。2.1.3 系统的运行流程1) 系统初始化,之后进入main函数;2) 在main函数中,首先创建一个二值的信号量mutex;3) 在main函数中创建TaskStart任务,由TaskStart任务创建所有的应用任务(TA0、TA1、TA2)。优先级较高的任务TA0、TA1先延时若干个时钟节拍,以便低优先级任务TA2运行。4) t1时刻,任务TA2运行并首先申请到信号量mutex;5) t2时刻,任务TA1延时到期,任务TA1的优先级高于任务TA2的优先级,因此任务TA1立刻抢占TA2

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论