收藏 分享(赏)

uC_OS-II内核实验指导书.doc

上传人:精品资料 文档编号:11220523 上传时间:2020-02-20 格式:DOC 页数:72 大小:1.24MB
下载 相关 举报
uC_OS-II内核实验指导书.doc_第1页
第1页 / 共72页
uC_OS-II内核实验指导书.doc_第2页
第2页 / 共72页
uC_OS-II内核实验指导书.doc_第3页
第3页 / 共72页
uC_OS-II内核实验指导书.doc_第4页
第4页 / 共72页
uC_OS-II内核实验指导书.doc_第5页
第5页 / 共72页
点击查看更多>>
资源描述

1、1C_OS-II 实验指导书电子科技大学嵌入式软件工程中心2目录第一部分 实验系统简介及入门 .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 任务的基

2、本管理 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 OSSe

3、mCreate() .254.2 OSSemPend() 2634.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

4、.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 运行及观察应用输出信息

5、 564 本实验中所用到的 C/OS-II 相关函数 .57实验 7 消息队列 581 实验目的 5842 原理及程序结构 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()715第一部分 实验系统简介及入

6、门1 实验系统的目的通过此实验系统,读者可以了解嵌入式实时操作系统 C_OS-II 的内核机制和运行原理。本实验系统展示了 COS-II 各方面的管理功能,包括信号量、队列、内存、时钟等。在各个实验中具体介绍了 COS-II 的相关函数。读者在做实验的同时能够结合理论知识加以分析,了解各个函数的作用和嵌入式应用程序的设计方法,最终对整个 Cos 和嵌入式操作系统的应用有较为清楚的认识。2 实验系统的构成本实验系统由以下各部分组成:1 COS-II 嵌入式实时操作系统。这个操作系统是开放源代码的; 2 LambdaTOOL。一个开发嵌入式软件的集成开发环境;3 BSP。针对特定嵌入式硬件平台的板

7、级支持包,提供板级初始化代码和一些基本的驱动程序;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 全部以源代码的方式提

8、供给读者,大约有 5500 行。CPU 相关的部分使用的是针对Intel80x86 微处理器的代码。虽然 C/OS-II 可以在 PC 机上开发和测试,但是可以很容易地移植到不同架构的嵌入式微处理器上。63.2 C/OS-II 的特点1、源代码:C/OS-II 全部以源代码的方式提供给使用者(约 5500 行) 。该源码清晰易读,结构协调,且注解详尽,组织有序;2、可移植(portable): C/OS-II 的源代码绝大部分是用移植性很强的 ANSI C 写的,与微处理器硬件相关的部分是用汇编语言写的。C/OS-II 可以移植到许许多多不同的微处理器上,条件是:该微处理器具有堆栈指针,具有

9、CPU 内部寄存器入栈、出栈指令,使用的 C 编译器必须支持内嵌汇编,或者该 C 语言可扩展和可链接汇编模块,使得关中断和开中断能在 C 语言程序中实现;3、可固化(ROMable): C/OS-II 是为嵌入式应用而设计的,意味着只要具备合适的系列软件工具(C 编译、汇编、链接以及下载 /固化)就可以将 C/OS-II 嵌入到产品中作为产品的一部分;4、可裁减(scalable): 可以只使用 C/OS-II 中应用程序需要的系统服务。可裁减性是靠条件编译实现的,只需要在用户的应用程序中定义那些 C/OS-II 中的功能应用程序需要的部分就可以了;5、可抢占性(preemptive): C/

10、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、任务栈: 每个任务都有自己单独的栈。

11、C/OS-II 允许每个任务有不同的栈空间,以便降低应用程序对 RAM 的需求;9、系统服务: C/OS-II 提供许多系统服务,比如信号量、互斥信号量、事件标志、消息邮箱、消息队列、时间管理等等;10、中断管理: 中断可以使正在执行的任务暂时挂起。如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可以达 255 层;11、稳定性和可靠性: C/OS-II 的每一种功能、每一个函数以及每一行代码都经过了考验和测试,具有足够的安全性与稳定性,能用于与人性命攸关、安全性条件极为苛刻的系统中。73.3 C/OS-II 主要源代码文件介绍C/OS-II 的源代

12、码具体包括以下的文件: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_CFGH: C/OS-I

