2.stm32freeRTOS---创建一个任务

2023-05-16

文章目录

  • 前言
  • 一、创建一个任务需要注意哪些?
    • 1、任务创建函数xTaskCreate
    • 2、代码分析
  • 二、动态/静态分配
    • 1· 动态分配
    • 2· 静态分配:
  • 三、删除任务
  • 四、一个函数创建两个任务
  • 总结


前言

上一次是初步接触实时系统,这次开始认真学习


一、创建一个任务需要注意哪些?

1、任务创建函数xTaskCreate

 BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //任务名
                            const char * const pcName,  //任务标签
                            const configSTACK_DEPTH_TYPE usStackDepth,//栈大小
                            void * const pvParameters,//传入参数
                            UBaseType_t uxPriority,//任务优先级
                            TaskHandle_t * const pxCreatedTask )//任务句柄

这里说一下 任务标签 ,它可以和任务名重名,也可以不重名。
任务优先级值越小,优先级越低。
任务句柄,就是在代码前面需要定义一个
TaskHandle_t Task1_Handler = NULL;

所以传任务句柄参数时可以传NULL。

2、代码分析

#include "sys.h"
#include "usart.h"
#include "led.h"

#include "FreeRTOS.h"
#include "task.h"

//任务句柄
TaskHandle_t	Task1_Handler = NULL;
TaskHandle_t	Task2_Handler = NULL;

void *Task1_func  (void *param)
{
    while(1)
        {
        printf("AS");
    }
}

void *Task2_func  (void *param)
{
    while(1)
        {
        printf("BJ");
    }
}
int main(void)
{
	delay_init();									//延时函数初始化	  
	uart_init(115200);								//初始化串口
	LED_Init(); 
										//初始化LED
	xTaskCreate((TaskFunction_t)Task1_func, "Task1", 52, NULL, 1, &Task1_Handler);
    xTaskCreate((TaskFunction_t)Task2_func, "Task2", 52, NULL, 1, NULL);

	vTaskStartScheduler();//开始任务调度
}


这里我一下创建2个任务,如果只是一个任务的创建,
只需要对上面代码删除一些东西就好。
我需要说一下实验现象:
ASASASASASASBJBJBJBJBJBJ......

所以任务1和任务2就是交替实行的,就类似于时分复用。
这次是串口打印,如果是用其他实验现象,比如是led的
闪烁,那么我们看见的就是两个任务在同时运行。




在这里插入图片描述

二、动态/静态分配

每一个任务都有一个TCB(任务控制块)的结构体TCB_t。
任务控制块里面就有malloc去申请堆空间。

1· 动态分配

xTaskCreate((TaskFunction_t)Task1_func, “Task1”, 52, NULL, 1, &Task1_Handler);

xTaskCreate函数就是动态分配TCB,动态分配栈。
上面代码就是动态分配。

2· 静态分配:

静态分配就是自己分配TCB,自己分配栈。

 TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
                                    const char * const pcName,
                        /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
                                    const uint32_t ulStackDepth,
                                    void * const pvParameters,
                                    UBaseType_t uxPriority,
                                    StackType_t * const puxStackBuffer, //传入栈
                                    StaticTask_t * const pxTaskBuffer )//TCB结构体
                                 

使用静态配需要打开一些配置:
在这里插入图片描述

在这里插入图片描述
configSUPPORT_STATIC_ALLOCATION 需要置为1.

在开任务调度的函数里面,如果configSUPPORT_STATIC_ALLOCATION 置为1了需要开一个空闲函数,所以需要提供一个vApplicationGetIdleTaskMemory函数
在这里插入图片描述

代码:

#include "sys.h"
#include "usart.h"
#include "led.h"


#include "FreeRTOS.h"
#include "task.h"






