STM32 存储器与堆栈问题

发布者:zeta16最新更新时间:2018-06-05 来源: eefocus关键字:STM32  存储器  堆栈 手机看文章 扫描二维码
随时随地手机看文章

首先我们先来看下stm32的系统架构: 
这里写图片描述 
可以看出四个驱动单元:D-bus,S-bus,DMA1,DMA2。四个被动单元:SRAM,Flash,FSMC(这块我是以stm32f103zet6来写的,有些32芯片没有这个接口,AHB到APB以及连接的APB设备) 
再来看下存储器映射 
这里写图片描述
可以看出flash起始地址为0x0800 0000,SRAM起始地址为0x20000000,外设映射起始地址为0x4000000,再次看到第8块512M的存储器,0xE0000000地址为向量中断控制器的起始地址,查看《crotex-m3权威指南》可以了解到,这个地址在操作系统移植也很重要。 
接下来讲BSS段,数据段,代码段,堆,栈 
BSS段:(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。 
数据段 :数据段(data segment)通常是指用来存放程序中 已初始化 的 全局变量 的一块内存区域。数据段属于静态内存分配。 
代码段: 代码段(code segment/text segment)通常是指用来存放 程序执行代码 的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于 只读 , 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些 只读的常数变量 ,例如字符串常量等。程序段为程序代码在内存中的映射.一个程序可以在内存中多有个副本. 
堆(heap) :堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc/free等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张)/释放的内存从堆中被剔除(堆被缩减) 
栈(stack) :栈又称堆栈, 存放程序的 局部变量 (但不包括static声明的变量, static 意味着 在数据段中 存放变量)。除此以外,在函数被调用时,栈用来传递参数和返回值。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。储动态内存分配,需要程序员手工分配,手工释放。 
我就先栈的问题来说下stm32注意的事项:我们可以startup_stm32f10x_hd.s文件看到Stack_Size EQU 0x00000400栈空间。下面举例说明: 
static void StackOverflowTest(void) 

int16_t i; 
uint8_t buf[2048]; 
(void)buf; 
1. 为了能够模拟任务栈溢出,并触发任务栈溢出函数,这里强烈建议使用数组的时候逆着赋值。 
因为对于M3和M4内核的MCU,堆栈生长方向是向下生长的满栈。即高地址是buf[2047], 低地址 
是buf[0]。如果任务栈溢出了,也是从高地址buf[2047]到buf[0]的某个地址开始溢出。 
因此,如果用户直接修改的是buf[0]开始的数据且这些溢出部分的数据比较重要,会直接导致 
进入到硬件异常。 
2. 栈溢出检测是在任务切换的时候执行的,我们这里加个延迟函数,防止修改了重要的数据导致直接 
进入硬件异常。 
3. 任务vTaskTaskUserIF的栈空间大小是2048字节,在此任务的入口已经申请了栈空间大小 
——uint8_t ucKeyCode; 
——uint8_t pcWriteBuffer[500]; 
这里再申请如下这么大的栈空间 
——-int16_t i; 
——-uint8_t buf[2048]; 
必定溢出。 
for(i = 2047; i >= 0; i–) 

buf[i] = 0x55; 
vTaskDelay(1); 


