FreeRTOS 学习:(十二)“任务创建” 和 “堆栈” 的动静态区分

上一篇 下一篇
任务创建和删除 相关的 API 函数

"任务创建" 和 "堆栈" 的动静态区分

注意:动态分配内存不是说连内存大小都能自动判断的,任务堆栈大小仍然是要作为输入参数人为给出的。

在一开始介绍任务的动静态创建方式时,大家或许会有一些疑问,这里的动静态貌似和堆栈的动静态内存分配相反了(C 语言中,栈是静态分配/自动分配,堆是动态分配),其实这只是表面上看似乎"反着来"了。但这是术语在不同上下文中的应用导致的错觉。

关键在于区分:

  1. 内存分配的时机和方式(编译时 vs 运行时)
  2. 内存本身的用途(是用作栈空间,还是其他)

① 核心概念:什么是"静态"和"动态"

在 C 语言和嵌入式系统中,"静态"和"动态"通常指的是内存分配的时间和管理方式

  • 静态分配 (Static Allocation) :
    • 内存是在编译时或链接时就确定的。
    • 内存通常来自程序的 .data(已初始化全局/静态变量)或 .bss(未初始化全局/静态变量)段。
    • 程序员手动定义变量,内存由编译器/链接器安排,不需要调用 malloc 或类似函数
    • 生命周期长,通常是全局的或 static 的。
  • 动态分配 (Dynamic Allocation) :
    • 内存是在程序运行时 通过调用库函数(如 malloc, free, pvPortMalloc, vPortFree)来申请和释放的。
    • 内存来自一个被称为"堆"(heap)的区域。
    • 分配和释放的时间不固定,由程序员在代码中控制。

② FreeRTOS 任务创建的两种方式

1. 动态创建 xTaskCreate()

c 复制代码
// 示例
xTaskCreate(vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
  • 发生了什么?
    • 当你调用 xTaskCreate() 时,FreeRTOS 内核会在函数内部调用 pvPortMalloc()(FreeRTOS 版本的 malloc)。
    • 这个 malloc 调用会从 FreeRTOS 管理的堆 (heap) 中动态地分配两块内存:
      1. 一块用于存放 任务控制块 (TCB - Task Control Block)
      2. 一块用于作为该任务的 栈空间 (Stack Space)
  • 为什么叫"动态"?
    • 因为这两块内存的分配发生在运行时 ,通过 malloc 类函数完成。
    • 你不需要提前准备内存,FreeRTOS 在你需要时自动从堆里"动态"地拿。
  • 内存用途 :这块动态分配的内存 ,其中一部分被用作任务的

2. 静态创建 xTaskCreateStatic()

c 复制代码
// 提前定义好内存
StaticTask_t xTaskBuffer;           // 用于 TCB
StackType_t xStack[STACK_SIZE];     // 用于栈空间

// 创建任务
xTaskCreateStatic(vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, xStack, &xTaskBuffer);
  • 发生了什么?
    • 你提前在代码中定义了两个变量:
      • xTaskBuffer:一个 StaticTask_t 类型的变量,它本身就是一个结构体,用来存放 TCB。
      • xStack:一个 StackType_t 数组,用来存放任务的栈数据。
    • 当你调用 xTaskCreateStatic() 时,你把这两个变量的地址传给 FreeRTOS。
    • FreeRTOS 直接使用你提供的内存,不再调用 malloc
  • 为什么叫"静态"?
    • 因为你提供的内存(xTaskBufferxStack)是在编译时就确定大小和位置的。
    • 它们通常是全局变量或 static 变量,存储在 .bss.data 段。
    • 分配发生在程序启动前,是"静态"的。

③ 为什么感觉"反着来"?

咱们感觉到的"反着来",很可能是因为混淆了 内存分配的方式内存的用途。表面上好像是:"栈"不是应该在栈上吗?栈上的内存不是"静态"或自动分配的吗?

实际是 :在 FreeRTOS 中,每个任务都有自己的私有栈空间 。关键问题是:这块用于"栈功能"的内存区域,是如何被分配的?

任务创建方式 用于"栈功能"的内存如何分配? 用于"TCB"的内存如何分配?
动态创建 堆 (heap)动态 (malloc) 分配 堆 (heap)动态 (malloc) 分配
静态创建 由用户静态定义(如全局数组)提供 由用户静态定义(如全局结构体)提供

所以,"动态"和"静态"描述的是TCB 和栈空间这两块内存的获取方式,而不是指任务运行时使用的"栈机制"本身。


相关推荐
qq_401700412 天前
FreeRtos——9、状态机(FSM)与面向对象在 RTOS 中的使用
freertos
hateregiste2 天前
嵌入式软件开发中常见知识点问答集锦!
c语言·单片机·嵌入式软件
济6173 天前
FreeRTOS基础--堆栈概念与汇编指令实战解析
汇编·嵌入式·freertos
嵌入式×边缘AI:打怪升级日志3 天前
基于ESP32S3的智能终端项目--5.显示时间和天气功能
笔记·esp32·freertos·天气·日历
Lester_11013 天前
STM32 电机控制应用中,ICxFilter,ICxPSC以及高级定时器的采样时钟分频CKD区别是什么
单片机·嵌入式硬件·嵌入式软件·电机控制
嵌入式×边缘AI:打怪升级日志3 天前
基于ESP32S3的智能终端项目--4.1 FreeRTOS 任务调度&&设置屏幕亮度
freertos·屏幕亮度
炸膛坦客3 天前
FreeRTOS 学习:(二十九)任务切换的底层逻辑(了解)
单片机·操作系统·freertos
qq_401700413 天前
FreeRtos——1、多任务与“上下文切换”的代价
freertos
螺丝钉的扭矩一瞬间产生高能蛋白3 天前
深入剖析FreeRTOS优先级继承机制:vTaskPriorityInherit与xTaskPriorityDisinherit源码解析
stm32·freertos·嵌入式软件·优先级反转
济6174 天前
FreeRTOS基础知识---为什么使用FreeRTOS以及其核心功能
嵌入式·freertos