本人在运行ucos时遇到一个非常奇怪的问题,运行一段时间后就会莫名进入hardfault函数,导致系统死机。后来根据对堆栈调试,发现每次调用的函数都不一样,甚是费解。通过map文件最后得出结论,原来在系统初始化的时候在flash里面读出了系统配置参数,在系统运行过程中会写flash,而flash定义的地址与程序代码存储的位置发生了重叠,一写数据就擦掉了一些函数,当调用到这些函数的时候就会发生未知指令的错误。把这个参数存储地址定义的分开些就会解决这个问题。可是,开始这个地址写好了,随着程序代码不断增多,消耗的片上flash也会增大,是个动态增长的过程,不注意很有可能发生冲突。所以在项目开发过程中定期检查定义的参数存储地址,或者干脆把参数存储地址定义在程序地址之前。
今天详细了解一下编译后的STM32工程,堆栈内存分布情况,有助于对堆栈大小分配的理解。打开一个基于STM32f103RET6的工程,具有512KB 内置flash,以及64KB SRAM,通过map文件可以看出:
名称 | 位置 | 地址 | 备注 |
RESET 复位向量 | Flash | 0x08000000 | 上电执行的第一条代码 |
库函数代码段 | Flash | 0x08000144 | 在程序中调用的库函数,例如字符串处理函数、内存分配函数等 |
用户自定义函数代码段 | Flash | 0x08001110 | 工程模板函数库、用户自定义函数编译后的代码,以函数名首字母排序 |
.constdata | Flash | 0x0800d07c-0x0800d680 | 用户定义的常量 |
剩余空间 | Flash |
|
|
名称 | 位置 | 地址 | 备注 |
.data | SRAM | 0x20000000 | 数据段,以及初始化的全局变量 |
.bss | SRAM | 0x20000268 | 未初始化的全局变量 |
HEAP(堆) | SRAM | 0x200033e8 | 启动文件定义的堆空间开始,程序调用malloc自由分配的内存在堆上 |
STACK(栈) | SRAM | 0x200073e8 | 启动文件定义的栈空间开始,各个函数中的局部变量空间分配到栈上 |
剩余空间 | SRAM |
|
|
例如在这个工程中,flash自定义参数存储地址,不要定义在 0x0800d680之前。
另外,还可以看出在SRAM里,分配存储的是全局变量区,未初始化变量区,堆以及栈。要注意的是,如果堆和栈定义的过小,程序默认定义都不大,一旦使用了一个较大的局部变量,有可能造成栈空间溢出,覆盖掉堆空间甚至上面的全局变量区,造成系统出错的问题。例如在做IAP的过程中,每当向flash写入512个字节时,由于大容量STM32片上flash块大小为2K,写之前要先读出,调用写函数的时候就自动创建一个2K大小的局部变量,由于栈是向上增长的,自然会覆盖堆以及全局变量区,造成未知的错误。根据片上SRAM的资源,将堆和栈适当调大一些为好,比如各设置为4K大小。
关键字:STM32 内存分布
引用地址:
STM32 内存分布探究
推荐阅读最新更新时间:2024-03-16 15:38
stm32+fpga架构的运动控制器
因为fpga的高速、高同步、纯硬件的特点,可以很好的实现多轴的同步和单轴任意频率脉冲的生成,远远比stm32自带的定时器好用。结合f407的高性能,高可靠,方便的开发环境,可以组合在一起做成类似dsp+fpga的运动卡,但是价格低廉,用户入门容易。 Stm32采用stm32f407,不扩展内存sram,外部fpga采用ep4ce6,引脚采用多的那种(黑金的那种),板子上使用rtc电池,用来保持断电保护的sram内容。 stm32板子支持以太网,mac使用f407自带的mac器件。 支持usb,232c,485,can通讯。 usb用来实现和pc机的连接,232c和485则可以使用modbus-rtu协议,以太网则实现eco
[单片机]
stm32 接收蓝牙(uart)等设备命令的处理
方法有两种: 方法1:查询法 static void BT_RX_Handler(void) { u8 data = USART_ReceiveData(USART2); if((BT_Buf_Status & 0x80) == 0) /* not complete */ { if(BT_Buf_Status & 0x40) { BT_RcvBuf = data; BT_RecCur++; if((data == 0xEC) && (8 == BT_RecCur)) //if((data == 0xEC)) { BT_Buf_Status |= (1 7); /* comple
[单片机]
基于STM32的MS5540c压强温度传感器的应用
3.5的库函数,stm32f10x系列的mcu,网上这个芯片的实例较少,而官方的代码an510这个文档找不到下载,datasheet写的也不甚明了。下面贴上我的基本程序给大家一个参考: #include main.h #include Flash_LED.h #include SPI_MS5540C.h #include SysTick.h vu32 led_timer = 0; extern vu32 global_timer; uint8_t detect_timer=0; vu16 var_D1=0,var_D2=0; int main() { SystemInit(); NVIC_SetVectorTable(NVIC
[单片机]
关于STM32的基本知识
STM32简介 STM32是“意法半导体”生产的基于“ARM公司Cortex-M3内核”的32位高性能MCU。 ST——芯片制造商意法半导体,SOC厂商 ARM——IP厂商,负责芯片内核设计的公司 M——Microelectronics的缩写,指微控制器 32——指它是一个32位的微控制器 注意:51单片机是5V工作电压,而STM32是3.3V工作电压。STM32芯片结构,如下图所示。 STM32和ARM7的关系 ARM7和STM32的内核都是由ARM公司设计的。ARM7内核采用的是冯诺依曼结构(也就是计算机CPU采用的结构)而STM32采用的是哈佛结构。STM32是ARM公司设计出来取代ARM7的,所以它的性能优于ARM7。
[单片机]
STM32单片机(10) 数码管输出实验[补] 静态(共阳)+动态(共阴)
注:使用普中科技开发板测试时,需要拔掉Boot1插口 参考手册、电路图等参见 STM32单片机学习(1) 总记 学习资料+参考手册+LED灯 静态数码管实验 /******************************************************************************* * * 软件功能: 静态数码管实验(软件延时方式) * *******************************************************************************/ #include stm32f10x.h #include de
[单片机]
STM32学习笔记一:选型与引脚说明
选型分类 STM32命名方法 如何分配原理图引脚 如何寺找引脚的功能说明 引脚功能解读
[单片机]
stm32中core_m3.h和core_m3.c详解
CMSIS是Cortex微控制器软件接口标准(Cortex MicroController Software Interface Standard)的缩写,这个是ARM定制的一个用于Cortex-M系列的一个标准,主要是为了提供通用api接口来访问内核和一些片上外设,提高代码的可移植性。 CMSIS有三个层:核内外设访问层Core Peripheral Access Layer(CPAL),中间件访问层Middleware Access Layer(MWAL),设备访问层(Device Peripheral Access Layer)。 CPAL用于访问内核的寄存器和组件,如NVIC,调试系统等。该层是由ARM实现的。 M
[单片机]
STM32 FSMC操作SRAM的步骤简析
本次操作的SRAM的型号是IS62WV51216,是高速,8M位静态SRAM。它采用ISSI(Intergrated Silicon Solution, Inc)公司的高性能CMOS技术,按照512K个字(16)位进行组织存储单元。其具有高性能、低功耗特点。为方便用户扩展SRAM的存储空间,为用户有提供了两个片选引脚;此外,含有两个字节控制信号UB和LB,可方便用户按字节访问SRAM或按字访问SRAM。IS62WV51216具有45ns/55ns访问速度,因为是全静态操作,因此无需外部时钟和刷新要求。 IS62WV51216功能框图 IS62WV51216有地址译码器、数据IO、控制逻辑和存储阵列四部分构成。地址译码器将1
[单片机]