我当初看到这里,感触还是挺多的。 
接着堆Heap_Size EQU 0x00000200 
注意这里的考虑大小端模式还有static,malloc,的知识点,stm32为小端模式,static静态存储空间,不需要用户释放,程序结束自动释放,而malloc需要用户释放,避免发生内存泄漏问题。 
再来看下flash: 
小容量产品主存储块1-32KB, 每页1KB。系统存储器2KB。 
中容量产品主存储块64-128KB, 每页1KB。系统存储器2KB。 
大容量产品主存储块256KB以上, 每页2KB。系统存储器2KB。 
互联型产品主存储块256KB以上, 每页2KB。系统存储器18KB。 
注意到每页多大,对IAP的编写很重要,当然做bootloader的时候注意向量表偏移量寄存器。SCB->VTOR,写到这又想起了DMA的FIFO这个对于做stm32也是必须的,其中很多的资料的这点感觉每个做stm32的都必须掌握。 
接着我最近看到了很多之前没了解到的,也拿出来记录一下: 
Cortex-M3,这种内核支持许多屏蔽指令。在下一个指令或者事件开始执行以前,这些屏蔽指令常常用于确保必然事件执行完成。 
在处理器内部,指令同步屏蔽(ISB)刷新流水线;以致于这个指令执行完以后,紧接着从缓存或者存储器取出指令表。这个表会改变这个系统,例如MPU立即生效。 
数据同步屏蔽(DSB)指令作为一种特殊的存储器屏蔽指令。访问外部存储器操作完成之前,执行完成数据同步屏蔽指令(DSB)。执行数据同步屏蔽指令,在该指令没有完成以前不再执行任何指令——换句话说,执行完成所有的挂起操作。 
数据存储屏蔽(DMB)指令作为一种存储器屏蔽指令。数据存储屏蔽(DMB)指令和数据同步屏蔽(DSB)指令有微小的差别。数据存储屏蔽(DMB)指令确保:数据同步屏蔽(DSB)指令执行完成之前,访问任意存储器;执行数据同步屏蔽(DSB)指令后,紧接着执行访问任意存储器操作。 
当然还有影子寄存器。 
好了,感觉自己写到差不多了,有什么不对的地方,请大家提出了,毕竟自己第二次写博客,什么都不懂,也就感觉对自己有用,就记录下来。

关键字:STM32  存储器  堆栈 引用地址:STM32 存储器与堆栈问题

上一篇:stm32的学习之存储器和总线架构
下一篇: STM32F1xxx存储器和总线架构

推荐阅读最新更新时间:2024-03-16 16:04

