嵌入式FreeRTOS学习二,FreeRTOS任务的创建和删除

2023-05-16

一、任务的创建和删除

1.1 函数xTaskCreate

       此函数用来创建一个任务,任务需要RAM来保存与任务有关的状态信息(任务控制块),任务也需要一定的RAM 来作为任务堆栈。
       如果使用函数xTaskCreate()来创建任务的话那么这些所需的RAM就会自动的从FreeRTOS的堆中分配,因此必须提供内存管理文件,默认我们使用heap_4.c这个内存管理文件,而且宏configSUPPORT_DYNAMIC_ALLOCATION必须为1。
       如果使用函数xTaskCreateStatic()创建的话这些RAM就需要用户来提供了。新创建的任务默认就是就绪态的,如果当前没有比它更高优先级的任务运行那么此任务就会立即进入运行态开始运行,不管在任务调度器启动前还是启动后,都可以创建任务。此函数也是我们以后经常用到的,本教程所有例程均用此函数来创建任务,函数原型如下:
 BaseType_t xTaskCreate( 
            TaskFunction_t pxTaskCode, 
            const char *const pcName, 
            const uint16_t usStackDepth, 
            void *const pvParameters, 
            UBaseType_t uxPriority, 
            TaskHandle_t *const pxCreatedTask);
参数:
pxTaskCode:任务函数。
pcName:任务名字,一般用于追踪和调试,任务名字长度不能超configMAX_TASK_NAME_LEN。
usStackDepth:任务堆栈大小,注意实际申请到的堆栈是usStackDepth的4倍,例如数值128,即128字。其中空闲任务的任务堆栈大小为 configMINIMAL_STACK_SIZE。
pvParameters:传递给任务函数的参数。
uxPriotiry:任务优先级,范围0~configMAX_PRIORITIES-1。若填写的数值超过configMAX_PRIORITIES-1,则静默地配置为 configMAX_PRIORITIES-1。有些版本增加了configASSERT( uxPriority<configMAX_PRIORITIES )语句,且使能configASSERT_DEFINED,则停留在该处。
pxCreatedTask:任务句柄,任务创建成功以后会返回此任务的任务句柄,这个句柄其实就是任务的任务堆栈。此参数就用来保存这个任 务句柄。其他API函数可能会使用到这个句柄。
返回值:
pdPASS:任务创建成功。
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY:任务创建失败,因为堆内存不足!

1.2 函数xTaskCreateStatic

此函数和xTaskCreate()的功能相同,也是用来创建任务的,但是使用此函数创建的任务所需的 RAM需要用用户来提供。如果要使用此函数的话需要将configSUPPORT_STATIC_ALLOCATION定义为1。函数原型如下:
TaskHandle_t xTaskCreateStatic( 
             TaskFunction_t pxTaskCode, 
             const char * const pcName, 
             const uint32_t ulStackDepth, 
             void * const pvParameters, 
             UBaseType_t uxPriority,  
             StackType_t * const puxStackBuffer, 
             StaticTask_t * const pxTaskBuffer );
参数:
pxTaskCode:任务函数。
pcName:任务名字,一般用于追踪和调试,任务名字长度不能超configMAX_TASK_NAME_LEN。
usStackDepth:任务堆栈大小,由于本函数是静态方法创建任务,所以任务堆栈由用户给出,一般是个数组,此参数就是这个数组的大小。
pvParameters:传递给任务函数的参数。
uxPriotiry:任务优先级,范围 0~configMAX_PRIORITIES-1,数值越大,优先级就越高,在FreeRTOSConfig.h可以配置configMAX_PRIORITIES.若填写的数值超过configMAX_PRIORITIES-1,则静默地配置为configMAX_PRIORITIES-1。有些版本增加了
configASSERT( uxPriority < configMAX_PRIORITIES )语句,且使能configASSERT_DEFINED,则停留在该处。
puxStackBuffer:任务堆栈,一般为数组,数组类型要为StackType_t类型。
pxTaskBuffer:任务控制块。
返回值:
NULL;任务创建失败,puxStackBuffer 或 pxTaskBuffer为 NULL的时候会导致这个错误的发生。
其他值:任务创建成功,返回任务的任务句柄
注意,若configSUPPORT_STATIC_ALLOCATION有效了,需要为系统的空闲任务和定时器任务提供独立的内存空间,详细添加的代码如下:
 static StaticTask_t xIdleTaskTCBBuffer; 
 static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];


/* 空闲任务所需内存 */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
 StackType_t **ppxIdleTaskStackBuffer,StaticTask_t **pulIdleTaskStackSize)
 {  *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer; 
    *ppxIdleTaskStackBuffer = &xIdleStack[0];
    *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
 /* place for user code */
 } 
 