//任务句柄
TaskHandle_t	Task1_Handler = NULL;
TaskHandle_t	Task2_Handler = NULL;
//--------------------------------------
StackType_t    task3stackbuff[100];
StaticTask_t *  task3TCB;
//--------------------------------------
StackType_t    idelstackbuff[100];
StaticTask_t *  idelTCB;
/*---------------任务函数-----------------------------------*/
void *Task1_func  (void *param)
{
    while(1)
        {
        printf("AS");
    }

}
void *Task2_func  (void *param)
{
    while(1)
        {
        printf("BJ");
    }
}
void *Task3_func  (void *param)
{
    while(1)
        {
        printf("NK");
    }

}
/*---------------任务函数-----------------------------------*/
/*---------------创建一个空闲函数函数-----------------------------------*/
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
                                    StackType_t ** ppxIdleTaskStackBuffer,
                                    uint32_t * pulIdleTaskStackSize )
{
    * ppxIdleTaskTCBBuffer = idelTCB;
    * ppxIdleTaskStackBuffer = idelstackbuff;
    * pulIdleTaskStackSize = 100;
}
/*---------------创建一个空闲函数函数-----------------------------------*/


int main(void)
{
	//delay_init();									//延时函数初始化	  
	uart_init(115200);								//初始化串口
	LED_Init(); 									//初始化LED



	xTaskCreate((TaskFunction_t)Task1_func, "Task1", 52, NULL, 1, &Task1_Handler);
    xTaskCreate((TaskFunction_t)Task2_func, "Task2", 52, NULL, 1, &Task2_Handler);
    xTaskCreateStatic(Task3_func,"task3",52,NULL,1,task3stackbuff,task3TCB);

    vTaskStartScheduler();//开始任务调度

}

注意:一定要configSUPPORT_STATIC_ALLOCATION 置为1.
再说一下关于优先级问题:freeRTOS中的优先级值越大,则程序越先执行。
多个任务的优先级一致,则多个任务时分复用执行(依次轮流循环执行)。
若多个任务的优先级不一致,则优先级高的先执行并且在该任务没有主动
放弃CPU的控制的情况下会一直执行,其他低优先级的任务根本没有把那发执行。


三、删除任务

在这里插入图片描述

vTaskDelete 函数传参是任务句柄,如果需要删除某个任务,就把该任务的任务句柄传进去。
在这里插入图片描述

【xTaskCreateStatic 静态分配的任务的返回值是该任务的任务句柄,所以需要定义一个变量来存储这个返回值,再把这个返回值传给vTaskDelete 】

四、一个函数创建两个任务

#include "sys.h"
#include "usart.h"
#include "led.h"


#include "FreeRTOS.h"
#include "task.h"


//任务句柄
TaskHandle_t	Task1_Handler = NULL;
TaskHandle_t	Task2_Handler = NULL;

StackType_t    task3stackbuff[100];
StaticTask_t *  task3TCB;

/*--------------------------------------------------*/
void *Task1_func  (void *param)
{
    while(1)
        {
        printf("AS");
    }

}

void *Task2_func  (void *param)
{
    while(1)
        {
        printf("BJ");
    }

}

void *Task3_func  (void *param)
{
    while(1)
        {
        printf("NK");
    }

}

/*--------------------------------------------------*/

/*---------通用函数-----------------------------------------*/
void taskGenericFunction(void *param)
{
    int val = (int ) param;
        while(1)
            {
            printf("%d",val);
        }
}
/*---------通用函数-----------------------------------------*/

int main(void)
{
	//delay_init();									//延时函数初始化	  
	uart_init(115200);								//初始化串口
	LED_Init(); 									//初始化LED
	
	xTaskCreate((TaskFunction_t)Task1_func, "Task1", 52, NULL, 1, &Task1_Handler);
    xTaskCreate((TaskFunction_t)Task2_func, "Task2", 52, NULL, 1, NULL);

    /*---------多个任务调用一个通用函数-----------------------------------------*/
    xTaskCreate((TaskFunction_t)taskGenericFunction, "Task3", 52, NULL, 1, NULL);
    xTaskCreate((TaskFunction_t)taskGenericFunction, "Task4", 52, NULL, 1, NULL);
    /*---------多个任务调用一个通用函数-----------------------------------------*/
    vTaskStartScheduler();//开始任务调度

}

原因:每一个任务都有自己独立的栈。

总结

1·归根结底,实时操作系统和裸机程序的不同就是 时分复用 和 挨个函数执行。
2·创建一个任务的那些参数就是给这个任务营造一种“生存条件”,比如它的栈大小,它的任务控制块TCB等。
3·任务优先级一致与不一致的情况。优先级一致,则时分复用;不一致则高优先级先执行,若高优先级不放弃cpu的控制权,则低优先级没有办法执行。
4·多个任务可以调用一个功能函数时,是因为任务都有独立的栈,这个功能函数只是一个函数而已。【xTaskCreate 只有调用这样的函数才可以给任务分配栈空间】

