请选择 进入手机版 | 继续访问电脑版
查看: 184|回复: 3

[单片机资料] STM32F4XX启动文件逐步分析

[复制链接]

签到天数: 377 天

[LV.9]元老将成

发表于 2018-8-8 21:34:00 | 显示全部楼层 |阅读模式
本帖最后由 小马哥-1650185 于 2018-8-8 21:36 编辑

导读:STM32F4XX启动文件的作用
  • 初始化设置SP,即栈指针

  • 初始化设置PC指针指向复位中断处理函数,即PC = Reset_Handler

  • 导入中断服务程序(ISR)地址以设置中断向量表

  • 配置系统时钟与外部挂载到STM324xG-EVAL板子上的的SRAM用作数据存储,外部完成的Systeminit完成

  • 转到C库的__main处,也就是main()函数处进行代码的执行

  • 复位CortexM4之后,处理器处于线程模式,为特权优先级,并且栈被设置位MSP主堆栈


1、设置栈Stack_Size      
  1. Stack_Size      EQU     0x00000400  ;栈大小设置为1024字节

  2.                 AREA    STACK, NOINIT, READWRITE, ALIGN=3   ;段名称为STACK,未初始化,允许读写,8字节对齐
  3. ;AREA指示编译器编译出一个新的代码段或者数据段,ALIGN = 3,就是2的3次方字节对齐,也就是8字节
  4. Stack_Mem       SPACE   Stack_Size  ;分配空间,大小为1024字节,并把首地址赋值给Stack_Mem
  5. __initial_sp    ;初始化栈指针,指向栈的顶部,也就是上述空间的尾部,STM32采用满递减堆栈
复制代码



寻址方式
说明

pop=LDM
push=STM
FA
满递增
LDMFA
LDMDA
STMFA
STMIB
FD
满递减
LDMFD
LDMIA
STMFD
STMDB
EA
空递增
LDMEA
LDMDB
STMEA
STMIA
ED
空递减
LDMED
LDMIB
STMED
STMDA

满递增:SP指向最后一个被压入的元素,SP朝内存地址增加方向递增
满递减:SP指向最后一个被压入的元素,SP朝内存地址减小方向递增
空递增:SP指向最后一个被压入的元素的下一个为空的地址,SP朝内存地址增加方向递增
空递减:SP指向最后一个被压入的元素的下一个为空的地址,SP朝内存地址减小方向递增

2、设置堆Heap_Size      

  1. Heap_Size       EQU     0x00000200  ;堆大小设置为512字节

  2.                 AREA    HEAP, NOINIT, READWRITE, ALIGN=3    ;段名称为HEAP,未初始化,允许读写,8字节对齐
  3. __heap_base                         ;堆起始地址
  4. Heap_Mem        SPACE   Heap_Size   ;分配堆空间
  5. __heap_limit                        ;堆限制大小
复制代码



3、设置对齐与指令集
  1. PRESERVE8   ;保持下述空间保持8字节对齐
  2. THUMB       ;使用THUMB指令集,要声明在任何使用THUMB指令集的语句之前
复制代码

