FreeRTOS——优先级翻转

news2024/11/26 10:51:29

1.优先级翻转概念

优先级翻转:高优先级的任务反而慢执行,低优先级的任务反而优先执行
注意:在实时操作系统中不允许出现,在二值信号量中经常出现

在这里插入图片描述

2.优先级翻转实战

在这里插入图片描述

2.1freertos_demo.c

#include "freertos_demo.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"


//FreeRTOS配置
//1.任务配置
//1.1 START_TASK 任务 配置
#define START_TASK_PRIO 1                   /* 任务优先级 */
#define START_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            StartTask_Handler;  /* 任务句柄 */
void start_task(void *pvParameters);        /* 任务函数 */

//1.2 TASK1 任务 配置
#define TASK1_PRIO      2                   /* 任务优先级 */
#define TASK1_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            lowTask_Handler;  /* 任务句柄 */
void task1(void *pvParameters);             /* 任务函数 */

//1.3 TASK2 任务 配置
#define TASK2_PRIO      3                   /* 任务优先级 */
#define TASK2_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            middleTask_Handler;  /* 任务句柄 */
void task2(void *pvParameters);             /* 任务函数 */

//1.4 TASK3 任务 配置

#define TASK3_PRIO      4                   /* 任务优先级 */
#define TASK3_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            highTask_Handler;  /* 任务句柄 */
void task3(void *pvParameters);             /* 任务函数 */

//1.5 二值信号量句柄定义
SemaphoreHandle_t        binarySemaphore;  

//2.在freertos_demo函数中创建start_task任务
void freertos_demo(void)
{
    //创建二值信号量
     binarySemaphore = xSemaphoreCreateBinary(); 
    if(binarySemaphore != NULL)
    {
        printf("二值信号量创建成功!!!\r\n");
    }
    xSemaphoreGive(binarySemaphore);                    //释放一次信号量
    xTaskCreate((TaskFunction_t )start_task,            /* 任务函数 */
                (const char*    )"start_task",          /* 任务名称 */
                (uint16_t       )START_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )START_TASK_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&StartTask_Handler);   /* 任务句柄 */
    vTaskStartScheduler();
}

//3.在start_task函数中创建task1、task2任务
void start_task(void *pvParameters)
{
    
    //进入临界区
    taskENTER_CRITICAL();
    //创建任务1
      xTaskCreate((TaskFunction_t )task1,            /* 任务函数 */
                (const char*    )"task1",          /* 任务名称 */
                (uint16_t       )TASK1_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )TASK1_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&lowTask_Handler);   /* 任务句柄 */
     //创建任务2          
     xTaskCreate((TaskFunction_t )task2,            /* 任务函数 */
                (const char*    )"task2",          /* 任务名称 */
                (uint16_t       )TASK2_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )TASK2_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&middleTask_Handler);   /* 任务句柄*/
    //创建任务3          
    xTaskCreate((TaskFunction_t )task3,            /* 任务函数 */
                (const char*    )"task3",          /* 任务名称 */
                (uint16_t       )TASK3_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )TASK3_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&highTask_Handler);   /* 任务句柄*/         
      //删除开始任务        
      vTaskDelete(StartTask_Handler);   
                
     //退出临界区
     taskEXIT_CRITICAL();
}


//4.任务一 低优先级任务
void task1(void *pvParameters)
{
    while (1)
    {
        printf("low Task获取信号量\r\n");
        xSemaphoreTake(binarySemaphore, portMAX_DELAY);
        printf("low Task正在运行\r\n");
        delay_ms(3000);
        printf("low Task正在释放信号量\r\n");
        xSemaphoreGive(binarySemaphore);
        vTaskDelay(1000);
    }
}

//5.任务二 中优先级任务
void task2(void *pvParameters)
{
    
    while(1)
    {
        printf("middle Task正在释放信号量\r\n");
        vTaskDelay(1000); 
    }
   
}

