我能,启动洗衣机,启动摩托车,启动泰坦尼克号,咋启动STM32F407?
我想,其实就跟开飞机差不多,就是了解他能做什么,然后我做什么;
@/"
1> 启动模式
1.1> 启动方式配置
选择STM32F407程序下载位置;
//--------------------------//
1> Flash :程序下载到Flash中,M4内核读取FLash, 起始地址【0x0800 0000】;
2> System memory :ISP下载时,通过UART,将程序下载到System memory, 起始地址【0x1FFF 0000】;
3> Embedded SRAM :程序下载到SRAM, 起始地址【0x2000 0000】
//--------------------------//
1.2> 外设内存映射
STM32F407将外设都统一编号;
1.3> 重映射 Remap机制
STM32F407根据boot引脚,自动进行内存重映射;
为啥搞3种启动模式,有空了,让ARM公司改进下;
2> std库启动示例
硬件干的活:
Cortex-M4上电后,会把【0x0】地址4字节数据赋值给【堆栈寄存器SP】,
把【0x4】地址4字节赋值给【程序计数器PC】,开始执行程序;
瞅瞅ARM公司是咋玩的,参考参考;
//--------------------------//
准备:
1> 硬件配置为:Flash启动模式;
2> 用std库模板写个点led程序;
----------------------------
从startup_stm32f40xx.c分析;
//--------------------------//
Step 1> 配置栈和堆
初始化栈,SP = 0x20009a8;
?为什么第一步就配置栈?
后面函数调用,变量使用,都在栈空间内实现;
Step 2> 配置_异常中断向量表
复位中断函数()地址:0x0800 023d;
Step 3> 实现Reset_Handler函数
调用:SystemInit()函数
功能:时钟配置;
Step 4> 调用系统_ _main 函数
Step 5> 调用用户main 函数
3> .hex文件分析
std库生成的project_demo.hex:
由上图分析Cotrex-M4,从0x0000 0000(0x0800 000)地址拿到4字节数据,
赋值给栈指针寄存器 SP = 0x2000 09A8;
从0x0800 0004(0x0800 0004)拿到4字节数据,得到复位程序地址;
在下载前,可以改一改,玩一玩
4> .map文件分析
.map文件 是编译器编译后生成的内存映射报告文件
段(section):描述映像文件的代码和数据块;
RO:Read-Only, 包括RO-data(只读数据)和RO-code(代码);
RW: Read-Write, RW-data, 由程序已初始化的变量;
ZI: Zero-Initialized,ZI-data,编译器初始化为0的变量; /* 未初始化的全局变量 */
.text: 与RO-code同义;
.constdata: 与RO-code同义;
.data: 与RW-Data同义;
4.1> 加载域(Load Region)
4.2> 执行域(Execution Region)
注意:区分.map文件映射,与STM32F407外设映射;
5> 简化版_启动代码
PRESERVE8 ; 8字节对齐
THUMB ; thumb汇编指令集
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY ; 段名,数据段,只读
EXPORT __Vectors
__Vectors DCD 0 ; Top of Stack
DCD Reset_Handler ; Reset Handler
AREA |.text|, CODE, READONLY
; Reset handler
Reset_Handler PROC ; 程序开始
EXPORT Reset_Handler [weak] ; 弱定义
IMPORT main
LDR sp, =(0x20000000 + 0x400) ; 栈顶指针
BL main ; 跳转到main函数
ENDP ; 程序结束
END