ESP32 freeRTOS笔记 参数传递、任务优先级

news2024/11/16 8:40:14

一、四种参数传递方式

1.1 整数传递

使用 (void *) 任何类型传递参数,通过地址传递给任务。

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

void myTask(void *pvPragma)
{
    int *getNum;
    getNum = (int *)pvPragma; //强转int类型指针
    printf("Task get num = %d\n",*getNum); //此处*为解地址符,解出地址存的东西
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    vTaskDelete(NULL);
}

int IntNum = 1;

void app_main(void)
{
    xTaskCreate(myTask, "mytask1", 2048, (void *)&IntNum, 1, NULL);    //取地址后传递参数
}

效果如下: 

1.2 数组

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

void myTask(void *pvPragma)
{
    int *pArrayNum;
    pArrayNum = (int *)pvPragma;
    printf("Task get num1 = %d\n", *pArrayNum);
    //因为是int类型指针 +1移动自动移动一个int
    printf("Task get num2 = %d\n", *(pArrayNum + 1)); //此处*为解地址符,解出地址存的东西
    printf("Task get num3 = %d\n", *(pArrayNum + 2));
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    vTaskDelete(NULL);
}

int testNum[] = {5, 6, 7};

void app_main(void)
{
    //数组本来就是地址 直接传递 不加&
    xTaskCreate(myTask, "mytask1", 2048, (void *)testNum, 1, NULL);    
}

效果如下:  

1.3 结构体

和整数传递很像,只不过换成了结构体,任务函数也是强转成结构体指针。

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"

//-------------------------------------------------------
typedef struct A_struct
{
    int num1;
    int num2;
} xstruct;//xstruct=struct A_struct,不清楚时查看struct和typedef struct的区别
xstruct testnum = {5,6};
void mytask(void *pvParam)
{
    xstruct *p;                             //声明一个结构体指针类型的变量,
    p = (xstruct *)pvParam;                 // 因为这里参数传的都是地址,将参数强制转化为相同的类型,取得输入参数的地址
    printf("I get testnum num1 = %d\n", p->num1); 
    printf("I get testnum num2 = %d\n", p->num2); 
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    vTaskDelete(NULL);
}
//-------------------------------------------------------
void app_main(void)
{
    xTaskCreate(mytask, "mytask1", 2048, (void *)&testnum, 1, NULL);
}

效果如下:  

1.4 字符串

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"

static const char *ptest = "hello world";


void mytask(void *pvParam)
{
    char *p;                            
    p = (char *)pvParam;                 
    printf("I get message = %s\n", p); 
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    vTaskDelete(NULL);
}

void app_main(void)
{
    xTaskCreate(mytask, "mytask1", 2048, (void *)ptest, 1, NULL);
}

效果如下:  

二、Task 任务优先级

2.1 任务优先级简介

FreeRTOS 中任务优先级数字越大,优先级越高。

引用 RTOS 官方手册RTOS task priorities in FreeRTOS for pre-emptive and co-operative real time operation

也就是 configMAX_PRIORITIES 是当前项目中允许的最大优先级。

在下路径中可以找到这个宏定义,其中在 esp-idf 代码中(非项目代码,应该是模板代码路径),FreeRTOSConfig.h 文件保存了这个的默认值。 

2.2 使用 uxTaskPriorityGet()

函数原型:

UBaseType_t uxTaskPriorityGet(TaskHandle_t xTask );
//参数: xTask: 要查找的任务的任务句柄。
//返回值: 获取到的对应的任务的优先级。 

对于 esp32 默认的 configMAX_PRIORITIES 是 25。但是如果我们创建优先级的时候将优先级设置为 25 以上。比如下文的 41。

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"

static const char *ptest = "hello world";

void mytask(void *pvParam)
{
    char *p;                            
    p = (char *)pvParam;                 
    printf("I get message = %s\n", p); 
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    vTaskDelete(NULL);
}

