深入解析stm32f407参考手册——启动模式
原标题:深入解析stm32f407参考手册——启动模式
系统上电之后,会检测两个引脚的状态,一个被标注为BOOT0;另一个是一个通用IO引脚,在是stm32f407zgt6就是PB2,但是在启动的时候作为启动模式的选择引脚BOOT1。
不同设备的启动引脚定义不同,请参考具体设备的规格书
这两个引脚在启动时其上施加的电平状态,在启动时候被采样,从而确定设备的启动模式,精确点说是在内部系统时钟SYSCLK在启动后第4个上升沿进行采样锁存。
所谓上升沿,就是低电平转换成高电平时的那段斜坡
采样完成后,这两个引脚系统就不会在乎它们的状态了,此时BOOT1那个引脚又可以作为一个通用IO引脚。只要系统上电,这个过程就自动执行了,不需要特地做一些设置。又由于SYSCLK第4个上升沿几乎是在开机一瞬间就到了,所以我们可以认为,这就是设备在启动刹那就已经确定了启动模式。
那么启动模式又是什么呢?为了弄明白这个问题,我们先来了解一些事情。通过上一回讲解,我们知道在整个系统中所有系统和内存都被编址到一个4GB的空间内,包括系统代码。代码区定义在地址0x0000 0000开始。一般我们将程序烧写在内部Flash存储器,而系统通过Flash接口的ICode和DCode总线进行访问的。处理器总是通过ICode总线来获取复位向量,我们大概可以理解成复位后启动代码和其入口地址。这也意味着启动引导空间只能在代码区。
stm32f4就是通过BOOT引脚的定义来选择三种不同的启动模式
这张表就说明了启动模式的选择,通常我们选择模式1,既BOOT0为0——也就是外部施加低电平。在这个状态下,BOOT1的状态被无视了,Flash被选择为启动引导区,这是我们最常用的一个模式。内部Flash存储器起始地址为0x0800 0000,在模式1中系统会自动映射0x0800 0000到地址0x0000 0000。我们既可以从0x0000 0000来进行Flash访问,也可以在0x0800 0000访问。
Flash的访问由Flash接口进行擦除和编程操作,它管理着CPU通过AHB的ICode和DCode总线对Flash的访问,并执行读写保护机制。Flash接口还通过指令预取和缓存来加速代码执行。Flash存储器组织如下:
主存储器块被划分为数个扇区
设备在启动模式2中启动的系统存储器(也就是内置启动引导程序的存储区域)
512字节用户数据OTP
选项字节,用于配置读写保护、BOR 级别、软件/硬件看门狗以及器件处于待机或停止模式下的复位
模式2是当BOOT0置1时,BOOT置0进行选择。这个模式有点复杂,因为它不是为了系统启动后为了顺利运行程序,而是为了下载程序。通常我们通过ST-LINK或者J-LINK等接口下载程序。而模式2将一块系统存储器的地址0x1fff 0000映射到了启动地址0x0000 0000,这里的系统存储器里面写了一段芯片出厂时就有的启动引导程序(称之为ISP程序),我们既不能读取它,也不能改写它,只能在该模式启动后系统自动去执行它。这段启动引导程序启动后通过使用以下串行接口之一对内部Flash存储器进行重新编程:
USART1(PA9/PA10)
USART3(PB10/11或PC10/11)
CAN2(PB5/13)
设备模式中的USB OTG FS(PA11/12)
以上USART运行于内部的一个16MHz振荡器(简称HSI),而CAN和USB OTG FS需要一个1MHz整数倍的外部时钟(范围在4~26MHz,简称HSE)。程序下载完成后需要硬件复位,并且启动前还是需要把BOOT引脚设置为模式1,一般需要手动或者外围逻辑电路进行模式切换。
模式3时把SRAM1的起始地址0x2000 0000映射到https://zhuanlan.zhihu.com/drafts了地址0x0000 0000。此时系统确实从SRAM1中开始运行,所以需要把NVIC异常向量表和偏移寄存器重新定位到SRAM中去。由于SRAM在系统断电后就丢失所有数据,一般这种模式只用于调试。
stm32f40xx带有4K字节的备份SRAM,和192K字节的系统SRAM。系统SRAM可按字节、半字(16位)、全字(32位)访问。可以CPU速度进行读写,所以CPU访问SRAM是没有等待周期的。系统SRAM分为:
起始地址0x2000 0000的SRAM1,大小112K字节,所有AHB总线主控设备可访问
起始地址0x2001 C000的SRAM2,大小16K字节,所有AHB总线主控设备可访问
起始地址0x1000 0000的CCM,大小64K字节,仅CPU能通过D-BUS总线进行访问
前两个AHB总线可进行并发访问(注意!是总线并发,而不是SRAM并发),比如比如CPU通过AHB在访问112K的SRAM,此时以太网还能通过AHB对16K进行访问。在选择启动模式3的时候,CPU可通过ICode和DCode进行SRAM访问。
最后我们要讨论一下物理重映射。BOOT引脚状态确定以后,应用程序可以将某些存储器设置位从代码空间0x0000 0000进行访问,如此我们便可使用更高效的ICode代替系统总线进行访问。通过修改SYSCFG控制器中的SYSCFG_MEMRMP寄存器来实现,这个寄存器顾名思义,直译就是内存重映射寄存器。stm32中的寄存器大部分是32位的,这个SYSCFG_MEMRMP寄存器也是如此,只是这个寄存器只有最低两位是有用的,其他位都是保留位,如下所示:
最低两位的取值决定了重映射的存储器,由于0x0000 0000是由启动时BOOT引脚状态已经定义了的,为了能够将其他存储器映射到这个地址,这两位的设置可以屏蔽BOOT引脚设置的状态。
MEM__MODE[1:0]位的设置:
00、主Flash映射到地址0x0000 0000
01、系统Flash映射到地址0x0000 0000
10、FSMC Bank1(NOR/PSRAM 1和2)映射到地址0x0000 0000
11、SRAM(112K字节)映射到地址0x0000 0000
不同映射后的内存地址如下表:
最左边的是内存中的线性地址,右边每一列都是在选择某个存储器映射到代码区后的内存布局。可以看到在地址0x0000 0000在不同的映射下对应了不同的存储器,而其他地址布局则不变。
关于地址映射,就不得不提一下位带。这个概念的最直白的解释就是在地址空间里有两个非常特殊的区域,其中的每个位,都能在其他地方代表一个字(32位)。被映射的字称为别名区,在这些别名区进行整字写入时,相当于对位带区域相应位进行读-修改-写操作流程。在stm32f4系列,外设寄存器和SRAM都被映射到一个位带区域,这样可实现单个位带区域读写操作。这些操作仅适用于CPU进行访问,其他AHB总线主设备就不可以这样访问了。
位带映射可通过一个公式来说明:
bit_word_addr = bit_band_base+(byte_offset * 32)+(bit_number * 4)
bit_word_addr —— 别名区域中将映射到目标位的字的地址
bit_band_base —— 别名区域的起始地址
byte_offset —— 目标位所在位段区域中的字节编号
bit_number —— 目标位的位位置 (0-7)
举个例子:我们将SRAM的位带区地址0x2000 0300处字节的第2位映射到别名区:
0x2200 6008 = 0x2200 0000 +(0x300 * 32)+(2 *4)
上式左边既是别名区的地址,而右边则是位带区位地址的计算方式,最终我们得到了别名区地址是0x2200 6008。当对别名区进行读操作,返回的将是位带区该位的值。而写别名区的操作相当于对位带区的位进行读-修改-写操作。
责任编辑:David
【免责声明】
1、本文内容、数据、图表等来源于网络引用或其他公开资料,版权归属原作者、原发表出处。若版权所有方对本文的引用持有异议,请联系拍明芯城(marketing@iczoom.com),本方将及时处理。
2、本文的引用仅供读者交流学习使用,不涉及商业目的。
3、本文内容仅代表作者观点,拍明芯城不对内容的准确性、可靠性或完整性提供明示或暗示的保证。读者阅读本文后做出的决定或行为,是基于自主意愿和独立判断做出的,请读者明确相关结果。
4、如需转载本方拥有版权的文章,请联系拍明芯城(marketing@iczoom.com)注明“转载原因”。未经允许私自转载拍明芯城将保留追究其法律责任的权利。
拍明芯城拥有对此声明的最终解释权。