实验报告三:(1)设计 Task0、Task1 两个任务:任务 Task0 不断地挂起自己,再被任务 Task1 解挂,两个任务不断地切换执行,并输出两个任务在各个时刻的状态。Task0 的主要功能是显示 Task1 的状态,Task1 的主要功能是显示 Task0 的状态。整个应用的运行流程如图 1 所示,其描述如下:在 main 函数创建起始任务 TaskStart,其优先级为 0。TaskStart 任务主要完成创建 2 个应用任务 Task0、Task1,并挂起自己(不再被其它任务唤醒)。之后整个系统的运行流程如下:t1 时刻,Task0 开始执行,它运行到 t2 时刻挂起自己;t2 时刻,系统调度处于就绪状态的优先级最高任务 Task1 执行,它在 t3 时刻唤醒 Task0,后者由于优先级较高而抢占 CPU;Task0 执行到 t4 时刻又挂起自己,内核调度 Task1执行;Task1 运行至 t5 时刻再度唤醒 Task0; 注意:图中的栅格并不代表严格的时间刻度,而仅仅表现各任务启动和执行的相对先后关系。 (2)设计 MyTask、YouTask、KeyTask 三个任务:MyTask 任务输出 M;YouTask 任务输出 Y,并输出 MyTask 任务的状态;KeyTask 任务从键盘接收字符 Y 或 N,当接收 Y 时挂起 MyTask 任务,当接收 N 时恢复 MyTask 任务。 (3)设计 KeyTask 任务,当从键盘输入+号时动态创建任务,最多可以创建 10 个任务,这 10个任务都执行一个函数 MyTask,要求优先级是(PRIO_BASE+0,1,2,3,4,5,6,7,8,9),还要向不同的任务传递不同的参数(0,1,2,3,4,5,6,7,8,9)给 MyTask 函数,优先级为(PRIO_BASE+0,1,2,3,4,5,6,7,8,9)的任务分别输出数字(0,1,2,3,4,5,6,7,8,9)。当从键盘输入-号时动态的删除刚创建的一个任务,最多可删除 10 个任务。提示:多个任务可以执行一个函数。运行结果如下图所示。 ### 任务的创建、挂起与恢复 #### 实验背景 本实验主要目的是让学生通过实践操作,深入理解µC/OS-II操作系统中的任务管理机制,包括任务的创建、挂起与恢复等基本操作。通过实验,学生将能够掌握任务状态转换的过程以及如何使用µC/OS-II提供的系统调用来实现这些功能。 #### 实验目的 1. **理解任务管理的基本原理**:掌握任务在µC/OS-II中的不同状态及其转换过程。 2. **熟悉µC/OS-II的任务管理方法**:学会如何使用µC/OS-II提供的API来创建、启动、挂起、恢复任务。 3. **熟练使用任务管理的系统调用**:能够熟练使用诸如`OSTaskCreate()`、`OSTaskSuspend()`、`OSTaskResume()`等关键函数。 #### 实验内容详解 **一、设计Task0、Task1两个任务** - **Task0**的功能主要是不断挂起自身,并显示Task1的状态。 - **Task1**的功能主要是显示Task0的状态,并在特定时间唤醒Task0。 - 整个实验从main函数开始,首先创建了一个初始任务TaskStart,其优先级为0,随后创建了Task0和Task1,并挂起了TaskStart。 - **具体流程**: - `t1`时刻,Task0开始执行,到`t2`时刻挂起自己。 - `t2`时刻,Task1因优先级最高开始执行,在`t3`时刻唤醒Task0。 - `t4`时刻,Task0再次挂起自己,Task1继续执行。 - `t5`时刻,Task1再次唤醒Task0。 **二、设计MyTask、YouTask、KeyTask三个任务** - **MyTask**:持续输出字符"M"。 - **YouTask**:输出字符"Y",并显示MyTask的状态。 - **KeyTask**:从键盘读取输入,如果接收到字符"Y"则挂起MyTask,如果接收到字符"N"则恢复MyTask。 - 这部分的设计旨在展示如何通过外部输入控制任务状态的变化。 **三、设计KeyTask动态创建和删除任务** - **KeyTask**还负责根据用户从键盘输入的不同字符("+"或"-")来动态创建或删除任务。 - 当输入"+"时,创建一个执行函数`MyTask`的新任务,该任务的优先级从`PRIO_BASE`递增到`PRIO_BASE+9`,并传递不同的参数(0到9)给`MyTask`函数。 - 每个新创建的任务会根据其优先级输出对应的数字。 - 输入"-"时,则删除最近创建的任务,最多可以删除10个任务。 #### 实验代码解析 以实验内容中的第一个案例为例: ```c #include "includes.h" #define TASK_STK_SIZE 128 // 定义任务堆栈大小 OS_STK AppStk_MyTask[TASK_STK_SIZE]; // 定义MyTask的堆栈 OS_STK AppStk_YouTask[TASK_STK_SIZE]; // 定义YouTask的堆栈 // 任务函数 static void MyTask(void *p_arg); static void YouTask(void *p_arg); // 主函数 void main(int argc, char *argv[]) { OSInit(); // 初始化µC/OS-II OSTaskCreate(MyTask, NULL, (OS_STK *)&AppStk_MyTask[TASK_STK_SIZE - 1], 10); // 创建MyTask任务 OSTaskCreate(YouTask, NULL, (OS_STK *)&AppStk_YouTask[TASK_STK_SIZE - 1], 9); // 创建YouTask任务 OSStart(); // 启动多任务管理 } // MyTask任务函数 void MyTask(void *p_arg) { p_arg = p_arg; OSTimeSet(0); // 设置定时器 while (TRUE) { while (OSTime < 50); // 等待50个时间单位 OSTaskSuspend(OS_PRIO_SELF); // 挂起自身 OS_Printf("YouTask=%d\n", OSTCBPrioTbl[9]->OSTCBStat); // 显示YouTask状态 OSTimeDlyHMSM(0, 0, 1, 0); // 延迟1秒 } } // YouTask任务函数 void YouTask(void *p_arg) { p_arg = p_arg; OSTimeSet(0); // 设置定时器 while (TRUE) { while (OSTime < 50); // 等待50个时间单位 OS_Printf("MyTask=%d\n", OSTCBPrioTbl[10]->OSTCBStat); // 显示MyTask状态 OSTaskResume(10); // 恢复MyTask OSTimeDlyHMSM(0, 0, 2, 0); // 延迟2秒 } } ``` 这段代码展示了如何创建两个任务(MyTask和YouTask),并通过循环挂起和恢复任务来实现状态显示的功能。同时,还展示了如何使用定时器来控制任务执行的时间间隔。 通过以上实验内容和代码的解析,我们可以看到µC/OS-II中的任务管理机制是如何运作的,以及如何利用系统提供的API来灵活地控制任务的状态变化。这对于理解和应用嵌入式实时操作系统具有重要意义。
剩余7页未读,继续阅读
- 粉丝: 1
- 资源: 11
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助