当前位置: 首页 > news >正文

堆内存和栈空间对任务创建的影响

在创建任务的时候使用下面函数


BaseType_t xTaskCreate( TaskFunction_t pxTasCode, // 函数指针, 任务函数const char * const pcName, // 任务的名字const configSTACK_DEPTH_TYPE usStackDepth, // 栈大小,单位为word,10表示40字节void * const pvParameters, // 调用任务函数时传入的参数UBaseType_t uxPriority,    // 优先级TaskHandle_t * const pxCreatedTask ); // 任务句柄, 以后使用它来操作这个任务
参数 描述
pvTaskCode 函数指针,任务对应的 C 函数。任务应该永远不退出,或者在退出时调用 "vTaskDelete(NULL)"。
pcName 任务的名称,仅用于调试目的,FreeRTOS 内部不使用。pcName 的长度为 configMAX_TASK_NAME_LEN。
usStackDepth 每个任务都有自己的栈,usStackDepth 指定了栈的大小,单位为 word。例如,如果传入 100,表示栈的大小为 100 word,即 400 字节。最大值为 uint16_t 的最大值。确定栈的大小并不容易,通常是根据估计来设定。精确的办法是查看反汇编代码。
pvParameters 调用 pvTaskCode 函数指针时使用的参数:pvTaskCode(pvParameters)。
uxPriority 任务的优先级范围为 0~(configMAX_PRIORITIES – 1)。数值越小,优先级越低。如果传入的值过大,xTaskCreate 会将其调整为 (configMAX_PRIORITIES – 1)。
pxCreatedTask 用于保存 xTaskCreate 的输出结果,即任务的句柄(task handle)。如果以后需要对该任务进行操作,如修改优先级,则需要使用此句柄。如果不需要使用该句柄,可以传入 NULL。
返回值 成功时返回 pdPASS,失败时返回 errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY(失败原因是内存不足)。请注意,文档中提到的失败返回值是 pdFAIL 是不正确的。pdFAIL 的值为 0,而 errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY 的值为 -1。

对于栈

  • 这里的栈分配的是每个任务独立的空间

  • 存放:局部变量、函数调用参数、返回地址、CPU寄存器

  • 任务切换时保存/恢复现场

  • 栈空间不够则会导致栈溢出

对于堆

  • #define configTOTAL_HEAP_SIZE ((size_t)10240) // 这是堆大小c在
    
  • 全局内存池,所有任务共享

  • 用于动态分配:任务栈、任务控制块(TCB)、队列、信号量等

  • 堆内存不够就会导致任务创建失败

/* USER CODE BEGIN Header */
/********************************************************************************* File Name          : freertos.c* Description        : Code for freertos applications******************************************************************************* @attention** Copyright (c) 2023 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
static TaskHandle_t MusicCreatedTask = NULL; 		//蜂鸣器句柄
static TaskHandle_t LED1CreatedTask = NULL;			//板载LED句柄
static TaskHandle_t LED2CreatedTask = NULL;			//LED句柄
static TaskHandle_t ButtonCreatedTask = NULL;		//按键句柄
BaseType_t retMusic;								//接收蜂鸣器返回值
BaseType_t retLED1;						   			//接收板载LED返回值
BaseType_t retLED2;									//接收LED返回值
BaseType_t retButton;								//接收按键返回值
/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {.name = "defaultTask",.stack_size = 128 * 4,.priority = (osPriority_t) osPriorityNormal,
};/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
//创建蜂鸣器响应函数
void PlayMusic(void *pvParameters)
{while(1){if(retMusic == pdPASS){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);vTaskDelay(500);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);vTaskDelay(500);}}
}
//创建板载LED响应函数
void PlayLed1(void *pvParameters)
{while(1){if(retLED1 == pdPASS){HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);vTaskDelay(500);HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);vTaskDelay(500);}}
}
//创建LED响应函数
void PlayLed2(void *pvParameters)
{while(1){if(retLED2 == pdPASS){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);vTaskDelay(500);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);vTaskDelay(500);}}
}
//利用按键删除蜂鸣器响应任务
void PlayButton(void *pvParameters)
{while(1){if(retButton == pdPASS){vTaskDelay(20); // 消抖if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) == GPIO_PIN_RESET){if(MusicCreatedTask != NULL){vTaskDelete(MusicCreatedTask);//删除蜂鸣器任务HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);vTaskDelay(50);MusicCreatedTask = NULL;}           }vTaskDelay(50);}}
}
/* USER CODE END FunctionPrototypes */void StartDefaultTask(void *argument);void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) *//*** @brief  FreeRTOS initialization* @param  None* @retval None*/
void MX_FREERTOS_Init(void) {/* USER CODE BEGIN Init *//* USER CODE END Init *//* USER CODE BEGIN RTOS_MUTEX *//* add mutexes, ... *//* USER CODE END RTOS_MUTEX *//* USER CODE BEGIN RTOS_SEMAPHORES *//* add semaphores, ... *//* USER CODE END RTOS_SEMAPHORES *//* USER CODE BEGIN RTOS_TIMERS *//* start timers, add new ones, ... *//* USER CODE END RTOS_TIMERS *//* USER CODE BEGIN RTOS_QUEUES *//* add queues, ... *//* USER CODE END RTOS_QUEUES *//* Create the thread(s) *//* creation of defaultTask */defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);/* USER CODE BEGIN RTOS_THREADS *//* add threads, ... *//*创建蜂鸣器任务*/retMusic = xTaskCreate(PlayMusic, "PlayMusic", 128, NULL, osPriorityNormal, &MusicCreatedTask);/*创建板载led闪烁任务*/retLED1 = xTaskCreate(PlayLed1, "PlayLed1", 128, NULL, osPriorityNormal, &LED1CreatedTask);/*创建led闪烁任务*/retLED2 = xTaskCreate(PlayLed2, "PlayLed2", 128, NULL, osPriorityNormal, &LED2CreatedTask);/*创建Button(按键)检测任务*/  retButton = xTaskCreate(PlayButton, "PlayButton", 128, NULL, configMAX_PRIORITIES-1, &ButtonCreatedTask);//提高按键的优先级 有按键先响应按键内容/* USER CODE END RTOS_THREADS *//* USER CODE BEGIN RTOS_EVENTS *//* add events, ... *//* USER CODE END RTOS_EVENTS */}/* USER CODE BEGIN Header_StartDefaultTask */
/*** @brief  Function implementing the defaultTask thread.* @param  argument: Not used* @retval None*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{/* USER CODE BEGIN StartDefaultTask *//* Infinite loop */for(;;){//osDelay(1);//Led_Test();
//	  LCD_Test();}/* USER CODE END StartDefaultTask */
}/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application *//* USER CODE END Application */