static StackType_t TimerTaskStack[configMINIMAL_STACK_SIZE];
 static StaticTask_t TimerTaskTCB;

 /* 定时器任务所需内存 */
 void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
 StackType_t**ppxTimerTaskStackBuffer,StackType_t**pulTimerTaskStackSize)
 {
  *ppxTimerTaskTCBBuffer=&TimerTaskTCB;
  *ppxTimerTaskStackBuffer=TimerTaskStack;
  *pulTimerTaskStackSize=configMINIMAL_STACK_SIZE;
 }
函数栈大小确定
函数的栈大小计算起来是比较麻烦的,那么有没有简单的办法来计算呢?有的,一般 IDE 开发环境都有这样的功能,比如 MDK 会生成一个 htm 文件,通过这个文件用户可以知道每个被调用函数的最大栈需求以及各个函数之间的调 用关系。但是 MDK 无法确定通过函数指针实现函数调用时的栈需求。另外,发生中断或中断嵌套时的现场保护需要的栈 空间也不会统计。
app_task_rtc (Thumb, 128 bytes, Stack size 48 bytes, main.o(i.app_task_rtc))
[Stack] 4 Max Depth = 200 + Unknown Stack Size
Call Chain = app_task_rtc ⇒ dgb_printf_safe ⇒ xQueueGenericSend ⇒ xTaskResumeAll ⇒ xTaskIncrementTick

1.3 函数xTaskCreateRestricted

此函数也是用来创建任务的,只不过此函数要求所使用的MCU有MPU(内存保护单元),用此函数创建的任务会受到MPU的保护。其他的功能和函数xTaskCreate()一样。
BaseType_t xTaskCreateRestricted( 
        const TaskParameters_t * const pxTaskDefinition,
        TaskHandle_t *pxCreatedTask );
参数:
pxTaskDefinition:指向一个结构体TaskParameters_t,这个结构体描述了任务的任务函数、堆栈大小、优先级等。此结构体在文件 task.h中有定义。
pxCreatedTask:任务句柄。
返回值:
pdPASS:任务创建成功。
其他值:任务创建失败,因为堆栈内存不足!

1.4 函数vTaskDelete

       删除一个用函数xTaskCreate()或者xTaskCreateStatic()创建的任务,被删除了的任务不再存在,也就是说再也不 会进入运行态。任务被删除以后就不能再使用此任务的句柄!如果此任务是使用动态方法创建的,也就是使用函数 xTaskCreate()创建的,那么在此任务被删除以后此任务之前申请的堆栈和控制块内存会在空闲任务中被释放掉,因此当 调用函数vTaskDelete()删除任务以后必须给空闲任务一定的运行时间。
        只有那些由内核分配给任务的内存才会在任务被删除以后自动的释放掉,用户分配给任务的内存需要用户自行释放 掉,比如某个任务中用户调用函数 pvPortMalloc()分配了500字节的内存,那么在此任务被删除以后用户也必须调用函数
vPortFree()将这500字节的内存释放掉,否则会导致内存泄露。此函数原型如下:
 vTaskDelete( TaskHandle_t xTaskToDelete )

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