void app_main(void)
{
    UBaseType_t iPriority = 0;
    TaskHandle_t pxTask = NULL;

    xTaskCreate(mytask, "mytask1", 2048, (void *)ptest, 41, &pxTask);

    iPriority = uxTaskPriorityGet(pxTask);
    printf("iPriority = %d\n",iPriority);
}

2.3 使用 vTaskPrioritySet() 

vTaskPrioritySet() 可以设置任务的优先级。如果设置的优先级高于当前执行任务的优先级,则上下文切换将在此函数返回之前发生。

void app_main(void)
{
    TaskHandle_t pxTask = NULL;
    UBaseType_t iPriority = 0;

    xTaskCreate(myTask1, "mytask1", 2048, (void *)ptest, 1,&pxTask);
    xTaskCreate(myTask2, "mytask2", 2048, (void *)ptest, 4, NULL);
    
    vTaskPrioritySet(pxTask,3);

    iPriority = uxTaskPriorityGet(pxTask);
    printf("Task1 iPriority = %d\n",iPriority);
}

 

三、Task 堆栈设置和调试

3.1 显示任务详细信息 vTaskList()

通过 vTaskList来协助分析操作系统当前 task 状态,以帮助优化内存,帮助定位栈溢出问题。

void vTaskList( char *pcWriteBuffer );
parameterdescription
pcWriteBuffer保存任务状态信息表的存储区,须足够大
return

pcWriteBuffe 表中信息:

说明定义
Name创建任务的时候给任务分配的名字
State任务的状态信息,X:运行态,B:阻塞态,R:就绪态,S:挂起态,D:删除态
Priority任务优先级
Stack任务堆栈的“高水位线”,就是堆栈历史最小剩余值
Num任务编号,这个编号是唯一的;当多个任务使用同一个任务名的时候;可以通过编号来区分
void task1(void *pvParam)
{
    while (1)
    {
        printf("task1!\n");
        vTaskDelay(3000 / portTICK_PERIOD_MS);
    }
}

void task2(void *pvParam)
{
    while (1)
    {
        printf("task2!\n");
        vTaskDelay(3000 / portTICK_PERIOD_MS);
    }
}