//6.任务三 高优先级任务
void task3(void *pvParameters)
{
    while(1)
    {
        printf("high Task获取信号量\r\n");
        xSemaphoreTake(binarySemaphore, portMAX_DELAY);
        printf("high Task正在运行\r\n");
        delay_ms(1000);
        printf("high Task正在释放信号量\r\n");
        xSemaphoreGive(binarySemaphore);
        vTaskDelay(1000);
    }
   
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

1.69寸SPI接口240280TFT液晶显示模块使用中碰到的问题说明并记录一下, 在网上买了1.69寸液晶显示模块,使用spi接口,分辨率240280,给的参考程序是GPIO模拟的SPI接口,打算先移植到FreeRtos测试,再慢慢使用硬件…

Algorithm-Left Edge算法

算法输入: 多个段,每个段由两个值表示,例如(1,3) 算法原理: 将多个段按照左边的值排序放到列表中遍历列表,不断选择没有重叠的段,直到列表遍历结束,将选择…

rk3588中编译带有ffmpeg的opencv

有朋友有工程需要,将视频写成mp4,当然最简单的方法当然是使用opencv的命令 cv::VideoWriter writer;bool bRet writer.open("./out.mp4", cv::VideoWriter::fourcc(m, p, 4, v), 15, cv::Size(640, 512), 1); 但是奈何很难编译成功&#xff…

【python入门】day12:bug及其处理思路

bug的常见类型 粗心 / 没有好习惯 思路不清 lst[{rating:[9.7,2062397],id:1292052,type:[犯罪,剧情],title:肖申克的救赎,actors:[蒂姆罗宾斯,摩根弗里曼]},{rating:[9.6,1528760],id:1291546,type:[剧情,爱情,同性],title:霸王别姬,actors:[张国荣 ,张丰毅 , 巩俐 ,葛优]},{r…

redis的使用、打开、关闭的详细介绍

redis的使用、打开、关闭的详细介绍 1.安装redis cd / cd opt/ wget https://download.redis.io/releases/redis-5.0.5.tar.gz 2.解压redis tar xzf redis-5.0.5.tar.gz 3.执行make cd redis-5.0.5/ make 如果出现找不到make的情况就yum install -y make 如果没有gcc就…

网络安全—SSL安全访问应用

文章目录 网络拓扑部署CA服务器颁发证书开启Web服务安装IIS服务修改Web默认网页 申请Web证书前提准备申请文件生成申请web证书开始安装web证书 客户机访问web默认网站使用HTTP使用HTTPS 为客户机安装浏览器证书 环境:Windows Server 2003 网络拓扑 这里使用NAT还是…

力扣hot100 二叉树的直径

👨‍🏫 题目地址 一个节点的最大直径 它左树的深度 它右树的深度 😋 AC code /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* Tr…

[C#]C# OpenVINO部署yolov8图像分类模型

【官方框架地址】 https://github.com/ultralytics/ultralytics.git 【算法介绍】 YOLOv8 抛弃了前几代模型的 Anchor-Base。 YOLO 是一种基于图像全局信息进行预测的目标检测系统。自 2015 年 Joseph Redmon、Ali Farhadi 等人提出初代模型以来,领域内的研究者们…

设计模式篇章(1)——理论基础

设计模式:在软件开发中会面临许多不断重复发生的问题,这些问题可能是代码冗余、反复修改旧代码、重写以前的代码、在旧代码上不断堆新的代码(俗称屎山)等难以扩展、不好维护的问题。因此1990年有四位大佬(GoF组合&…

魔改Stable Diffusion,开源创新“单目深度估计”模型

单目深度估计一直是计算机视觉领域的难点。仅凭一张 RGB 图像,想要还原出场景的三维结构,在几何结构上非常不确定,必须依赖复杂的场景理解能力。 即便使用更强大的深度学习模型来实现,也面临算力需求高、图像数据注释量大、泛化能力弱等缺点。 为了解决这些难题&a…

导入和导出功能的简单实现

理解定义 导入:将外部文件数据导入到数据库或内存中。导出:将数据库或内存中的数据导出为外部文件。 具体实现步骤如下: 导入数据:可以通过读取外部文件(如Excel、CSV等)的数据,然后将数据保存…

简易机器学习笔记(八)关于经典的图像分类问题-常见经典神经网络LeNet

前言 图像分类是根据图像的语义信息对不同类别图像进行区分,是计算机视觉的核心,是物体检测、图像分割、物体跟踪、行为分析、人脸识别等其他高层次视觉任务的基础。图像分类在许多领域都有着广泛的应用,如:安防领域的人脸识别和…

【数据结构】二叉树的创建和遍历:前序遍历,中序遍历,后序遍历,层次遍历

目录 一、二叉树的定义 1、二叉树的定义 2、二叉树的五种形态 二叉树的子树 : 3、满二叉树与完全二叉树 4、二叉树的性质 5、二叉树的存储结构 1、顺序存储 ​编辑 2、链式存储 二、二叉树的遍历 按照前序序列构建二叉树 1、前 (先) 序遍历(Preorder …

没有Kubernetes也可以玩转Dapr?

一、NameResolution组件 虽然Dapr提供了一系列的编程模型,比如服务调用、发布订阅和Actor模型等,被广泛应用的应该还是服务调用。我们知道微服务环境下的服务调用需要解决服务注册与发现、负载均衡、弹性伸缩等问题,其实Dapr在这方面什么都没…

Golang拼接字符串性能对比

g o l a n g golang golang的 s t r i n g string string类型是不可修改的,对于拼接字符串来说,本质上还是创建一个新的对象将数据放进去。主要有以下几种拼接方式 拼接方式介绍 1.使用 s t r i n g string string自带的运算符 ans ans s2. 使用…

STM32 基础知识(探索者开发板)--135讲 ADC转换

ADC定义: ADC即模拟数字转换器,英文详称 Analog-to-digital converter,可以将外部的模拟信号转换 ADC数模转换中一些常用函数: 1. HAL_ADC_Init 函数 HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc); 初始化ADC 形参&…

网络连通性批量检测工具

一、背景介绍 企业网络安全防护中,都会要求配置物理网络防火墙以及主机防火墙,加强对网络安全的防护。云改数转之际,多系统上云过程中都会申请开通大量各类网络配置,针对这些复杂且庞大的网络策略开通配置,那么在网络配…

【12】ES6:模块化

一、JavaScript 模块化 JavaScript 模块化是一种组织和管理 JavaScript 代码的方法,它将代码分割为独立的模块,每个模块都有自己的作用域,并且可以导出和导入功能。模块化可以提高代码的可维护性、可重用性和可扩展性。 在JavaScript中&…

AIGC时代-GPT-4和DALL·E 3的结合

在当今这个快速发展的数字时代,人工智能(AI)已经成为了我们生活中不可或缺的一部分。从简单的自动化任务到复杂的决策制定,AI的应用范围日益扩大。而在这个广阔的领域中,有两个特别引人注目的名字:GPT-4和D…

2020年认证杯SPSSPRO杯数学建模A题(第二阶段)听音辨位全过程文档及程序

2020年认证杯SPSSPRO杯数学建模 A题 听音辨位 原题再现: 把若干 (⩾ 1) 支同样型号的麦克风固定安装在一个刚性的枝形架子上 (架子下面带万向轮,在平地上可以被水平推动或旋转,但不会歪斜),这样的设备称为一个麦克风树。不同的麦…