stm32启动过程

这个问题在面试百度嵌入式技术二面的被问到,当时没有想到会问STM32的问题,答的不好。刚刚看到了类似的文章,记录一下。

参考原文链接:https://blog.csdn.net/wqx521/article/details/50925553


首先是启动文件,列举f10x比较常见几种文件,按照FLASH容量的不同使用不同的文件。

startup_stm32f10x_ld.s           小容量:FLASH<=32K
startup_stm32f10x_md.s           中容量:64K<=FLASH<=128K
startup_stm32f10x_hd.s           大容量:256K<=FLASH<=512K
startup_stm32f10x_xl.s           超大容量:FLASH>=512K

写句题外话,小于256K FLASH的STM32,页的大小为1K,大于256K的页大小为2K。在写FLASH,擦FLASH的需要注意。

;******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
;* File Name          : startup_stm32f10x_cl.s
;* Author             : MCD Application Team
;* Version            : V3.3.0
;* Date               : 04/16/2010
;* Description        : STM32F10x Connectivity line devices vector table for RVMDK 
;*                      toolchain. 
;*                      This module performs:
;*                      - Set the initial SP
;*                      - Set the initial PC == Reset_Handler
;*                      - Set the vector table entries with the exceptions ISR address
;*                      - Configure the clock system
;*                      - Branches to __main in the C library (which eventually
;*                        calls main()).
;*                      After Reset the CortexM3 processor is in Thread mode,
;*                      priority is Privileged, and the Stack is set to Main.
;* <<< Use Configuration Wizard in Context Menu >>>   

Stack_Size      EQU     0x00000400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

设置栈大小

AREA:汇编一个新的代码段或者数据段。STACK段名,任意命名;NOINIT表示不初始化;READWRITE可读可写;ALIGN=3(2^3= 8字节对齐)。

__initial_sp紧挨了SPACE放置,表示栈的结束地址,栈是从高往低生长,结束地址就是栈顶地址。

Heap_Size       EQU     0x00000200

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

设置堆大小

__heap_base堆的起始地址,__heap_limit堆的结束地址。堆由低向生长。动态分配内存用到堆。

                PRESERVE8
                THUMB

PRESERVE8 //指定当前文件的堆栈按照 8 字节对齐。

THUMB //表示后面指令兼容 THUMB 指令。THUBM 是ARM 以前的指令集,16bit,现在 Cortex-M 系列的都使用 THUMB-2 指令集,THUMB-2 是32 位的,兼容 16 位和 32 位的指令,是 THUMB 的超级。

紧接着设置的是中断向量,建立中断服务入口地址,即把中断向量与中断服务函数链接起来。

Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main
                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

这个文件里面首先定义了复位中断(复位入口矢量被硬件固定在地址0x0000_0004,地址是在flash中,所以地址是0x0800 0004)的处理函数:Reset_Handler,它的作用就是将保存于flash中的初始化数据复制到sram中,调用上面说到的SystemInit来初始化时钟,接着跳转到main执行。


 在进入main函数之前,我们要进行系统初始化:SystemInit 


SystemInit():在"startup_stm32f10x_xx.s"文件中被调用,功能是设置系统时钟(包括时钟源,PLL系数,AHB/APBx的预分频系数还有 flash的设定),这个函数会在系统复位之后首先被执行。文件中默认的一些设置:允许HSE(外部时钟),FLASH(允许预取缓冲区,设置2个等待周 期),PLL系数为9,开启PLL并选择PLL输出作为时钟源(SYSCLK),后续设置SYSCLK = HCLK = APB2 = 72MHz,APB1 = HCLK/2 = 36MHz,HCLK即AHB的时钟。


中断处理函数提供了弱(weak)别名(Default_Handler),如果不重写,中断了默认执行Default_Handler,如果重写了,因为是弱别名,所以会被你写的同名函数覆盖。WEAK声明其他的同名标号优先于该标号被引用,就是说如果外面声明了的话,;会调用外面的

 

最后定义了一个中断向量表的段(.section    .isr_vector,"a",%progbits),这个表将会放置在0x0000 0000那里,第二个字(0x0000 0004)是复位向量,复位之后从这地址所指的函数执行。


猜你喜欢

转载自blog.csdn.net/mwj327720862/article/details/80195748