一、启动流程
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
内存五区:
- 栈区stack:由编译器自动分配释放,存放函数的参数值,局部变量的值。
- 堆区heap:由程序员分配和释放,若程序员不释放,程序结束时由OS回收。
- 全局区(静态区 static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量、未初始化的静态变量在相邻的另一块区域。
- 文字常量区:常量字符串就是放在这里的。
- 程序代码区 : 存放函数体的二进制代码。
启动五个步骤
- 设置堆栈指针SP=_initial_sp
- 设置PC指针=Reset_Handler
- 配置系统时钟
- 配置外部SDRAM用于程序变量等数据存储
- 调用C库的_main函数,最终调用main函数
要点
- 上电复位后第四个时钟的上升沿,boot管脚的值被锁存,从对应的存储区启动
- stm都是从0x00000000这个地址启动的,不同启动区重映射不同,重映射关系如图
- 例如从flash启动,经过重映射后,CPU将 0x08000000 位置存放的堆栈栈顶地址存放到 SP 中(MSP),将 0x08000004 位置存放的向量地址装入 PC 程序计数器。
详细请参考:https://zhuanlan.zhihu.com/p/123291856
二、HEX文件
编译时,提示的代码大小
Program Size: Code=5788 RO-data=336 RW-data=44 ZI-data=1028
其中:
- Code为代码,本质上就是一大堆ARM指令;
- RO为只读的数据,例如,char *name = “TOM”;//TOM三个字符就存放在ROM中作为RO-DATA;char cmd[] = “AT”;AT两个字符会在RAM和FLASH中各有一份。有些常量会在RO区中,有些例如立即数,会直接被编译在code区中。
- RW为非0初始化的全局和静态变量占用的RAM大小.注意:同时还要占用等量的ROM大小用于存放这些非0变量的初值;
- ZI(zero initialize)为0初始化的内存区的大小(该区域3个用途:0初始化的全局和静态变量+堆区+栈区)。
flash的大小:Code+RO+RW
RAM的大小:RW+ZI
再看HEX文件前4个字节:
前4个字节0x20000430,关系如下
0x20000430 - 0x20000000 = 0x430 = 1072 = RW + ZI = 44 + 1028
这就证明了RAM的大小是RW+ZI,也就是主堆栈指针MSP的初值
stm的RAM分配如图:
如果代码不使用内存分配,也就不需要用到堆区,最大栈区=RAM大小 - RW -ZI。