嵌入式FreeRTOS学习二,FreeRTOS任务的创建和删除 的相关文章

  • Ubuntu18.04安装教程——超详细的图文教程

    电脑配置 xff1a 名称 xff1a Lenovo 拯救者Y7000P 处理器 xff1a i7 10750H 内存 xff1a 32G 固态 xff1a 1TB 显卡 xff1a RTX2060 6G 一 准备工作 本文以 Ubuntu
  • Ubuntu18.04启动后无法进入桌面修复方法(图文)

    引言 xff08 吐槽可略过 xff09 xff1a Ubuntu是应用广泛的Linux操作系统 xff0c 特别是在机器学习应用中 xff0c 通过调用NVIDIA显卡的GPU进行计算和研究的主要平台之一 但是由于NV显卡的存在 xff0
  • VINS-Course代码解析——run_euroc前端数据处理

    vins mono总框架如下 xff1a 主要分为三大块 xff1a 我们先从主函数 main 入手 xff1a 主函数中有三个线程 xff0c 读取完数据集和配置文件的路径后就会进入这三个线程 xff0c 如下图 xff1a thd Ba
  • Gazebo11的更新与安装

    Melodic自带的Gazebo版本过低 xff0c 建议升级 Gazebo安装见gazebo官网 需注意以下四点 删除gazebo9以及相关插件选用Alternative installation step by step的安装方式 xf
  • XTDrone目标检测

    编译Darkent ROS 方法一 xff1a xff08 推荐 xff09 直接clone xff0c 记得加 recurse submodules xff0c 防止文件缺失 cd span class token operator sp
  • C++求解N个数的最大公约数、最小公倍数

    一 2个数的最大公约数 span class token comment 辗转相除法 span span class token keyword int span span class token function gcd span spa
  • 子序列个数——动态规划

    题目 xff1a 统计一个字符串中全部不同的子序列的个数 思路 xff1a 动态规划求解 令 f i 61 前 i 个元素中包含的全部子序列的个数 那么状态转移方程分为下面两种情况 xff1a 当第 i 个元素在前面 i 1 个字符中没有出
  • 字符串中特定子序列出现的次数(动态规划)

    题目 xff1a 给定一个字符串 xff0c 求子序列 cwbc 出现的次数 思路 xff1a 动态规划 令 dp i j 表示前 i 个字符中匹配了字符串 cwbc 中前 j 位 xff08 j 61 1 2 3 4 xff09 的个数
  • VMware ubuntu虚拟机无法上网的解决办法(笔记本连接WIFI情况)

    文章目录 一 虚拟机网络配置 一 虚拟机网络配置 1 设置Ubuntu网络适配器的网络连接方式为NAT模式 2 还原虚拟机网络配置 还原一下默认设置 3 window网络适配器设置适配器允许网络共享 4 Ubuntu启用联网 xff0c 连
  • ubuntu在树梅派上之VNC

    启动vncserver vncserver span class token operator span geometry 1600x900 杀死第一个桌面 vncserver span class token operator span
  • Sourcetree介绍及使用

    Sourcetree是一个操作简单但功能强大的免费Git客户端管理工具 xff0c 可应用在Windows和Mac平台 Sourcetree的安装 xff1a 1 从Sourcetree Free Git GUI for Mac and W
  • javascript创建一个基于数组的栈结构

    栈是一种遵从后进先出 xff08 LIFO xff09 原则的有序集合 新添加或待删除的元素都保存在栈的同 一端 xff0c 称作栈顶 xff0c 另一端就叫栈底 在栈里 xff0c 新元素都靠近栈顶 xff0c 旧元素都接近栈底 栈拥有以
  • Ubuntu16.04+RealsenseT265跑通VINS-Fusion

    一 提前条件 系统版本 xff1a ubuntu16 04 43 ROS xff08 kinetic xff09 默认已经掌握了ubuntu系统下的基本命令以及ROS的基本操作 二 realsenseT265的SDK测试 官方网站https
  • Why Kubernetes ,我对Kubernetes的理解

    去年换工作后 xff0c 开始真正在生产环境中接触容器与Kubernetes 边恶补相关知识的同时 xff0c 也想把学到的内容和自己的理解整理出来 学习的途径包括k8s官方文档 书籍 极客时间专栏及网上各种博文 所涉及一些摘抄或描述 xf
  • Kubernetes的几种主流部署方式01-minikube部署

    综述 Kubernetes集群的组件众多 xff0c 要部署一套符合生产环境的集群不是一件容易的事 好在随着社区的快速发展 xff0c 特别是在它成为事实上的容器编排标准以后 xff0c 基本所有的主流云平台都完全支持Kubernetes
  • Kubernetes 1.14版本的亮点新功能

    部分翻译自https sysdig com blog whats new kubernetes 1 14 Kubernetes 1 14的亮点新功能 xff1a 支持Windows容器服务可以通过kubeadm动态地创建一个高可用集群将ku
  • Kubernetes的几种主流部署方式02-kubeadm部署1.14版本高可用集群

    在上篇文章minikube部署中 xff0c 有提到Minikube部署Kubernetes的核心就是Kubeadm xff0c 这篇文章来详细说明下Kubeadm原理及部署步骤 写这篇文章的时候 xff0c Kubernetes1 14刚
  • Kubectl常用命令详解

    要使用和维护Kubernetes集群 xff0c 最常用且直接的方式 xff0c 就是使用自带的命令行工具Kubectl 这里梳理下常用的子命令及参数 xff0c 方便查找参考 参考文档 xff1a Overview of kubectlk
  • Word | 关于删除分节符(下一页)前面的版式就乱了解决方案

    WORD中删除分节符有这样的规定 xff1a 如果要删除分节符 xff0c 只要把光标移动到该分节符上 xff0c 按Delete键即可 但是要注意该分节符前面的文字将合并到后面的节中 xff0c 并且采用后者的格式设置 解决方法 xff1
  • sheetjs在使用中日期被自动转换问题

    在vue开发后台中 xff0c 需求是前端上传csv文件 xff0c 解析成对象数组 xff0c 找到了插件SheetJS js xlsx npm i xlsx span class token operator span span cla

随机推荐