问题:
1、任务句柄的作用是什么?可以赋值为NULL?
任务句柄 就是指向 任务控制块的指针。

2、为什么要加一个任务调度函数?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2.stm32freeRTOS---创建一个任务 的相关文章

  • #Python实现话题的发布与订阅

    Python实现话题的发布与订阅 首先我们的先了解ROS文件系统的基本框架 xff0c 如下图所示 xff1a 由上图可知 xff0c py文件放在工作包里面的scripts文件夹内 xff0c 所以 xff0c 整活 xff01 1 在工
  • #创建自定义topic

    创建自定义topic 前面我们学了用C 43 43 和Python创建发布者与订阅者 xff0c 这次我们创建自定义的话题 xff0c 其实同C 43 43 实现topic差不多 xff0c 都是编写 cpp文件 步骤有点多且繁琐 xff0
  • #使用TF实现海龟机器人跟随

    使用TF实现海龟机器人跟随 昨天粗略地讲解了一会儿TF变换 xff0c 用的是ROS系统中自带的功能包实现小海龟跟随的功能 xff08 具体见 初识TF变换 xff09 今天我们将用自己编写节点的方式实现小海龟跟随的功能 xff0c 并且
  • #创建虚拟机器人URDF模型

    创建虚拟机器人URDF模型 题外话 xff1a 作业发布已有一两天了 xff0c 之所以今天才编辑这篇博客 xff0c 是因为我也遇到问题了 xff0c 现在以及解决了 xff08 小细节 xff1a 创建功能包之前先编译工作空间确保里面已
  • # gazebo 仿真

    gazebo 仿真 1 给 base link 添加惯性 xff0c 碰撞以及 gazebo 属性 在路径xqrobot description urdf xacro 件夹下新建 件夹 gazebo xff0c 并在 gazebo 件下创建
  • #Gmapping

    Gmapping 开始之前先安装两个功能包 xff0c 命令如下 xff1a sudo apt span class token operator span get install ros span class token operator
  • #navigation

    navigation 1 安装相关依赖 sudo apt span class token operator span get install ros span class token operator span kinetic span
  • # Qt_day1

    Qt day1 1 项目框架 span class token macro property span class token directive hash span span class token directive keyword i
  • ros先订阅后发布 无法收到消息的解决办法

    现象 今天遇到的问题是 使用的是Ros1 在先订阅后发布时 会导致订阅者无法收到订阅的消息 除非在发布者发布后重新订阅 思考 以前使用的是Ros2似乎并不关心订阅和发布的先后顺序 nbsp 似乎都可以收到消息 nbsp nbsp 这个问题后
  • C/C++中关于struct和class类的区别

    struct和class的主要的区别在于两者默认的访问权限有所不同 在不设置类中的成员属性和成员方法的权限时 xff0c struct默认的访问权限是公共权限 xff0c class默认的访问权限是私有权限 补充 xff1a 成员属性和成员
  • C++中STL容器的主要使用及含义

    1 stack栈容器的使用 假如栈中存放的是字符串 xff0c 我们做如下定义 xff1a stack lt string gt ss 设该变量名为ss 其主要用法如下 xff1a ss push a 存入栈中元素a ss top 读取栈顶
  • 电赛备赛记录第一篇(控制部分)

    2022 5 25 九校联赛备赛阶段第一天 联赛小车系统沿用去年国赛使用的树莓派驱动底板与外设 整车情况良好 xff0c 摄像头通信 连接均正常 xff0c 现已拼装完整 复产复工的初步成果为 xff1a 小车可以实现开机自启动的程序运行
  • 数据结构——栈详解

    1 栈 Stack 是一种线性存储结构 xff0c 它具有如下特点 xff1a xff08 1 xff09 栈中的数据元素遵守 先进后出 34 First In Last Out 的原则 xff0c 简称FILO结构 xff08 后进先出的
  • 双目相机标定

    一 运行环境 opencv2 windows vs 二 图像获取 分割 保存 参考博客opencv打开双目摄像头 图像切割保存 scutqq的博客 CSDN博客 双目图像分割 include amp lt opencv2 core core
  • uart1接收不定长度数据和发送:STM32 HAL库串口+DMA+IDLE空闲中断

    DMA增加 xff1a usart1 gpio 默认即可 usart1中断必须打开 在 STM32 中 USART 发送接收有三种基本方式 xff0c 轮询 中断和 DMA 1 轮询方式为堵塞模式 xff0c 使用超时管理机制 它每次接收一
  • 串口、网口等自定义通信协议的问题

    自定义通信协议的问题 一 串口1 通信分为网络通信和串口通信2 协议格式3 协议设计4 代码实现 二 网口1 TCP粘包与拆包 包的划分 出现TCP粘包的原因 粘包与拆包的几种情况 常见的粘包与拆包解决方案 2 为什么UDP没有粘包 xff
  • 如何理解奇偶校验位?

    奇偶校验位提供对传输数据的简单错误 xff08 奇偶校验 xff09 检查 此表描述奇偶校验的类型 奇偶校验类型 xff1a Even 描述 xff1a 数据位加上奇偶校验位产生偶数个1 xfffc 奇偶校验类型 xff1a Mark 描述
  • C语言----隐藏代码文件

    在C语言中 xff0c 常用的文件主要是后缀为 c的源文件以及后缀名为 h的头文件 我们通常使用头文件对函数进行声明 xff0c 使用源文件对具体的函数进行实现 有些时候会由于各种原因需要将函数的功能交给别人使用 xff0c 但是又不想将具
  • c++入门系列(三)之头文件

    1 什么是头文件 xff1f 在C语言家族程序中 xff0c 头文件被大量使用 一般而言 xff0c 每个C 43 43 C程序通常由头文件和定义文件组成 头文件作为一种包含功能的函数 数据接口声明的载体文件 xff0c 主要用于保存程序的
  • std::atomic_thread_fence

    在原子变量的存取上应用不同的memory order可以实现不同的内存序来达到数据同步的目的 xff0c 而在C 43 43 11及之后的标准里 xff0c 除了利用原子操作指定内存序 xff0c 还定义了单独使用 内存栅栏 xff08 s