void app_main(void)
{
    xTaskCreate(task1, "task1", 4096, NULL, 1, NULL);
    xTaskCreate(task2, "task2", 4096, NULL, 1, NULL);

    static char pcWriteBuffer[512] = {0};

    while(1)
    {
        vTaskList(pcWriteBuffer);

        printf("-----------------------------------------\n");
        printf("Name    State   Priority    Stack   Num\n");
        printf("%s\n",pcWriteBuffer);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

 3.2  查看任务剩余的堆栈空间 uxTaskGetStackHighWaterMark() 

函数原型:

UBaseType_t uxTaskGetStackHighWaterMark(TaskHandle_t xTask)

传 入 值:xTask 要查询的任务的任务句柄,若为NULL表示查询自身任务的高水位线

返 回 值:任务堆栈的高水位线值,即堆栈的历史剩余最小值。

注意是以字节为单位

void task1(void *pvParam)
{
    while (1)
    {
        printf("task1!\n");
        vTaskDelay(3000 / portTICK_PERIOD_MS);
    }
}

void app_main(void)
{
    TaskHandle_t pxTask1;

    xTaskCreate(task1, "task1", 4096, NULL, 1,&pxTask1);
    UBaseType_t iStack;

    while(1)
    {
        iStack = uxTaskGetStackHighWaterMark(pxTask1);
        printf("task1 iStack = %d\n",iStack);

        vTaskDelay(3000 / portTICK_PERIOD_MS);
    }
}

 上述代码中,task1有两行函数。运行效果如下:

如果我们将 task1中的 printf 注释掉

void task1(void *pvParam)
{
    while (1)
    {
        printf("task1!\n");
        vTaskDelay(3000 / portTICK_PERIOD_MS);
    }
}

效果如下:

与之对比,可得出printf占用了大概300多字节的堆栈。

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

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

相关文章

leetcode算法之栈

目录 1.删除字符串中的所有相邻重复项2.比较含退格的字符串3.基本计算器II4.字符串解码5.验证栈序列 1.删除字符串中的所有相邻重复项 删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {string ret;//使用数组模拟栈操作for(auto …

element的el-date-picker时间控件,限制选择范围区间天数并且当前之后的日期不可选

element的el-date-picker时间控件&#xff0c;限制选择范围区间天数并且当前之后的日期不可选 HTML部分代码 <el-date-pickerv-model"dateRange"type"datetimerange"value-format"yyyy-MM-dd HH:mm:ss"range-separator"至"start-p…

Python小案例:打印10以内的素数

解析 1、利用循环控制范围&#xff08;1,100&#xff09; 2、通过循环判断素数 3、利用标记法进行打印素数 代码 #求1——100之间的素数 for i in range(2,101):is_primeNum Truefor j in range(2,i):if i%j 0:# print(f"{i}不是素数")is_primeNum Falseif is_…

3D Web可视化平台助力Aras开发PLM系统:提供数据访问、可视化和发布功能

HOOPS中文网慧都科技是HOOPS全套产品中国地区指定授权经销商&#xff0c;提供3D软件开发工具HOOPS售卖、试用、中文试用指导服务、中文技术支持。http://techsoft3d.evget.com/ Aras是一个面向数字化工业应用的开放性平台&#xff0c;帮助世界领先的复杂互联产品制造商转变其产…

文字处理工具Word mac软件特点

Microsoft Word mac是一款文字处理软件。它是 Microsoft office 套件的一部分&#xff0c;已广泛用于创建、编辑和格式化文本文档。 Word mac软件特点 改进的协作工具&#xff1a;使用 Microsoft Word 2021&#xff0c;多个用户可以同时处理一个文档&#xff0c;从而更轻松地与…

(华为)网络工程师教程笔记(网工教程)网工入门——3、静态路由路由表的配置

参考文章&#xff1a;【全236集】网络工程师从基础入门到进阶必学教程&#xff01;通俗易懂&#xff0c;2023最新版&#xff0c;学完即可就业&#xff01;网工入门_华为认证_HCIA_HCIP_数据通信_网工学习路线 文章目录 13. 网工入门10-静态路由&#xff08;路由表的配置&#x…

STM32通用定时器

本文实践&#xff1a;实现通过TIM14_CH1输出PWM&#xff0c;外部显示为呼吸灯。 通用定时器简介 拥有TIM2~TIM5、TIM9~TIM14 一共10个定时器&#xff0c;具有4路独立通道&#xff0c;可用于输入捕获、输出比 较&#xff0c;同时包含了基本定时去的所有功能。 通用定时器的结…

Educational Codeforces Round 159 (Rated for Div. 2)(B 二分贪心 Cgcd D二分+前缀和 E字典树)

A - Binary Imbalance 有只要在01之间插入就能制造无限个0&#xff0c;没有0就统计0 1个数即可 #include<bits/stdc.h> using namespace std; const int N 110010,mod998244353; #define int long long typedef long long LL; typedef pair<int, int> PII; const…

java学习part34collect和map

153-集合框架-数组的特点、弊端与集合框架体系介绍_哔哩哔哩_bilibili 1.以前的数组 2.常用 3.Collection add只能加object&#xff0c;如果有基本类型会装箱 3.2集合和数组转换 3.3往集合添加对象的注意事项 4.迭代器 容易越界 一般不用 常用好用 5.for each 类似c的for( …

vue3 vue-router编程式导航(二)

文章目录 一、跳转到指定路径1. query传参2. Params传参 二、前进/后退三、替换当前页 Vue Router提供了强大且灵活的编程式导航功能&#xff0c;能够通过代码来控制路由的切换和跳转。本篇博客将介绍如何在Vue 3应用程序中使用Vue Router进行编程式导航。 一、跳转到指定路径…

Proteus仿真--基于51单片机的DS18B20温度采集及报警

本文介绍基于DS18B20温度采集及报警的仿真设计&#xff08;完整仿真源文件及代码见文末链接&#xff09; 仿真图如下 其中温度传感器选用DS18B20器件&#xff0c;主要用于获取温度数据并上传&#xff0c;温度显示选用数码管&#xff0c;报警模块选用蜂鸣器 仿真运行视频 Pr…

pip命令详解

pip命令介绍 pip是由Ian Bicking在2008年提出的&#xff0c;他将pyinstall重命名为pip。名称pip是首字母缩写词&#xff0c;全称为“Package Installer for Python”。自Python3的3.4版本以及Python2的2.7.9版本开始&#xff0c;pip被直接包括在Python的安装包内&#xff0c;成…

SpringBoot系列之使用Redis ZSet实现排序分页

软件环境&#xff1a; JDK 1.8 SpringBoot 2.2.1 Maven 3.2 Mysql 8.0.26 spring-boot-starter-data-redis 2.2.1 jedis3.1.0 开发工具 IntelliJ IDEA smartGit 实现思路 相对于set来说&#xff0c;sorted set是一种有序的set&#xff0c;排序是根据每个元素的score…

云原生之深入解析如何限制Kubernetes集群中文件描述符与线程数量

一、背景 linux 中为了防止进程恶意使用资源&#xff0c;系统使用 ulimit 来限制进程的资源使用情况&#xff08;包括文件描述符&#xff0c;线程数&#xff0c;内存大小等&#xff09;。同样地在容器化场景中&#xff0c;需要限制其系统资源的使用量。ulimit: docker 默认支持…

【Vue】使用 Vue CLI 脚手架创建 Vue 项目(使用命令行创建)

前言 在开始使用Vue进行开发之前&#xff0c;我们需要先创建一个Vue项目。Vue CLI&#xff08;Command Line Interface&#xff09;是一个官方提供的脚手架工具&#xff0c;可以帮助我们快速创建Vue项目。 步骤 打开终端或命令行工具&#xff0c;运行以下命令&#xff1a; vu…

传输层可靠传输的原理

目录 1.停止等待协议 2.连续ARQ协议 3.TCP报文段的首部格式 4.TCP的滑动窗口机制 &#xff08;1&#xff09;发送窗口 &#xff08;2&#xff09;接收窗口 &#xff08;3&#xff09;发送缓存 5.超时重传时间的选择 6.选择确认SACK(Selective ACK) 7.使用滑动窗口实现…

TCL - 库编译过程和官方手册

文章目录 TCL - 库编译过程和官方手册概述笔记编译步骤TCL官方手册END TCL - 库编译过程和官方手册 概述 想看看sqlite3的官方demo工程, 没看到. 想编译一下sqlite3源码, 看看编译后有没有example 工程. 看了sqlite3的官方说明, 他们工程使用tcl来编译的. 一听tcl, 咋这么耳熟…

基于Docker构建Python开发环境

1. Dockerfile dockerfile所在目录结构 FROM python:3.8 WORKDIR /leo RUN apt-get install -y wget RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo Asia/Shanghai >/etc/timezone # ssh免密登录 COPY id_rsa.pub /leo RUN mkdir ~/.s…

戴森发布全新Airstrait吹风直发器,美发科技品类再添力作

——利用气流&#xff0c;吹干的同时拉直头发&#xff0c;无需热夹板&#xff0c;头发无热损伤 &#xff08;2023年11月30日&#xff0c;上海&#xff09;戴森今日重磅发布全新美发造型产品——戴森Airstrait™吹风直发器&#xff0c;作为戴森美发科技品类的又一创新力作&…

Redis Hash数据类型

Redis Hash数据类型 几乎所有的主流编程语言都提供了哈希(hash)类型&#xff0c;它们的叫法可能是哈希、字典、关联数组、映射。在 Redis 中&#xff0c;哈希类型是指值本身又是一个键值对结构&#xff0c;形如key “key”&#xff0c;value {ffield1, value1 }, … {fieldN…