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


相关推荐
Zeku1 小时前
20251127 - 韦东山Linux - 通用Makefile解析
linux·驱动开发·嵌入式软件·linux应用开发
inputA2 小时前
【rt-thread】点灯实验和按键输入实验
c语言·笔记·学习·实时操作系统
离凌寒18 小时前
一、基于freertos下对LAN8720模块进行通信测试
网络·freertos
dreamczf2 天前
如何确定项目中的产品选型-物联网设备
单片机·物联网·嵌入式软件
charlie1145141915 天前
在上位机上熟悉FreeRTOS API
笔记·学习·嵌入式·c·freertos·工程
拍浪人5 天前
使用寄存器点亮LED
stm32·嵌入式软件
飞来客isdn6 天前
GD32F407ZGT6在FreeRTOS下串口中断接收异常情况及解决方法
单片机·mcu·freertos·信息与通信
俊俊谢6 天前
华大HC32F460配置JTAG调试引脚为普通GPIO(PB03、PA15等)
嵌入式硬件·嵌入式·arm·嵌入式软件·hc32f460
唐僧洗头爱飘柔95277 天前
【软考:程序员(01)】如何考得程序员证书?本片知识点:操作系统基本概念、操作系统的分类、进程管理、三态模型、信号量机制、同步与互斥模型
程序员·软考·实时操作系统·信号量机制·批处理操作系统·三态模型·同步与互斥模型
离凌寒7 天前
一、在freertos上使用esp01s模块并配置使用sta模式进行数据通信传输测试。
单片机·freertos·esp01s