当前位置: 首页 > news >正文

Freertos系统(任务挂起和恢复)

 如果不想看的可以直接使用git把我的代码下载出来,里面工程挺全的,后期会慢慢的补注释之类的

码云地址:stm32学习笔记: stm32学习笔记源码

如果不会使用git快速下载可以选择直接下载压缩包或者去看看git的使用

Git入门教程-CSDN博客

目录


一 函数讲解

函数说明:本章3个函数,挂起、恢复、在中断中恢复任务

1.1 挂起函数

void vTaskSuspend(TaskHandle_t xTaskToSuspend)

需要开启宏:INCLUDE_vTaskSuspend  配置为 1

之后使用方法就是传入句柄,删除自己就传入NULL

1.2 恢复函数

vTaskResume()

传入句柄即可:需要打开宏:INCLUDE_vTaskSuspend

1.3 恢复函数(中断中恢复)

xTaskResumeFromISR()

开启宏:INCLUDE_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 必须定义为 1

二 任务测试

2.1 挂起函数

我们先测试一下使用函数挂起任务2:PS框架在创建任务中有可以去看看

void KEY1_IRQHandler(void)
{//确保是否产生了EXTI Line中断if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) {taskENTER_CRITICAL();vTaskSuspend(task2_handler);taskEXIT_CRITICAL();//清除中断标志位EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);     }  
}void task1( void * pvParameters )
{while (1){printf("task 1\r\n");vTaskDelay(pdMS_TO_TICKS(500));}
}void task2( void * pvParameters )
{while (1){printf("task 2\r\n");				vTaskDelay(pdMS_TO_TICKS(500));}
}

按下按键后,task2被挂起了。测试成功

2.2 任务恢复函数

2.2.1 普通恢复函数

普通任务恢复函数,这里我直接拿vTaskResume()来在中断中给大家测试删除:这里应该是会引起程序崩溃的,最后给大家说原因

void KEY1_IRQHandler(void)
{//确保是否产生了EXTI Line中断if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) {taskENTER_CRITICAL();vTaskSuspend(task2_handler);taskEXIT_CRITICAL();//清除中断标志位EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);     }  
}void KEY2_IRQHandler(void)
{//确保是否产生了EXTI Line中断if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) {vTaskResume(task2_handler);//清除中断标志位EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);     }  
}

结果

= =没有被卡死,应该是我手动中断太慢,或者一直amr架构保护之类的。但是切记不能把这个释放函数用在中断里面

2.2.2 恢复函数(中断中恢复)

任务恢复函数:xTaskResumeFromISR() 在中断里面使用这个函数靠谱一点

void KEY2_IRQHandler(void)
{// 声明变量记录是否需要触发调度BaseType_t xHigherPriorityTaskWoken = pdFALSE;// 确保是否产生了EXTI Line中断if(EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) {// 调用中断版恢复函数,并获取返回值if (xTaskResumeFromISR(task2_handler) == pdTRUE) {// 若返回pdTRUE,说明被恢复的任务优先级高于当前运行任务xHigherPriorityTaskWoken = pdTRUE;}portYIELD_FROM_ISR(xHigherPriorityTaskWoken);// 清除中断标志位EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);}  
}

关键补充说明

  1. xHigherPriorityTaskWoken 变量:
    用于标记 “被恢复的任务优先级是否高于当前正在运行的任务”。当 xTaskResumeFromISR() 返回 pdTRUE 时,说明被恢复的 task2 优先级更高,需要立即调度它运行。

  2. portYIELD_FROM_ISR() 调度触发:
    这是中断专用的调度触发函数,作用是在中断退出前完成任务切换。如果缺少这一步,即使 task2 优先级更高,也需要等待当前任务时间片耗尽才能运行,可能导致实时性下降。

  3. 句柄有效性检查:
    为了更健壮,可增加句柄非空判断,避免恢复无效任务:

  4. 这样可以确保被恢复的任务在优先级更高时能立即执行,同时避免内核数据结构冲突,保证系统稳定性。

我这里按下按键1后,task2被挂起了,之后按下按键2,task2正常恢复了

2.3 两个函数的区别总结

  • 任务上下文:内核会自动处理数据结构的保护(如通过调度器锁),因此 vTaskResume() 无需额外操作即可安全修改任务状态。
  • 中断上下文:中断优先级高于所有任务,直接修改内核数据可能导致冲突(如任务列表正在被修改时被中断打断)。xTaskResumeFromISR() 内部通过特殊的原子操作实现安全访问,且需要手动触发调度(portYIELD_FROM_ISR()),避免中断嵌套导致的状态混乱。

2.4 错误使用的后果

  • 中断中调用 vTaskResume():会导致内核数据结构损坏,可能引发系统崩溃(HardFault)或任务调度异常。
  • 任务中调用 xTaskResumeFromISR():虽然不会报错,但属于冗余操作(返回值处理和手动调度逻辑多余),不符合编程规范。

三 总结

  • vTaskResume():任务中使用,简单恢复被挂起任务,自动处理调度。
  • xTaskResumeFromISR():中断中使用,安全恢复任务,需手动触发调度,返回值指示是否需要切换任务。

http://www.dtcms.com/a/389593.html

相关文章:

  • Git更新仓库时,忽略指定文件
  • 告别“瞎练”!数据闭环正成机器人智能进化核心引擎!
  • 基于MATLAB的无人机遥感数据预处理与农林植被性状估算
  • MATLAB基于AHP-模糊综合评价法的工程实践能力评价
  • 特征选择+优化算法+GBDT+SHAP分析!ReliefF-CPO-GBDT分类预测结合SHAP可解释分析MATLAB
  • 设计模式-外观模式详解
  • 《FastAPI零基础入门与进阶实战》第19篇:消息管理
  • 类和对象(下):static成员、友元类、内部类、匿名对象、优化——对象拷贝时的编译器优化
  • 虚拟线程(Virtual Thread)
  • 1688 店铺全商品接口技术全解:从页面解析到分页采集的完整实现方案
  • 日志轮转策略针对香港VPS存储空间的设置标准
  • 线性分组码及其相关概念
  • JWT的工作流程
  • Java 25 新特性 更简洁、更高效、更现代
  • 探讨前端与后端的安全策略:保护用户数据的关键措施
  • 如何使用DeepSeek等AI工具来帮助自己的工作
  • 灵途科技亮相CIOE2025 | 光电感知赋能具身智能升级
  • 我的云端影院:LibreTV+cpolar的异地观影记
  • NW748NW765美光固态闪存NW775NW781
  • 软考中级习题与解答——第八章_计算机网络(1)
  • Playwright 完全指南:从入门到实战,解锁自动化测试新范式
  • OpenCV:直接用NV21/NV12格式,画线、贴图都是相加效果,而不是替换、覆盖
  • MCP3421与STM32电压采集实现
  • 表白网页制作免费网站制作 表白网站建设教程
  • 嵌入式Linux C语言程序设计一、二
  • cocos做简单自动发射追踪子弹 切换敌人
  • C#知识学习-014(修饰符_3)
  • Linux 下逆向解析 VNC Server 密码文件为明文密码(逆向解析passwd)
  • Linux dma_resv机制原理、实现与应用详解
  • LangGraph 进阶学习