最近由于需要用到stm32,一直没怎么用过这个芯片,最近又巴拉巴拉,看了看,对stm32的启动文件,在这记录一下,自己的一点理解
新建的stm32工程,都会自动添加一个startup_stm32f10x_hd.s文件,这个文件也就是启动文件了,程序刚开始运行之处 ,这么说也不对,其实程序刚开始运行,在M3权威指南这么说的
在离开复位状态后,
CM3 做的第一件事就是读取下列两个
32 位整数的值:
z1从地址0x0000,0000处取出MSP
的初始值。
z2 从地址0x0000,0004处取出PC
的初始值——这个值是复位向量,
LSB 必须是
1。然
后从这个值所对应的地址处取指。
刚开始启动这里应该存放了,boot0和boot1的数值,然后再跳转到rom或者sram中运行,这应该叫做是一个映射吧,这里只分析flash运行情况
一半,都这么用
这个是编译器上面的地址定义
Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
Heap_Size EQU 0x00000200
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
很明显,st的做法就是了,申请了栈和堆,分配个内存吧,先占个地,从第一句话可以看出,这个栈是向下的,__initial_sp这个就是栈顶了,当然,大小0x00000400
然后是堆,不过你如果你不用malloc函数的话,我认为,堆是可以不要的,不过这个我没有尝试,堆我的理解就是动态分配内存然后free了
接着就是代码段了,初始化向量表 顺序都是标准的,看手册就可以知道
至于第一个为什么是栈顶,我也不是很理解,看手册,第一个地址入口为保留地址,没有什么作用,而第二个才是resert,才是正确的代码执行入口
紧接着就是申请一大堆向量表的空间,再跳转到_main,然后就到main了
但向量表的首地址是在C中初始化的
还有一个,flash运行的时候,启动代码并没有搬移指令,看编译好的map文件,可以知道,堆栈地址都是在sram中的,但代码段却是在flash,flash是直接运行的程序,并没有进行向bootloader类似的搬移,我们知道bootloader一半会把nandflash整个程序文件都复制到Dram然后运行,但这里却是不是,只是把随时改变的堆栈还有bss段这些放在ram,而代码段是只读的
只能说明norflash读的速度确实够快。这么做也是合理的,