13、I 的配置文件,定义使用 C/OS-II 中的哪些功能。4 LambdaTOOL 集成开发环境简介LambdaTOOL 是一个通用、统一、开放的新一代 32 位嵌入式软件集成开发环境,支持多种嵌入式操作系统和 32 位嵌入式处理器,具备先进的新一代交叉开发环境和系统配置工具。本实验系统中提供的 LambdaTOOL 是其面向教学的免费版本,具备支持嵌入式软件仿真开发的完整功能,具体由下列内容组成: 编辑环境 系统配置 编译环境 目标机管理 调试环境8在本实验系统中,采用 LambdaTOOL 提供的一个 PC 虚拟机作为实验项目运行的仿真目标平台。在 LambdaTOOL 上项目的开发流程如下

14、图所示:创建项目编辑源码配置项目构建项目调试应用固化应用有关开发流程的细节请看后面的“预备实验:嵌入式开发环境的建立” 。5 C/OS-II 实验内容简介5.1 任务管理实验此实验的目的是让读者理解嵌入式操作系统中任务管理的基本原理,了解任务的各个基本状态及其变迁过程;掌握 C/OS-II 中任务管理的基本方法(创建、启动、挂起和解挂任务) ;熟练使用 C/OS-II 任务管理的基本系统调用。5.2 优先级反转实验通过此实验读者可以了解在基于抢占式嵌入式实时操作系统并有共享资源的应用中,出现优先级反转现象的原理。优先级反转发生在有多个任务共享资源的情况下,高优先级任务被低优先级任务阻塞,并等待

15、低优先级任务执行的现象。95.3 优先级继承实验通过此实验读者可以了解嵌入式实时操作系统 C/OS-II 解决优先级反转的策略优先级继承的原理,以此解决低优先级任务在占用了共享资源的情况下,被高优先级任务抢占了 CPU 使用权而导致的优先级反转的问题。5.4 哲学家就餐实验通过经典的哲学家就餐应用,读者可以了解如何利用嵌入式实时操作系统 C/OS-II 的信号量机制来对共享资源进行互斥访问。5.5 内存管理实验通过此实验读者可以了解嵌入式实时操作系统 C/OS-II 中的内存管理的原理,包括对内存的分配和回收。5.6 时钟中断实验通过此实验读者可以了解嵌入式实时操作系统 C/OS-II 中,时

16、钟中断的使用情况。5.7 消息队列实验通过此实验读者可以了解嵌入式实时操作系统 C/OS-II 中的消息队列机制。读者可以了解一个应用中的任务是如何进行通信的,如何能使它们相互协调工作。10第二部分 C/OS-II 实验实验 1 任务的基本管理1 实验目的 理解任务管理的基本原理,了解任务的各个基本状态及其变迁过程; 掌握 C/OS-II 中任务管理的基本方法(创建、启动、挂起、解挂任务) ; 熟练使用 C/OS-II 任务管理的基本系统调用。2 实验原理及程序结构2.1 实验设计为了展现任务的各种基本状态及其变迁过程,本实验设计了 Task0、Task1 两个任务:任务Task0 不断地挂起

17、自己,再被任务 Task1 解挂,两个任务不断地切换执行。通过本实验,读者可以清晰地了解到任务在各个时刻的状态以及状态变迁的原因。起始任务Task0Task1Task0 Task0Task1 Task1t0 t1 t2 t3 t4 t5 t6 t7 t8图 1-1图 1注意:图中的栅格并不代表严格的时间刻度,而仅仅表现各任务启动和执行的相对先后关系。112.1.1 运行流程整个应用的运行流程如图 1 所示,其描述如下:(1)系统经历一系列的初始化过程后进入 boot_card()函数,在其中调用 ucBsp_init()进行板级初始化后,调用 main()函数;(2)main ()函数调用 O

18、SInit()函数对 C/OS-II 内核进行初始化,调用 OSTaskCreate 创建起始任务 TaskStart;(3)main ()函数调用函数 OSStart()启动 C/OS-II 内核的运行,开始多任务的调度,执行当前优先级最高的就绪任务 TaskStart;(4)TaskStart 完成如下工作:a、安装时钟中断并初始化时钟,创建 2 个应用任务;b、挂起自己(不再被其它任务唤醒 ),系统切换到当前优先级最高的就绪任务 Task0。之后整个系统的运行流程如下: t1 时刻,Task0 开始执行,它运行到 t2 时刻挂起自己; t2 时刻,系统调度处于就绪状态的优先级最高任务 T

