任务挂起和恢复

本文详细介绍了任务挂起和恢复的过程,包括挂起流程、恢复流程以及一个实际的应用场景,展示了如何通过任务调度来控制任务的执行顺序。

2、任务挂起和恢复

(1)OSTaskSuspend流程图

(2)OSTaskResume流程图

(3)测试 

/* App1Task */

void App1Task(void *p_arg)

{

    p_arg = p_arg;

 

    while(1)

    {

       printf("Hello,I amTask1!\n");

 

       OSTimeDlyHMSM(0, 0, 1, 0);                             /* 任务调度*/

}

/* App2Task */

void App2Task(void *p_arg)

{

    p_arg = p_arg;

 

    while(1)

    {

       printf("Task2 isrunning!\n");

       if(task2_time == 2) 

       {

           OSTaskSuspend(App1Task_Prio);   /* Task2运行2次挂起Task1任务,会进行任务调度*/

       }

       else if(task2_time== 10)                                    

       {

           OSTaskResume(App1Task_Prio);    /* Task2运行10次后恢复Task1任务运行,会进行任务调度*/

       }

       task2_time++;                         /* 计数值加*/                                      

 

       OSTimeDlyHMSM(0, 0, 2, 0);         /* 任务调度*/

}

运行结果

实验报告三:(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 个任务。提示:多个任务可以执行一个函数。运行结果如下图所示。
### FreeRTOS 中任务挂起恢复的使用方法 #### 1. 任务挂起 (vTaskSuspend) `vTaskSuspend()` 函数用于挂起指定的任务。一旦某个任务挂起,它将不会进入就绪队列,也不会再被调度器选中运行,直到其被显式恢复为止。 调用 `vTaskSuspend(NULL)` 将会挂起当前正在运行的任务[^1]。 ```c void vTaskSuspend( TaskHandle_t xTaskToSuspend ); ``` - 参数说明: - `xTaskToSuspend`: 要挂起任务句柄。如果设置为 `NULL`,则表示挂起当前任务。 #### 示例代码:挂起任务 ```c // 假设已经创建了一个名为 TaskB 的任务,并获取了它的句柄 xTaskBHandle vTaskSuspend(xTaskBHandle); // 挂起 TaskB ``` --- #### 2. 任务恢复 (vTaskResume xTaskResumeFromISR) `vTaskResume()` 是用来恢复之前通过 `vTaskSuspend()` 挂起任务。当一个任务恢复后,它会被重新加入到就绪队列中并参与调度。 对于中断服务程序中的任务恢复操作,则应使用 `xTaskResumeFromISR()` 来替代普通的 `vTaskResume()`,因为后者可能引发上下文切换的需求,在 ISR 中需要特别处理这种需求[^4]。 ##### **普通场景下的任务恢复** ```c void vTaskResume( TaskHandle_t xTaskToResume ); ``` - 参数说明: - `xTaskToResume`: 需要恢复任务句柄。 ###### 示例代码:恢复任务 ```c // 继续上面的例子,假设我们希望再次激活 TaskB vTaskResume(xTaskBHandle); ``` ##### **中断服务程序中的任务恢复** ```c BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ); ``` - 返回值解释: - 如果返回值为 `pdTRUE`,意味着在退出中断时应该触发一次上下文切换。 ###### 示例代码:从中断恢复任务 ```c BaseType_t xHigherPriorityTaskWoken = pdFALSE; xTaskResumeFromISR(xTaskBHandle); if (xHigherPriorityTaskWoken != pdFALSE) { portYIELD_FROM_ISR(); // 请求立即进行上下文切换 } ``` --- #### 3. 使用注意事项 - 当前任务可以通过传递 `NULL` 到 `vTaskSuspend()` 或者 `vTaskResume()` 自己挂起恢复自己。 - 不建议频繁地挂起恢复高优先级任务,这可能会破坏系统的实时性能。 - 在多核系统或者复杂的嵌入式环境中,确保同步机制正确无误以避免竞态条件的发生。 --- #### 4. 结合定时功能延时恢复任务 除了直接调用上述 API 外,也可以利用 FreeRTOS 提供的时间管理接口来实现延迟一定时间后再自动唤醒任务的功能。例如: - `vTaskDelay()` - `vTaskDelayUntil()` 这些函数允许开发者定义精确的时间间隔让任务保持阻塞状态直至超时期满才继续执行[^2]。 --- ### 总结 以上介绍了如何在 FreeRTOS 下管理控制任务的状态转换——包括暂停以及重启它们的方法论及其典型应用场景。合理运用这些工具可以帮助构建更加高效稳定的应用框架结构。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值