STM32启动分析
STM32启动方式
STM32不仅可以从FLASH上启动,还可以从SRAM上启动,也可以从系统存储器启动,由BOOT0和BOOT1引脚确定,其对应启动模式如表所示:
单片机复位后,在SYSCLK的第四个上升沿锁存BOOT引脚的值,以确定启动模式。
在确定启动模式后,会对地址空间进行映射,对于flash启动 0x0800 0000会映射到0x0000 0000。SRAM启动 0x2000 0000会映射到0x0000 0000。系统存储器0x1FFFB000会映射到0x0000 0000。比如SRAM启动:
复位序列
在离开复位状态后,CM4做的第一件事是读取下列两个32位整数的值:
-
从地址0x0000 0000处取出MSP的初始值。
-
从地址0x0000 0004处取出PC的初始值–这个值是复位向量,LSB必须是1,然后从这个值所对应的地址处取值。
-
请注意,这与传统的ARM架构不同——其实也和绝大多数的其他单片机不同。传统的ARM架构总是从0地址开始执行第一条指令,它们的0地址处总是一条跳转指令。在CM3、CM4中,0地址提供MSP的初始值,然后就是向量表(向量表在以后还可以被移至其它位置)。向量表中的数值是32位的地址,而不是跳转指令。向量表的第一个条目指向复位后应执行的第一条指令。
因为CM4与CM3使用的是向下生长的满栈,所以MSP的初始值必须是堆栈内存的末地址加1。举例来说,如果你的堆栈区域在0x2000 7C00——0X2000 7FFF之间,那么MSP的初始值就必须是0x2000 8000。
向量表跟随在MSP的初始值之后——也就是第2个表目。要注意因为CM3是在Thumb态下执行,所以向量表中的每个数值都必须把LSB置1(也就是奇数),倘若写了0,则视为企图转入ARM模式,CM3将产生一个fault异常。(源自Coretex M3权威指南,如下图)
正是因为这个原因,图3.18中使用0x101来表达地址0x100。当0x100处的指令得到执行后,就正式开始了程序的执行。在此之前初始化MSP是必须的,因为可能第1条指令还没执行就会被NMI或是其他fault打断。MSP初始化后就已经为他们的服务例程准备好了堆栈。
上述过程由内核自动设置运行环境并执行主体程序,因此它被称为自举过程。
在STM32启动配置中有一个小提示:引脚模式设置为Flash,但设置为从SRAM中启动,需要重新设置中断向量表,中断向量表的设置是用户在用户程序中自己实现的!!!
要验证这个猜想,可以将引脚模式设置为Flash,从SRAM中启动,但是不设置中断向量表 ,看一下会出现什么情况。答案是程序会使用地址0x0800 0000作为中断向量表的首地址,而不是0x2000 0000。
STM32启动代码分析
可看这篇博客
链接: link
时钟配置
对于寄存器版本,时钟配置在main()函数里面,通过调用Stm32_Clock_Init()函数实现。
配置时钟,得结合时钟树一起看,时钟树如图所示
时钟介绍:
- HSE时钟:高速外部时钟,对于stm32探索者来说为8MHz。启用HSE时钟方式为:HSE晶振可通过RCC时钟控制寄存器(RCC_CR)中的HSEON位打开,在打开后,检测RCC时钟控制寄存器(RCC_CR)中的HSERDY标志是否为1(该标志位指示高速外部振荡器是否稳定),硬件将此位置1后,则表示HSE时钟可以用了。
- HSI时钟:由内部16MHz RC振荡器生成,可直接用作系统时钟,或者用作PLL输入。启用HSI时钟方式:通过RCC_CR中的HSION位打开,打开后,检测RCC_CR中的HSIRDY标志是否为1(该标志指示HSI RC是否稳定),硬件将此位置1后,HSI才可以使用。
- LSE时钟:LSE晶振是32.768KHz低速外部(LSE)晶振或陶瓷谐振器,可作为实时时钟(RTC)的时钟源来提供时钟/日历或其他定时功能,具有功耗低且精度高的优点。启用LSE时钟方式为:通过RCC_BDCR中的LSEON位打开,打开后,检测RCC备份域控制寄存器(RCC_BDCR)中的LSERDY标志是否为1(该标志位指示LSE晶振是否稳定),硬件将此位置1后,此时钟才可以使用。
- LSI时钟:LSI RC可作为低功耗时钟源在停机和待机模式下保持运行,供独立看门狗(IWDG)和自动唤醒单元(AWU)使用,时钟频率在32KHz左右。启用LSI时钟方式为:通过RCC_CSR中的LSION位打开,打开后,
检测RCC_CSR中的LSIRDY标志是否为1(该标志位指示低速内部振荡器是否稳定),在启动时,硬件将此位置1后,此时钟才可以使用。
配置时钟,可以用STM32CubeMx来设置参数
对于Sys_Clock_Set()函数配置FLASH
对于系统SRAM,其读写操作以CPU速度执行,且等待周期为0。
但FLASH读操作小于CPU时钟,所以需要设置CPU等待时间,或者使用自适应实时存储器加速器(ART加速器),使用ART加速器所获得的性能,相当于Flash在CPU频率高达168MHz时以0个等待周期执行程序。
FLASH->ACR|=1<<8; //指令预取使能.
FLASH->ACR|=1<<9; //指令cache使能.
FLASH->ACR|=1<<10; //数据cache使能.
FLASH->ACR|=5<<0; //5个CPU等待周期.