19、ask1 执行,它在 t3 时刻唤醒 Task0,后者由于优先级较高而抢占 CPU; Task0 执行到 t4 时刻又挂起自己,内核调度 Task1 执行; Task1 运行至 t5 时刻再度唤醒 Task0; 2.1.2 C/OS-中的任务描述一个任务通常是一个无限的循环 ,由于任务的执行是由操作系统内核调度的,因此任务是绝不会返回的,其返回参数必须定义成 void。在 C/OS-中,当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的 CPU 使用权就会被抢占,高优先级任务会立刻得到 CPU 的控制权(在系统允许调度和任务切换的前提下) 。C/OS- 可以管理多达 64 个任

20、务,但目前版本的C/OS-有两个任务已经被系统占用了(即空闲任务和统计任务) 。必须给每个任务赋以不同的优先级,任务的优先级号就是任务编号(ID) ,优先级可以从 0 到 OS_LOWEST_PR10-2。优先级号越低,任务的优先级越高。C/OS- 总是运行进入就绪态的优先级最高的任务。2.2 操作系统配置操作系统配置的目的在于根据应用的需要,对操作系统的功能和规模进行设置,以便优化对系12统存储空间的使用。配置的方法为修改 uC_OS-II 源代码目录中的 OS_CFG.h 文件:#define OS_MAX_EVENTS 10 /*最多可以有 10 个事件*/#define OS_MAX_

21、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_SI

22、ZE 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

23、_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

24、_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 /*是否允许使用 OS

25、QAccept()*/#define OS_Q_DEL_EN 1 /*是否允许使用 OSQDel()*/13#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 O

26、S_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_TA

27、SK_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_RESUM

28、E_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

29、:OSTaskCreate(TaskStart, (void *)0, TaskStart 任务TaskStart 任务负责安装操作系统的时钟中断服务例程、初始化操作系统时钟,并创建所有的应用任务:ucos_x86_idt_set_handler(0x20,(void *)OSTickISR,0x8e00); /* Install uC/OS-IIs clock tick ISR */ucos_timer_init(); /*Timer 初始化*/14TaskStartCreateTasks(); /* Create all the application tasks */OSTaskSusp

30、end(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 *)OSTaskCreate(Task1, (

31、void *)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

32、 *pdata) INT8U i;15INT8U err;i=*(int *)pdata;for (;) OSTimeDly(150); /*此处为输出信息,显示任务运行的状态 */OSTimeDly(150);err=OSTaskResume(5); /* resume task0 */3 运行及观察应用输出信息按照本实验手册第一部分所描述的方法建立应用项目并完成构建,当我们在 LambdaTOOL 调试器的控制下运行构建好的程序后,将看到在 C/OS-内核的调度管理下,两个应用任务不断切换执行的情形:T1 时刻的截图16T2 时刻的截图T3 时刻的截图17T4 时刻的截图4 本实验中所用到

33、的 C/OS-II 相关函数4.1 OSTaskCreate()建立一个新任务。任务的建立可以在多任务环境启动之前,也可以在正在运行的任务中建立。中断处理程序中不能建立任务。一个任务可以为无限循环的结构。函数原型:INT8U OSTaskCreate(void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio);参数说明:task 是指向任务代码首地址的指针。Pdata 指向一个数据结构,该结构用来在建立任务时向任务传递参数。返回值:OSTaskCreate()的返回值为下述之一: OS_NO_ERR:函数调用成功。 OS_PRI

34、O_EXIST:具有该优先级的任务已经存在。 OS_PRIO_INVALID:参数指定的优先级大于 OS_LOWEST_PRIO。 OS_NO_MORE_TCB:系统中没有 OS_TCB 可以分配给任务了。4.2 OSTaskSuspend()无条件挂起一个任务。调用此函数的任务也可以传递参数 OS_PRIO_SELF,挂起调用任务本18身。当前任务挂起后,只有其他任务才能唤醒被挂起的任务。任务挂起后,系统会重新进行任务调度,运行下一个优先级最高的就绪任务。唤醒挂起任务需要调用函数 OSTaskResume() 。任务的挂起是可以叠加到其他操作上的。例如,任务被挂起时正在进行延时操作,那么任务

35、的唤醒就需要两个条件:延时的结束以及其他任务的唤醒操作。又如,任务被挂起时正在等待信号量,当任务从信号量的等待对列中清除后也不能立即运行,而必须等到被唤醒后。函数原型:INT8U OSTaskSuspend ( INT8U prio);参数说明:prio 为指定要获取挂起的任务优先级,也可以指定参数 OS_PRIO_SELF,挂起任务本身。此时,下一个优先级最高的就绪任务将运行。返回值:OSTaskSuspend()的返回值为下述之一: OS_NO_ERR:函数调用成功。 OS_TASK_ SUSPEND_IDLE:试图挂起 C/OS-II 中的空闲任务(Idle task) 。此为非法操作。

36、 OS_PRIO_INVALID:参数指定的优先级大于 OS_LOWEST_PRIO 或没有设定 OS_PRIO_SELF的值。 OS_TASK_ SUSPEND _PRIO:要挂起的任务不存在。4.3 OSTaskResume()唤醒一个用 OSTaskSuspend()函数挂起的任务。OSTaskResume()也是唯一能“解挂” 挂起任务的函数。函数原型:NT8U OSTaskResume ( INT8U prio);参数说明:prio 指定要唤醒任务的优先级。返回值:OSTaskResume ()的返回值为下述之一: OS_NO_ERR:函数调用成功。 OS_TASK_RESUME_P

37、RIO:要唤醒的任务不存在。 OS_TASK_NOT_SUSPENDED:要唤醒的任务不在挂起状态。 OS_PRIO_INVALID:参数指定的优先级大于或等于 OS_LOWEST_PRIO。19实验 2 优先级反转1 实验目的掌握在基于优先级的可抢占嵌入式实时操作系统的应用中,出现优先级反转现象的原理。2 原理及程序结构2.1 实验设计2.1.1 优先级反转原理在本实验中,要体现嵌入式实时内核的优先级抢占调度的策略,并显现由于共享资源的互斥访问而出现的优先级反转现象。优先级反转发生在有多个任务需要使用共享资源的情况下,可能会出现高优先级任务被低优先级任务阻塞,并等待低优先级任务执行的现象。高

38、优先级任务需要等待低优先级任务释放资源,而低优先级任务又正在等待中等优先级任务,这种现象就被称为优先级反转。两个任务都试图访问共享资源是出现优先级反转最通常的情况。为了保证一致性,这种访问应该是顺序进行的。如果高优先级任务首先访问共享资源,则会保持共享资源访问的合适的任务优先级顺序;但如果是低优先级任务首先获得共享资源的访问,然后高优先级任务请求对共享资源的访问,则高优先级任务被阻塞,直到低优先级任务完成对共享资源的访问。2.1.2 设计要点1)设计了 3 个应用任务 TA0TA2 ,其优先级逐渐降低,任务 TA0 的优先级最高。2)除任务 TA1 外,其它应用任务都要使用同一种资源,该资源必

