STM32CubeMX学习笔记23---FreeRTOS(任务的挂起与恢复)

1、硬件设置

本实验通过freertos创建两个任务来分别控制LED2和LED3的亮灭,需要用到的硬件资源

  • LED2和LED3指示灯
  • 串口

2、STM32CubeMX设置

根据上一章的步骤创建两个任务:STM32CubeMX学习笔记22---FreeRTOS(任务创建和删除)-CSDN博客

在 Include parameters 中把 vTaskSuspend 和 vTaskResumeFromISR 选择 Enabled 使能。

 生成代码。

3、程序编程

(1)、单个任务挂起

osThreadSuspend

挂起指定任务。被挂起的任务绝不会得到 CPU 的使用权,不管该任务具有什么优先级。

函数osThreadSuspend (osThreadId thread_id)
参数thread_id: 挂起指定任务的任务ID
返回值错误码(osStatus )

 要想使用该函数必须在 Include parameters 中把 vTaskSuspend 选择 Enabled 来使能。

 例:

/*
* 任务句柄是一个指针,用于指向一个任务,当任务创建好之后,它就具有了一个任务句柄
* 以后我们要想操作这个任务都需要通过这个任务句柄,如果是自身的任务操作自己,那么
* 这个句柄可以为 NULL。
*/
osThreadSuspend (LED2Handle);//挂起LED2
(2)、挂起全部任务

osThreadSuspendAll

函数osThreadSuspendAll (void)
参数
返回值错误码(osStatus )
(3)、单个任务恢复

osThreadResume

让挂起的任务重新进入就绪状态,恢复的任务会保留挂起前的状态信息,在恢复的时候根据挂起时的状态继续运行。如果被恢复任务在所有就绪态任务中,处于最高优先级列表的第一位,那么系统将进行任务上下文的切换。可用在中断服务程序中。

函数osThreadResume (osThreadId thread_id)
参数thread_id: 挂起指定任务的任务ID
返回值错误码(osStatus )

 要想在中断服务程序中使用该函数必须在 Include parameters 中把 vTaskResumeFromISR 选择 Enabled 来使能。

例:

osThreadResume (LED2Handle);//恢复LED2
(4)、全部任务恢复

osThreadResumeAll,将所有的任务都恢复。

函数osStatus osThreadResumeAll (void)
参数
返回值错误码

 osThreadResumeAll 函数的使用方法很简单,但是要注意,调用了多少次 osThreadSuspendAll() 函数就必须同样调用多少次 osThreadResumeAll() 函数。

void vDemoFunction( void )
{
    osThreadSuspendAll();
    /* 处理 xxx 代码 */
    osThreadSuspendAll();
    /* 处理 xxx 代码 */
    osThreadSuspendAll();
    /* 处理 xxx 代码 */
 
    osThreadResumeAll(); 
    osThreadResumeAll(); 
    osThreadResumeAll(); 
}
(5)、中断服务中恢复

使用 xTaskResumeFromISR()的时候有几个需要注意的地方:

  • 当函数的返回值为 pdTRUE 时:恢复运行的任务的优先级等于或高于正在运行的任务,表明在中断服务函数退出后必 须进行一次上下文切换 , 使用 portYIELD_FROM_ISR() 进行上下文切换。当函数的返回值为 pdFALSE 时:恢复运行的任务的优先级低于当前正在运行的任务,表明在中断服务函数退出后不需 要进行上下文切换。
  • xTaskResumeFromISR() 通常被认为是一个危险的函数,因为它的调用并非是固定的,中断可能随时来来临。所以 xTaskResumeFromISR()不能用于任务和中断间的同步,如果中断恰巧在任务被挂起之前到达,这就会导致一次中断丢失(任务还没有挂起,调用 xTaskResumeFromISR()函数是没有意义的,只能等下一次中断)。这种情况下,可以使用信号量或者任务通知来同步就可以避免这种情况。
void vAnExampleISR( void )
{
    BaseType_t xYieldRequired;

    /* 恢复被挂起的任务 */ 
    xYieldRequired = xTaskResumeFromISR( xHandle ); 

    if ( xYieldRequired == pdTRUE ) 
    { 
        /* 执行上下文切换, ISR 返回的时候将运行另外一个任务 */ 
        portYIELD_FROM_ISR(xYieldRequired ); 
    } 
}
(6)、获取任务状态

osThreadGetState,获取任务当前状态。

