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 和栈空间这两块内存的获取方式,而不是指任务运行时使用的"栈机制"本身。


相关推荐
2401_853448236 小时前
FreeRTOS项目---WiFi模块(2)
stm32·单片机·freertos·esp8266·通信协议
一个平凡而乐于分享的小比特1 天前
UCOSIII内核 VS FreeRTOS内核
笔记·freertos·ucosiii
Meraki.Zhang1 天前
【STM32实践篇】:STM32CubeMX 的使用
stm32·单片机·嵌入式软件
2401_8534482311 天前
学习FreeRTOS(第四天)
单片机·嵌入式·freertos
Hello_Embed12 天前
FreeRTOS 入门(四):堆的核心原理
数据结构·笔记·学习·链表·freertos·
墨辰JC17 天前
基于STM32标准库的FreeRTOS移植与任务创建
数据库·stm32·嵌入式硬件·freertos
炸膛坦客18 天前
FreeRTOS 学习:(十七)“外部中断”和“内核中断”的差异,引入 FreeRTOS 中断管理
stm32·freertos·实时操作系统
顾晨阳——22 天前
MQTT协议
mqtt·tcp·嵌入式软件