STM32单片机的学习经验
随便写写,关于stm32 最近在学习stm32,写点东西,虽然简单,但都是原创啊 开发板是前辈画的,好像是用来测试一个3G功能的,不过对于我来说太远;我要来了3个,自己焊了一个最小系统,好在公司资源还是不错的,器件芯片有,还可以问问前辈--对公司还是比较满意的,虽然工资少了点,但学东西第一位O( _ )O~。 最开始当然是建工程了,这个真不太会,前前后后竟用了一周(时间真长,别见笑啊),上网查资料, 问前辈,自己琢磨。。。总算搞定,然后从GPIO开始学,开始还真没什么头绪(虽然在大学学点51,但完全没有真正应用,顶多是跑马灯实验),开始纠结是从寄存器开始学还是从库函数开始学,后来看到一句 用库函数入门,用寄存器提高 于是
[单片机]
STM32 FLASH擦除、写入以及防止误擦除程序代码
编译环境:(Keil)MDK4.72.10 stm32库版本:STM32F10x_StdPeriph_Driver_3.5.0 一、本文不对FLASH的基础知识做详细的介绍,不懂得地方请查阅有关资料。   对STM32 内部FLASH进行编程操作,需要遵循以下流程:   1、FLASH解锁;   2、清除相关标志位;   3、擦除FLASH(先擦除后写入的原因是为了工业上制作方便,即物理实现方便);   4、写入FLASH;   5、锁定FLASH; 实例: #define FLASH_PAGE_SIZE ((uint16_t)0x400) //如果一页为1K大小 #define WRITE_START_ADDR ((uin
[单片机]
<font color='red'>STM32</font> FLASH擦除、写入以及防止误擦除程序代码
stm32 嵌套向量中断控制器NVIC
嵌套向量中断控制器(NVIC)和处理器核的接口紧密相连,可以实现低延迟的中断处理和高效地处理晚到的中断。 嵌套向量中断控制器管理着包括内核异常等中断 NVIC 相关的函数包含在 misc.c 文件中 void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) void NVIC_SystemLPConfig(uint8_t LowPower
[单片机]
<font color='red'>stm32</font> 嵌套向量中断控制器NVIC
STM32固件解密步骤
方法1:代码解密 FLASH_OBProgramInitTypeDef OBInit; __HAL_FLASH_PREFETCH_BUFFER_DISABLE(); HAL_FLASHEx_OBGetConfig(&OBInit); if(OBInit.RDPLevel != OB_RDP_LEVEL_0) { OBInit.OptionType = OPTIONBYTE_RDP; OBInit.RDPLevel = OB_RDP_LEVEL_0; (void)HAL_FLASH_Unlock(); (void)HAL_FLASH_OB_Unlock(); (void)HAL_FLASHEx_OBProgram(&OBInit
[单片机]
案例说明stm32官方库函数使用方法 (库版本v3.5, Keil MDK 5)
stm32的官方库非常方便,但是里面的使用手册是英文的,而且也没有很详细的使用说明,对新手来说入门比较困难,而且网上现存的教程要么是针对v2.x的库的,要么是针对keil 4.x的,这两个东西更新后差别都蛮大。有新的可用为何不用最新的呢? 一: 用keil 5构建模板工程。在keil顶部选Project- New uVision Project, 输入工程名称,进入device选择界面。注意,因为keil 5变成了在线安装Package的模式(即刚安装好软件并不附带各种芯片的包,用哪个下哪个),如果你已经安装了ST的Package,不要用那个Package!!Keil 5暂时不兼容官方库,如果用了的话编译会报错。解决方案:1.
[单片机]
STM32 DMA使用详解
DMA部分我用到的相对简单,当然,可能这是新东西,我暂时还用不到它的复杂功能吧。下面用问答的形式表达我的思路。 DMA有什么用? 直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。 有多少个DMA资源? 有两个DMA控制器,DMA1有7个通道,DMA2有5个通道。 数据从什么地方送到什么地方? 外设到SRAM(I2C/UART等获取数据并送入SRAM); SRAM的两个区域之间; 外设到外设(ADC读取数据后送到TIM1控制其产生不同的PWM占空比); SRAM到外
[单片机]
<font color='red'>STM32</font> DMA使用详解
使用STM32调试FMSDR模块及解调FM电台(3)
3. 调试8027使其发出单音FM信号 3.1 输出24Mhz和验证I2C接口 1. 硬件连接 将FM_SDR板卡和STM32H750开发板连接。 本文中所有例子中我们都仅给MSI001使用天线,因为QN8027离得很近,发射端不需要使用天线 本程序中操作的管脚如下描述: 2. PWM输出24MHz QN8027芯片需要输入24MHz的时钟作为参考信号,在这里通过STM32H750的TIMER2产生24M的方波,提供给QN8027作为输入参考信号。 PWM信号的关键参数是频率和占空比,我们分别看一下如何设定TIM2来确定输出PWM的频率和占空比: PWM的输出频率=计数器计数频率/(计数器的计数上限+1),计数器计数频
[单片机]
使用<font color='red'>STM32</font>调试FMSDR模块及解调FM电台(3)
SD NAND在STM32应用上的保姆级教程
SD NAND与正点原子精英板的连接 由于正点原子精英板没有SD NAND接口,只有TF卡接口,所以SD NAND需要用到转接板来连接。 SD NAND正常运行现象 本次实验的程序是正点原子的SD卡实验例程,先用读卡器把SD NAND接到电脑上,并复制一个文件进去,再插到开发板上; 用送的数据线连接USB UART接口,下载好程序,打开电脑上的串口助手,按下KEY0,即可读取到数据, 具体实验步骤和现象可以看例程文件夹中的readme, 另外LED-DS0闪烁也表示SD NAND芯片在正常运行, SD NAND芯片用的是MK-米客方德的工业级芯片MKDV1GIL-AS;MK-米客方德家还有其他各种型号的SD NAN
[单片机]
SD NAND在<font color='red'>STM32</font>应用上的保姆级教程
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved