对STM32栈的理解Stack_Size EQU 0x00000400

STM32的Stack_SizeEQU0x00000400表示栈大小为1024字节,用于存储局部变量和函数调用信息。文章讨论了栈、堆、全局区、文字常量区和程序代码区等内存区域,强调了栈的动态分配和后进先出特性。此外,还提到了如何通过不同方式定位内存中的变量,以及变量在RAM和Flash中的存储位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


本人主要为个人参考网络及个人总结而来比较,如有雷同请告知,即刻删除
以下引用网上资料 理解堆和栈的区别

(1)栈区(stack):由编译器自动分配和释放,存放函数的参数值、局部变量的值等,其操作方式类似
于数据结构中的栈,用于局部变量,函数调时现场保护和返回地址,函数的形参等。
(2)堆区(heap):一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。分配
方式类似于数据结构中的链表,用于动态内存分配,如malloc,calloc,realloc等函数分配的变量空间是在堆上。
(3)全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态
变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系
统自动释放。
(4)文字常量区:常量字符串就是存放在这里的。
(5)程序代码区:存放函数体的二进制代码。

Stack_Size EQU 0x00000400表示什么意思

0x00000400(0x400)十六进制转换为十进制是为 1k=1024Byte (字节)
表示:栈大小是1024字节,即局部变量不能大于1024字节
例如:局部变量例如u8 temp[4000]; 那么启动文件的栈应该修改为Stack_Size EQU0x00001000 ,此时栈是4096字节
栈是什么:栈stack是一块程序运行时用来存储临时变量的内存RAM空间。栈一般静态分配,并且后进先出,栈的生命周期从程序的起始直到程序结束。一个函数返回,其用到的栈空间就被释放给后续函数使用
详细的分析看这篇博客:
STM32栈stack 堆栈 注意事项 Stack_Size EQU 0x00000400

可以通过查找flash内存的方式定位存储

1.flash

详细的分析看这篇博客:
STM32 内存分配、堆栈以及变量存储位置理解与分析

#include "sys.h"
#include "delay.h"
#include "usart.h"	

const int DATA1= 100; //一个常量

int DATA2=0x1010;//一个有初始值的全局变量

int main(void)
{ 
	delay_init(500);		  //初始化延时函数
	LED_Init();		        //初始化LED端口
	uart_init(9600);

	printf("%p\r\n",&DATA1);
	printf("%p\r\n",&DATA2);
	while(1)
	{                   
	}
}

1.可以通过 printf(“%p\r\n”,&DATA2);//打印地址
2.通过MAP文件查找
3.直接通过ST-LINK Utility软件直接查看芯片的flash。先定位到DATA1所在的地址

2.RAM内部

在这里插入图片描述
比较关键的点:
1、data : 存放初始化为非 0 值的全局变量
2、bss : 存放未初始化或者是初始化为 0 的全局变量
3、堆 (heap) : 由 malloc 申请,由 free 释放
4、栈 (Stack) : 存放局部变量和函数调用时的返回地址
详细的分析看这篇博客:
STM32 内存分配解析及变量的存储位置
看例子:

#include <stdio.h>
#include <stdlib.h>
int data_var = 500;//已经初始化的全局变量,存放在RAM中的data区
int bss_var0;//未初始化的全局变量,存放在RAM中的bss数据中
int bss_var1 = 0;//初始化为0的全局变量,存放在RAM中的bss数据中
static int static_var;//RAM的bss