39、须被互斥使用。为此,创建一个二值信号量 mutex 来模拟该资源。虽然 C/OS-在创建信号量时可以选择采用防止优先级反转的策略,但在本实验中我们不使用这种策略。3)应用任务的执行情况如图 2-1 所示:20t1 t2 t4 t5 t6 t7 t8 t9 t10 t117优先级65t12 t13101022212t310 0任务 2: 任务 1: 任务 0: 图 2-1注意:图中的栅格并不代表严格的时间刻度,而仅仅表现各个任务启动和执行的相对先后关系。2.1.3 系统的运行流程1) 系统初始化,之后进入 main 函数;2) 在 main 函数中,首先创建一个二值的信号量 mutex;3) 在

40、 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 由执行态转为就

41、绪态,任务 TA0 申请二值信号量 mutex 被阻赛;7) t4 时刻,任务 TA1 由就绪态转回为执行态;此时 TA0 在等待 TA2 保持的 mutex , 而 TA2又因为优先级低于 TA1 被阻塞。 如果 TA1 一直执行而 TA2 没有机会被调度的话,那么TA2 将一直等到 TA1 执行完后才能执行,而 TA0 更要等到 TA2 释放它所占有的信号量资源后才能执行,这样就出现了优先级高的 TA0 任务等待优先级低的 TA1 任务的现象;8) t5 时刻,任务 TA1 挂起自己,而 TA0 又因为申请二值信号量 mutex 而处于阻塞状态,所2 1 021以任务 TA2 由就绪态转为

42、执行态,任务 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

43、执行,又因为任务 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

44、_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

45、_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()*/2

46、2#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 /*是否允许使用

47、 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 /*是

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报