4、设置中断向量表AREA   
  1. AREA    RESET, DATA, READONLY   ;段名称为RESET,数据段,只读,保持8字节对齐,由上面的PRESERVE8指定
  2.                 EXPORT  __Vectors       ;向量表开始
  3.                 EXPORT  __Vectors_End   ;向量表结束
  4.                 EXPORT  __Vectors_Size  ;向量表大小,可由上述两个标号算出
  5. ;EXPORT 标号的输出(类似于linux设备驱动模块的EXPORT_SYMBOL(symbol))
  6. ;DCD 用于分配一片连续的存储单元,并且使用指定的数据进行初始化,仍然保持8字节的对齐
  7. __Vectors       DCD     __initial_sp               ; 堆栈顶部地址,复位后首先装载堆栈
  8.                 DCD     Reset_Handler              ; Reset Handler
  9.                 DCD     NMI_Handler                ; NMI Handler
  10.                 DCD     HardFault_Handler          ; 硬件错误
  11.                 DCD     MemManage_Handler          ; MPU错误
  12.                 DCD     BusFault_Handler           ; 总线错误
  13.                 DCD     UsageFault_Handler         ; 引用错误
  14.                 DCD     0                          ; Reserved
  15.                 DCD     0                          ; Reserved
  16.                 DCD     0                          ; Reserved
  17.                 DCD     0                          ; Reserved
  18.                 DCD     SVC_Handler                ; SVCall Handler
  19.                 DCD     DebugMon_Handler           ; Debug Monitor Handler
  20.                 DCD     0                          ; Reserved
  21.                 DCD     PendSV_Handler             ; PendSV Handler
  22.                 DCD     SysTick_Handler            ; 系统滴答计时器中断响应函数
  23. ;上述为STM32内部指定中断向量
  24.                 ; External Interrupts
  25.                 DCD     WWDG_IRQHandler                   ; Window WatchDog                                       
  26.                 ... ...                                    
  27.                 DCD     HASH_RNG_IRQHandler               ; Hash and Rng
  28.                 DCD     FPU_IRQHandler                    ; FPU                        
  29. __Vectors_End   ;中断向量表结束地址

  30. __Vectors_Size  EQU  __Vectors_End - __Vectors  ;定义中断向量表长度为结束地址减去开始地址
复制代码


5、构建中断向量函数AREA   
  1. AREA    |.text|, CODE, READONLY ;段名为.text(C编译器产生的代码段就是.text,此处可以嵌入C编译出来的代码段),代码段,只读
  2. ; Reset handler
  3. Reset_Handler    PROC
  4.                  EXPORT  Reset_Handler             [WEAK]   ;WEAK,如果有重复的定义,优先执行其他的定义

  5.         IMPORT  SystemInit  ;导入SystemInit标号
  6.         IMPORT  __main      ;导入__main标号,也就是main()函数地址

  7.                  LDR     R0, =SystemInit
  8.                  BLX     R0 ;带链接跳转并切换指令集
  9.                  LDR     R0, =__main
  10.                  BX      R0 ;跳转并切换指令集
  11.                  ENDP

  12. ; Dummy Exception Handlers (infinite loops which can be modified)
  13. NMI_Handler     PROC
  14.                 EXPORT  NMI_Handler                [WEAK]
  15.                 B       .   ;死循环
  16.                 ENDP

  17. ... ... ... ...
复制代码

6、用户栈与堆初始化               
  1. ALIGN   ;默认的对齐方式,也就是4字节对齐

  2. ;*******************************************************************************
  3. ; User Stack and Heap initialization
  4. ;*******************************************************************************
  5.                  IF      :DEF:__MICROLIB    ;如果勾选了此选项(在keil工程option的target选项右侧)

  6.                  EXPORT  __initial_sp   ;导出三个符号
  7.                  EXPORT  __heap_base    ;
  8.                  EXPORT  __heap_limit   ;

  9.                  ELSE

  10.                  IMPORT  __use_two_region_memory    ;否则导入__use_two_region_memory
  11.                  EXPORT  __user_initial_stackheap   ;导出__user_initial_stackheap

  12. __user_initial_stackheap

  13.                  LDR     R0, =  Heap_Mem    ;堆首地址
  14.                  LDR     R1, =(Stack_Mem + Stack_Size)  ;栈顶
  15.                  LDR     R2, = (Heap_Mem +  Heap_Size)  ;堆末地址
  16.                  LDR     R3, = Stack_Mem    ;栈首地址
  17.                  BX      LR ;等同于mov pc, lr
  18.                  ;跳转并切换指令集,也就是切换到ARM指令集

  19.                  ALIGN

  20.                  ENDIF

  21.                  END
复制代码

7、整个流程分析
  • 先分配好栈,堆段
  • 设置中断向量表段
  • 初始化堆栈(外部调用)
  • 构建中断处理函数,代码段(里面包含了中断复位处理函数,里面可以初始化整个系统,然后跳转到main()函数处执行)


签到天数: 674 天

[LV.9]元老将成

发表于 2018-8-9 08:31:35 | 显示全部楼层
不错的资料
回复 支持 反对

使用道具 举报

签到天数: 674 天

[LV.9]元老将成

发表于 2018-8-9 08:31:39 | 显示全部楼层
不错的资料
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

返回顶部