在创建上述任务时由于堆内存分配不足所以导致PlayButton按键任务没有创建成功,无法对蜂鸣器响应任务进行删除处理,因此在检查所有硬件电路完整的同时,查看变量无误后还需要在FreeRTOSConfig.h里面查看

define configTOTAL_HEAP_SIZE ((size_t)10240)分配的堆内存是否够

http://www.jsqmd.com/news/491886/

相关文章:

  • 深入理解计算机系统:CPU 里面根本没有减法器?揭秘计算机的 0 和 1 是如何计算的
  • 2.Adobe Animate散件、绘制对象、组、元件
  • 2026年除甲醛品牌TOP10揭晓:谁才是真正靠谱的行业首选?
  • 排土场在线监测厂家核心竞争力对比:2026高性价比品牌推荐 - 深度智识库
  • Win10/11系统中检测电池健康的工具有哪些?
  • 【ABAP】ALV 指定单元格染色
  • LeetCode Hot 100——贪心部分
  • spaCy v2.0:自定义流水线组件与扩展属性实战
  • 赋能智慧电厂:一块开发板如何重塑能源安全巡检的底层逻辑
  • 相比高防IP,为什么现在的游戏公司更倾向于选择“湘情盾”?
  • 2026年全国精密传动设备供应商选型测评:行星减速机与中空旋转平台综合指南 - 深度智识库
  • 从标准件到定制化:2026车床刀座选型全流程指南与品牌推荐 - 品牌推荐大师1
  • Linux 基础IO (五)深入理解文件系统
  • 国产化编辑器如何扩展KindEditor的Excel公式导入?
  • 将文本转化为向量化表示
  • ansys apdl 车轨耦合车桥耦合 列车模型:考虑车体、转向架、车轮质量和二系悬挂 钢轨
  • 计算机毕业设计springboot高校学生党员信息管理系统 基于SpringBoot的高校党建信息化管理平台 基于SpringBoot的智慧校园党员服务系统
  • 全志H618
  • ceph提供rbd存储
  • 飞函私有化,安全重塑跨部门协作
  • 建议收藏|2026知网新规下如何降AI?国内外5款降低AIGC率工具实测(含免费降AI教程) - 殷念写论文
  • Unity Shader 实战:从零掌握 PBR 基于物理的渲染
  • django基于大数据技术的医疗数据分析与研究
  • CoPaw网页爬虫skill技能及定时任务管理
  • Linux 命令之 uname 详解(查看系统信息)
  • Python全栈入门到实战【基础篇 23】函数式编程:高阶函数与匿名函数
  • 中断很难?看完这篇就懂了
  • Claude code安装/CC switch安装
  • 伟伦定制工厂店
  • 医疗HIS系统Java如何通过控件优化病历图片文件夹的浏览器端分片加密断传?