随机推荐

  • 【数据结构】【期末复习】知识点总结

    算法 线性表 概念明晰 xff1a 随机存取 顺序存取 随机存储和顺序存储 随机存取 顺序存取 随机存储和顺序存储这四个概念是完全不一样的 xff0c 切不可将之混淆 很多人包括我可能认为随机存取就是随机存储 xff0c 顺序存取就是顺序存
  • 【单片机学习】51单片机【定时/计数器】,详细介绍

    51单片机学习 一 先知先会1 CPU时序的有关知识1 1 周期换算2 在学习定时器之前需要明白的3 定时 计数器的工作原理4 51单片机定时器结构 二 定时 计数器的控制1 工作方式寄存器TMOD2 控制寄存器TCON3 定时 计数器的工
  • 【跟着江科大学Stm32】GPIO_LED_流水灯_蜂鸣器

    只要坚持下来了 xff0c 一定会有收获 xff01 一 LED闪烁 span class token macro property span class token directive hash span span class token
  • STM32F103C8T6 PWM驱动舵机(SG90)

    小知识 xff1a 同一个定时器 xff0c 不同通道输出不同输出PWM的特点 对于同一个定时器的不同通道输出PWM xff0c 因为它们是共用一个计数器的 xff0c 所以频率必须一样 xff0c 而占空比由各自的CCR决定 xff0c
  • STM32 PWM周期与频率的计算

    文章目录 STM32 PWM周期与频率的计算频率的计算占空比的计算笔记仅供自学 xff0c 用来回看复习 xff0c 不一定适合你 xff0c 如有错误请指出 STM32 PWM周期与频率的计算 TIM TimeBaseInitTypeDe
  • STM32F103C8T6 实现舵机与电机的控制 2个定时器输出不同频率的PWM

    智能小家居 舵机开门 xff0c 电机做风扇 or 拉窗帘 呼吸灯做提示 xff0c 小OLED屏幕显示当前状态 文章目录 直接上代码main cpwm hpwm cservo hservo cmotor hmotor c笔记仅供自学 xf
  • 【学习记录】Tpro遥控器_暂时取消Tpro的控制权(简易)

    文章目录 按照如下图示配置1 设置好 96 逻辑开关 96 2 选择执行该 96 逻辑开关指令 96 的 96 通道 96 3 配置成功附 xff1a 继电器与R88的接法 按照如下图示配置 1 设置好逻辑开关 2 选择执行该逻辑开关指令的
  • 【Linux】gcc编译工具,断点的设置,gdb调试

    文章目录 注意1 在gcc编译过程中一定要加入选项 96 g 96 xff1b 2 只有在代码处于 96 运行 96 中在 96 暂停 96 状态时才能查看变量值 xff1b 3 设置断点后 xff0c 程序在指定行之前停止 总结主要内容1
  • 【Linux】信号量操作函数

    文章目录 二 实验原理1 semget 函数函数作用 xff1a 参数意义 xff1a 例子 xff1a 2 semop 函数函数作用 xff1a 参数意义 xff1a struct sembuf 结构体定义如下例子 xff1a 再来个完整
  • 【Linux】# 2022 Linux 笔试主要内容 MJ_University

    2022 Linux 笔试主要内容 看前须知道 带 的都是老师复习课上提到的内容 xff0c 但不代表说一定会考哦 xff01 选择题 xff08 20分 xff09 填空题 xff08 20分 xff09 判断题 xff08 10分 xf
  • Ubuntu18.04安装AX210驱动

    Linux Support for Intel Wireless Adapters 从官网可以看到AX210支持的内核版本是5 10 43 如果要在低于5 10的内核版本上安装AX210的驱动的话 xff0c 需要安装以下方法操作 xff1
  • 【Linux】实验四 进程信号通信

    文章目录 一 实验目的二 实验内容三 实验原理1 信号3 1 1 信号的基本概念3 1 2 信号的发送 2 所涉及的系统函数调用3 2 1 fork 3 2 2 kill This is my question 3 2 3 signal 代
  • 报错.SO文件找不到

    此报错大多数可以通过设置环境变量解决 原因 xff1a 当执行函数动态链接 so时 xff0c 此文件不在缺省目录下 lib and usr lib 里 缺省 61 61 默认 解决方案 xff1a 1 find name so文件名 2
  • 头文件(.h) 和实现文件(.cpp)区别

    简单讲 xff0c 一个Package就是由同名的 h和 cpp文件组成 当然可以少其中任意一个文件 xff1a 只有 h文件的Package可以是接口或模板 template 的定义 xff1b 只有 cpp文件的Package可以是一个
  • 坚持学习100天:STL(头大的英文,一个模板库,非得写得我看不懂)

    前言 Hello 我是修齊 学习C 43 43 的第一百零一十八天 18是个美好的数字 xff0c 18岁刚刚好 xff0c 28岁也要用心学习 在这里记录一些学习的东西和学习的心情 内容主要是一些自己学习整理的小笔记 一 指针与引用 1
  • Ubuntu20.04以及ROS系统的安装(避坑指南)

    一 Ubuntu20 04的安装 暑期在我导那里确认好研究方向后 xff0c 一个人摸爬滚打走来确实走了不少弯路 xff0c 遂决定写下这篇文章来帮助有需要的朋友来避坑 本次安装是通过VMware来创建一台虚拟机进行后续操作 xff0c 之
  • Rplidar A2单线雷达实现Cartographer建图

    首先安装rplidar2 xff0c 在工作空间src目录下git clone xff0c catkin make编译后即可使用了 git clone https github com robopeak rplidar ros git 在使
  • 解决Ubuntu非root用户登录时,无法打开Firefox浏览器

    在使用Ubuntu操作系统时 xff0c 创建了一个普通用户 xff0c 登录该用户后发现无法打开Firefox浏览器 xff0c 进行如下步骤可解决问题 提示 Your Firefox profile cannot be loaded I
  • 【C语言】 链表 超详细解析

    目录 一 xff1a 静态存储和动态存储 二 xff1a 存储类别 三 xff1a malloc函数 四 xff1a free函数 五 xff1a 内存初始化函数memset 六 xff1a calloc函数 七 xff1a realloc
  • 2.stm32freeRTOS---创建一个任务

    文章目录 前言一 创建一个任务需要注意哪些 xff1f 1 任务创建函数xTaskCreate2 代码分析 二 动态 静态分配1 动态分配2 静态分配 xff1a 三 删除任务四 一个函数创建两个任务总结 前言 上一次是初步接触实时系统 x