函数osThreadGetState(osThreadId thread_id)
参数thread_id: 任务ID
返回值以下值(osThreadState )
/* Thread state returned by osThreadGetState */
typedef enum {
	osThreadRunning   = 0x0,	      /*线程正在查询自身的状态,因此必须正在运行。*/
	osThreadReady     = 0x1 ,		  /* 正在查询的线程位于已读或挂起的就绪列表中。 */
	osThreadBlocked   = 0x2,		  /* 正在查询的线程处于阻止状态。 */
	osThreadSuspended = 0x3,	      /*被查询的线程处于“挂起”状态,或者处于“阻止”状态,超时时间无限长。 */
	osThreadDeleted   = 0x4,		  /* 正在查询的线程已被删除,但其TCB尚未释放。 */   
  osThreadError     = 0x7FFFFFFF
} osThreadState;
(7)、编写程序

在任务函数中编写程序,让LED1计数到10时挂起LED2,当计数到15时恢复LED2.

void LED1_Task1(void const * argument)
{
  /* USER CODE BEGIN LED1_Task1 */
  /* Infinite loop */
	int i=0;
  for(;;)
  {
		HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);   //LED1状态每500s翻转一次
		printf("this LED1 run %d\r\n",i);
		
		if(i++==10)
		{
			osThreadSuspend (LED2Handle);//挂起LED2
			printf("挂起LED2 \r\n");
		}
		
		if(i==15) 
		{
			printf("恢复LED2 \r\n");
			osThreadResume (LED2Handle);//恢复LED2
			
		}
    osDelay(1001);
  }
  /* USER CODE END LED1_Task1 */
}

/* USER CODE END Header_LED2_Task03 */
void LED2_Task03(void const * argument)
{
  /* USER CODE BEGIN LED2_Task03 */
  /* Infinite loop */
	    /* 用于保存上次时间。调用后系统自动更新 */ 
    static portTickType PreviousWakeTime; 
    /* 设置延时时间,将时间转为节拍数 */ 
    const portTickType TimeIncrement = pdMS_TO_TICKS(1000); 

    /* 获取当前系统时间 */ 
    PreviousWakeTime = osKernelSysTick();
	int i=0;
  for(;;)
  {
		 /* 调用绝对延时函数,任务时间间隔为 1000 个 tick */ 
    osDelayUntil( &PreviousWakeTime,TimeIncrement ); 
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);   //LED1状态每500s翻转一次
		printf("this LED2 run %d \r\n",i++);
   // osDelay(900);
  }
  /* USER CODE END LED2_Task03 */
}

4、下载验证

程序编译无误后下载到板子上,可以看到LED1计数到10时挂起LED2,当计数到15时恢复LED2。

注:在不同任务(任务优先级相同)中同时使用同一个中断会导致任务轮流使用该中断,如LED1和LED2都延时1000ms后同时使用printf,则会出现以下情况,即两个任务轮流使用printf,就导致了中间的遗漏了。(优先级不同则不会出现该情况)

5、参考文献

STM32CubeMX学习笔记(28)——FreeRTOS实时操作系统使用(任务管理)_stm32 rtos 任务固定时间运行-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/472907.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

递归方法解决树的遍历问题

二叉树的最大深度 描述:给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 递归法(自顶向下) 通过递归法,左右子树同时向下递归遍历,直到遍…

大数据开发--02.环境准备

一.准备三台linux虚拟机 1.分别取名node1,node2,node3 2.配置静态ip 这里以node1为例,配置静态ip地址,其他node2.node3一样 配置完成之后别忘记 systemctl restart network 3.在各自的/etc/hosts文件中编辑三个Ip地址 三台都要配置, 4.然…

【百度灵境矩阵实训营】操作指南

【百度灵境矩阵实训营】操作指南 写在最前面提交注意事项比赛参与指南1、创建智能体作品要求 2、提交作品 学习资料包 🌈你好呀!我是 是Yu欸 🌌 2024每日百字篆刻时光,感谢你的陪伴与支持 ~ 🚀 欢迎一起踏上探险之旅&…

Java SE入门及基础(44)

目录 I / O流(上) 1. 什么是I / O流 过程分析 I / O的来源 Java 中的 I / O流 2. 字节流 OutputStream 常用方法 文件输出流 FileOutputStream 构造方法 示例 InputStream 常用方法 文件输入流 FileInputStream 构造方法 示例 综合练习 字节流应用场景 Java SE文…

LC串联谐振拓扑仿真建模及控制策略分析

直流高压电源主要应用于高端精密分析仪器、高端医疗分析仪器、静电应用、激光雷达、核探测、惯性导航、雷达通信、电子对抗、高功率脉冲、等离子体推进等行业领域。 LC串联谐振拓扑是直流高压电源中最为常用的拓扑结构。上一期内容中我们对 LC 串联谐振变换器的工作原理进行了…

Pytest单元测试框架 —— Pytest+Allure+Jenkins的应用

一、简介 pytestallurejenkins进行接口测试、生成测试报告、结合jenkins进行集成。 pytest是python的一种单元测试框架,与python自带的unittest测试框架类似,但是比unittest框架使用起来更简洁,效率更高 allure-pytest是python的一个第三方…