void my_function(void)
{
	static int static_var1 = 0;//RAM的bss静态初始化区
	int stack = 0;//存RAM放栈中
	char s[]="abc";   //栈
    char *p3= "1234567";   //在文字常量区Flash
	char *buffer;//存放栈中
	const int value = 1;//只读,存RAM放栈中,并不是所有用 const 修饰的变量都是存放于只读变量区的
	buffer = malloc(10);//存放堆
	strcpy(p1,"123456");   //"123456"放在常量区
}
<think>嗯,用户问的是关于STM32F103RCT6的stack_size设置多少合适。首先,我需要回忆一下STM32的堆设置相关知识。STM32的启动文件里通常有Stack_Size和Heap_Size的定义,用户可能是在使用Keil或者IAR这样的IDE,在配置启动文件的时候遇到了这个问题。 首先,Stack_Size的作用是给程序中的局部变量、函数调用保存的返回地址、寄存器等使用的内存空间。如果设置得太小,可能会导致溢出,进而引发各种奇怪的问题,比如程序跑飞或者HardFault。所以设置合适的大小很重要。 STM32F103RCT6属于中等容量的型号,有48KB的SRAM。一般来说,对于大多数应用,大小设置在1KB到2KB之间可能足够。比如简单的控制应用,没有大量递归或者深度函数调用的情况。但如果是用了RTOS,或者有较多的任务切换,可能需要更大的空间。此外,如果使用了一些库函数,比如printf,或者有较大的局部数组,也会消耗较多空间。 需要提醒用户的是,的大小没有统一的标准,需要根据具体的应用来分析。可以通过调试工具来查看的使用情况,比如Keil的编译完成后会有一个map文件,里面会显示的最大使用量。或者通过填充空间并在运行时检查指针的位置,估算实际需要的大小。 另外,可能用户对堆和的区别不太清楚,需要简单说明一下。堆用于动态内存分配,而是用于函数调用和局部变量。两者的设置都需要根据应用来调整。 还要考虑到中断服务程序对的影响。中断发生时,当前的上下文会被压入中,如果中断嵌套较多,的使用量会增加。这时候可能需要更大的空间。 总结来说,建议用户从默认的1KB开始测试,然后根据实际运行情况调整,通过工具分析的使用量,确保有足够的余量,避免溢出。如果出现异常,可以考虑逐步增加的大小,同时优化代码,减少不必要的局部变量使用,或者将大数组移到全局存储区。</think>关于STM32F103RCT6的Stack_Size设置,建议从以下角度考虑: 1. **基础参考值** 默认启动文件(如startup_stm32f103xe.s)通常设置: ``` Stack_Size EQU 0x00000400 ; 1KB (1024字节) ``` 对于简单裸机程序(如LED控制、按键检测),此配置基本足够 2. **关键影响因素** 需增大空间的情况: - 使用RTOS(如FreeRTOS)时,每个任务需独立空间(通常2KB起) - 存在深度函数调用(例如递归算法) - 使用大体积局部变量(如`uint8_t buffer[512]`) - 频繁使用printf等格式化输出函数 - 中断嵌套层级较多 3. **调试检测方法** (1)编译后查看MAP文件中的最大消耗预估 (2)使用Keil的运行时检测功能: ```c extern uint32_t Image$$STACK$$ZI$$Limit; // 顶部地址 extern uint32_t __initial_sp; // 初始指针 void check_stack() { uint32_t used = __initial_sp - (uint32_t)&Image$$STACK$$ZI$$Limit; printf("Stack used: %d bytes\n", used); } ``` (3)填充魔数检测法(在启动阶段填充区域特定值,运行后检查被覆盖区域) 4. **典型场景建议** | 应用场景 | 推荐Stack_Size | 说明 | |---------------------|---------------|--------------------------------| | 简单裸机控制 | 1KB-1.5KB | GPIO操作、定时器基础应用 | | 串口通信协议解析 | 1.5KB-2KB | 含Modbus、自定义协议解析 | | 文件系统(FATFS) | 2KB-3KB | SD卡读写操作 | | FreeRTOS主任务 | 3KB-4KB | 含TCP/IP协议等复杂应用 | | 图形界面(LVGL) | 4KB+ | 需结合显存分配情况调整 | 5. **优化建议** - 将大数组改为`static`或全局变量 - 减少函数调用层级深度 - 使用`-fstack-usage`编译选项生成使用报告 - 保留至少20%的余量应对突发需求 ▶ 实际案例: 某工业控制器项目配置(基于STM32F103RCT6): ```assembly Stack_Size EQU 0x00000C00 ; 3KB Heap_Size EQU 0x00000200 ; 512B ``` 该配置满足以下需求: - FreeRTOS运行3个任务(通信/控制/显示) - 包含Modbus RTU协议 - 使用LVGL图形界面 - 通过SWD接口定期监测使用率 建议通过实际测试最终确定最佳值,可使用以下代码片段监测实时使用: ```c // 在RTOS任务中定期调用 void TaskMonitor(void *argument) { UBaseType_t uxHighWaterMark; for(;;) { uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL); printf("Remaining stack: %d bytes\n", uxHighWaterMark * sizeof(StackType_t)); vTaskDelay(pdMS_TO_TICKS(1000)); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值