uC_OS-II内核实验指导书.doc_第1页
uC_OS-II内核实验指导书.doc_第2页
uC_OS-II内核实验指导书.doc_第3页
uC_OS-II内核实验指导书.doc_第4页
uC_OS-II内核实验指导书.doc_第5页
已阅读5页,还剩67页未读 继续免费阅读

下载本文档

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

文档简介

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 消息队列实验9第二部分 C/OS-II实验10实验1 任务的基本管理101 实验目的102 实验原理及程序结构102.1 实验设计102.2 操作系统配置112.3 源程序说明133 运行及观察应用输出信息154 本实验中所用到的C/OS-II相关函数174.1 OSTaskCreate()174.2 OSTaskSuspend()174.3 OSTaskResume()18实验2 优先级反转191 实验目的192 原理及程序结构192.1 实验设计192.2 操作系统配置212.3 源程序说明223 运行及观察应用输出信息254 本实验中所用到的C/OS-II相关函数254.1 OSSemCreate()254.2 OSSemPend()264.3 OSemPost()264.4 OSTimeDly()27实验3 优先级继承281 实验目的282 原理及程序结构282.1实验设计282.2 操作系统配置313 运行及观察应用输出信息324 本实验中所用到的C/OS-II相关函数334.1 OSMutexCreate()334.2 OSMutexPend()334.3 OSMutexPost()345 应用调试过程35实验4 信号量:哲学家就餐问题的实现371 实验目的372 原理及程序结构372.1 实验设计372.2 操作系统配置383运行及观察应用输出信息394 本实验中所用到的C/OS-II相关函数41实验5 C/OS-II的内存管理421 实验目的422 原理及程序结构422.1实验设计422.2 操作系统配置483 本实验中所用到的C/OS-II相关函数493.1 OSMemCreate()493.2 OSMemGet()503.3 OSMemPut()503.4 OSMemQuery()51实验6 时钟中断521 实验目的522 原理及程序结构522.1 实验设计522.2 操作系统配置543运行及观察应用输出信息564 本实验中所用到的C/OS-II相关函数57实验7 消息队列581 实验目的582 原理及程序结构582.1 实验设计582.2 源程序说明582.3 操作系统配置633 运行及观察应用输出信息644 本实验中所用到的C/OS-II相关函数684.1 OSQCreate()684.2 OSQPend()684.3 OSQPostFront()694.4 OSQPost()694.5 OSQFlush ()704.6 OSQQuery()704.7 OSQDel()714.8 OSTimeDlyHMSM()71第一部分 实验系统简介及入门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中的消息队列机制。读者可以了解一个应用中的任务是如何进行通信的,如何能使它们相互协调工作。第二部分 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执行,任务TA2由执行态转为就绪态;6) t3时刻,任务TA0延时到期,任务TA0的优先级高于任务TA1的优先级,所以任务TA0立刻抢占执行,任务TA1由执行态转为就绪态,任务TA0申请二值信号量mutex被阻赛;7) t4时刻,任务TA1由就绪态转回为执行态;此时TA0在等待TA2保持的mutex , 而TA2又因为优先级低于TA1被阻塞。如果TA1一直执行而TA2没有机会被调度的话,那么TA2将一直等到TA1执行完后才能执行,而TA0更要等到TA2释放它所占有的信号量资源后才能执行,这样就出现了优先级高的TA0任务等待优先级低的TA1任务的现象;8) t5时刻,任务TA1挂起自己,而TA0又因为申请二值信号量mutex而处于阻塞状态,所以任务TA2由就绪态转为执行态,任务TA2释放信号量mutex;9) t6时刻,TA0获得信号量并立刻抢占执行,任务TA2由执行态转为就绪态;10) t7时刻,任务TA0将自己延时一段时间,而TA1仍然处于挂起状态,TA2是当前最高优先级的就绪任务,它又转为执行状态,任务TA2因申请二值信号量mutex而阻塞;11) t8时刻,任务TA1延时到期转为执行态,任务TA1又因等待一个事件而阻塞;12) t9时刻,任务TA0延时到,释放二值信号量mutex,mutex被TA2得到后,内核自动切换任务;13) t10时刻,在就绪队列中,TA0优先级最高,TA0执行,又因为任务TA0等待一事件而阻塞;14) t11时刻,任务TA1延时到期,立刻抢占执行,又由于任务TA1等待一事件而阻塞;15) t12时刻,任务TA2执行,保持信号量mutex;以后系统再次出现优先级反转现象;16) 系统如此周而复始地运行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 9 /*最多可以创建9个任务*/#define OS_LOWEST_PRIO 24 /*任务优先级不可以大于24*/#define OS_TASK_IDLE_STK_SIZE 1024 /*空闲任务堆栈大小*/#define OS_TASK_STAT_EN 1 /*是否允许使用统计任务*/#define OS_TASK_STAT_STK_SIZE 1024 /*统计任务堆栈大小*/#define OS_FLAG_EN 1 /*是否允许使用事件标志功能*/#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_MEM_EN 1 /*是否允许使用内存管理的功能*/#define OS_MEM_QUERY_EN 1 /*是否允许使用OSMemQuery()*/#define OS_MUTEX_EN 1 /*是否允许使用互斥信号量的功能*/#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_SEM_EN 1 /*是否允许使用信号量功能*/#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 1 /*是否允许使用 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 1 /*是否允许使用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()函数中创建一个二值信号量:mutex=OSSemCreate(1);然后,在main()函数中创建TaskStart任务。TaskStart任务在TaskStart任务中创建并启动所有的应用任务TA0, TA1,TA2。static void TaskStartCreateTasks (void) INT8U i;for (i = 0; i N_TASKS; i+) /* Create N_TASKS identical tasks */TaskDatai = i; /* Each task will pass its own id */OSTaskCreate(Task0, (void *)&TaskData0, &TaskStk0TASK_STK_SIZE - 1, 5);OSTaskCreate(Task1, (void *)&TaskData1, &TaskStk1TASK_STK_SIZE - 1, 6);O

温馨提示

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

评论

0/150

提交评论