看似封装,其实不止于封装?

本文介绍的也不只是封装,包含零零散散的知识点。其中,主要介绍封装、包和访问限定符、static、代码块等 提示:使用PC端观看,效果更佳! 目录 一、封装 1.为什么要封装 2.怎么封装 3.怎么访问被封装的数据 4.封装…

必知必会干货!Python正则表达式常用函数

1.正则表达式 正则表达式:是一个特殊的字符序列,计算机科学的一个概念,主要用来检索/替换哪些符合某个模式的文本 在python中使用正则表达式,主要是借助re模块来实现 ​特点 灵活性/功能性/逻辑性非常强 可以使用极其简单的方法…

【NTN 卫星通信】 车辆物联网设备通过NTN和TN切换的应用场景

1 场景描述 对于有两个3GPP无线接入网服务的大面积农田和农场,物联网设备可以通过NTN和TN接入网同时受益于5G系统的双转向数据连接能力。   在这个用例中,我们有一个广域的农业自动化应用系统来控制农业车辆,例如,一个装有数百个…

二分查找算法(1)

算法介绍 二分查找适用范围不止是有序数组,很多有“二段性”的数组其实都可以使用二分查找,什么是“二段性”呢?在数组中,我们查到某个数不符合条件后,就可以排除它之前或之后的所有数据,这种性质就叫做“…

【Linux】盘点广义层面上【三种最基本的进程状态】

前言 大家好吖,欢迎来到 YY 滴 Linux系列 ,热烈欢迎! 本章主要内容面向接触过Linux的老铁 主要内容含: 欢迎订阅 YY滴C专栏!更多干货持续更新!以下是传送门! YY的《C》专栏YY的《C11》专栏YY的…

119.设计链表(力扣)

代码解决 class MyLinkedList { public:// 定义链表节点结构体struct LinkedNode {int val;LinkedNode* next;LinkedNode(int val):val(val), next(nullptr){}};MyLinkedList() {dummyhead new LinkedNode(0);size0;}int get(int index) {if (index > (size - 1) || index…

分布式文件存储与数据缓存(二)| Redis

目录 Redis概述_什么是NoSQLNoSQL的四大分类KV型NoSql(代表----Redis)列式NoSql(代表----HBase)文档型NoSql(代表----MongoDB)搜索型NoSql(代表----ElasticSearch) 关系型数据库和非…

刷力扣看见一个寻找单身狗的问题?【力扣题解】

今天刷力扣遇到一道有意思的题目,题目是写着撞色问题177 ,当我写完这个题去看看有什么好的解题方式的时候,看见一个有趣的题解问题,他对这个题目的描述是几对情侣,带几个单身狗出去玩,然后现在我们要把这几…

使用Laravel开发项目

如何使用Laravel框架开发项目 一、安装Laravel框架 1.在安装Laravel框架钱我们需要先查看要安装的Laravel框架版本以及版本所需要的安装运行条件。 2.配置好安装环境后再安装Laravel框架 2.1.配置安装环境 1)PHP版本 2)PHP OpenSSL扩展 3&#xff…

详解隐私计算框架及技术要点

隐语架构一览 为什么这样分层? 完备性透明性开放性 隐语架构解析 产品层 算法层 隐语PSI特点 PIR Data Analysis SCQL 核心特性 联邦学习 特色 计算层 SPU 核心 HEU 同态加密设备 TEEU 密码原语 资源层 kuscia 互联互通 跨域管控 最后

软件工程-第三版王立福-第1章 绪论

本书结合IEEE最新发布的软件工程体系SWEBOK,和IEEE/ACM软件工程学科小组公布的软件工程教育知识体系SEEK,北大本科生指定教材。注重基础知识的系统性,选材的先进性及知识的应用。2009年出版 软件开发本质的认识,两大技术问题&…

计算机缺失xapofx1_5.dll如何修复?分享多种修复方法轻松搞定

在计算机使用过程中,我们经常会遇到一些错误提示,其中之一就是xapofx1_5.dll丢失。丢失xapofx1_5.dll文件对电脑系统及运行程序的影响是多方面的,某些依赖于xapofx1_5.dll文件的特定软件或应用程序可能无法启动或运行过程中出现崩溃现象&…

上位机图像处理和嵌入式模块部署(qmacvisual脚本编辑)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 个人认为qmacvisual软件中,另外一个鲜明的特色,就是它本身支持javascript脚本编写,虽然是利用qt script engine…

Java基础 学习笔记九

for循环 for循环语句的语法结构 for(初始化表达式;条件表达式;更新表达式){循环体;}初始化表达式最先被执行,而且只执行一次条件表达式的执行结果必须是一个布尔类型的值更新表达式一般是负责更新某个变量值的(只有更新了某个变量值,条件表达…