精华内容
下载资源
问答
  • 本文详细介绍STM32单片机启动的过程,既从上电Reset_Handle跳转到main()函数的过程。其中,会着重解释__main的汇编代码 STM32启动过程 1. 从Reset_Handler开始启动 Reset_Handler的代码如下,参考《startup_stm32f10...

    本文详细介绍STM32单片机启动的过程,既从上电Reset_Handle跳转到main()函数的过程。其中,会着重解释__main的汇编代码

    STM32启动过程

    1. 从Reset_Handler开始启动

    Reset_Handler的代码如下,参考《startup_stm32f10x_hd.s》
    在这里插入图片描述
    1-计算SystemInit函数入口地址,并把地址load到R0;
    R0 = [PC + 24] = [0x08000144 + 24 +4] = [0x08000160] = 0x08000495
    从Keil中可查看地址的值
    2 – 执行r0所指向的函数,既 SystemInit();同时,把下一条指令的地址(既PC+4)保存到lr(r14)中
    3 – 计算__main的入口地址,并load到r0
    在这里插入图片描述
    在这里插入图片描述
    4 – 执行__main()

    __main 的执行过程

    • __main函数内容
      在这里插入图片描述
    • SP(R13)赋值
      SP = [pc +12 +4] = [0x08000130 + 12 + 4] = [0x08000140] = 0x20000408
      在这里插入图片描述
    • 执行 __scatterload() (地址0x08000168),并load R14, lr = 0x08000139
      在这里插入图片描述

    __scatterload函数执行过程

    在这里插入图片描述
    在这里插入图片描述

    __scatterload_copy执行过程

    在这里插入图片描述
    在这里插入图片描述

    __scatterload_zeroinit执行过程

    在这里插入图片描述
    在这里插入图片描述

    __main_after_scatterload执行过程

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • Version S Description Date By V1 ...单片机在执行main函数之前,都干了什么呢?...用KEIL学STM32单片机编程的时候,按下其仿真...会发现进入到一个启动文件startup_stm32f10x_md.s,运行指示光标,会停在一个位置...
    Version S Description Date By
    V1 C First Version 2020-12-19 AYZP

    C―― Create,
    A—— Add,
    M—— Modify,
    D—— Delete。

    前言

    单片机在执行main函数之前,都干了什么呢?都做了什么准备呢?来总结一下。

    一 准备

    用KEIL学STM32单片机编程的时候,按下其仿真按钮
    在这里插入图片描述
    再按下RST按钮

    在这里插入图片描述

    会发现进入到一个启动文件startup_stm32f10x_md.s,运行指示光标,会停在一个位置上:
    在这里插入图片描述

    详细代码见附录A,这块代码前面是栈大小设置stack size堆大小设置heap size、一堆中断向量表Vector Table

    可以看到,我们的运行光标停在Reset_Handler处。在我们执行__main之前,还要执行SystemInit,这个SystemInit包括什么呢,打开看看。我们会发现这个SystemInit在文件system_stm32f10x.c文件中,是一个函数,里面的动作包括很多,详细代码放在附录B,有兴趣看看。

    二 分析

    分析全是看别人的,链接见参考文献

    2.1 MCU程序执行过程

    MCU上电(复位)时,从固定的地址启动,一般是地址0x00000000,如ARM7;个别特殊的如STM32默认启动地址为0x8000000(flash区启动)。

    STM32的内部闪存地址起始于0x8000000,一般情况下,程序文件就从此地址开始写入。此外STM32是基于Cortex-M3内核的微控制器,其内部通过一张“中断向量表”来响应中断,程序启动后,将首先从“中断向量表”取出复位中断向量(上面的Reset_Handler)执行复位中断程序完成启动。

    程序执行过程如下图:

    在这里插入图片描述
    1、STM32复位后,会从地址为0x8000004处取出复位中断向量的地址,并跳转执行复位中断服务程序,如图1中标号1️⃣​所示。
    2、复位中断服务程序执行的最终结果是跳转至C程序的main函数,如上图中标号2️⃣所示,而main函数应该是一个死循环,是一个永不返回的函数。(我们这篇文章主要就是这里了,跳到main函数前,程序干了啥,见下一节)


    3、在main函数执行的过程中,发生了一个中断请求,此时STM32的硬件机制会将PC指针强制指回中断向量表处,如图中标号3️⃣所示。
    4、根据中断源进入相应的中断服务程序,如图1中标号5️⃣所示。
    5、中断服务程序执行完毕后,程序再度返回至main函数中执行,如图中标号6️⃣所示。

    STM32的内部闪存地址起始于0x8000000,一般情况下,程序文件就从此地址开始写入。此外STM32是基于Cortex-M3内核的微控制器,其内部通过一张“中断向量表”来响应中断,程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动。而这张“中断向量表”的起始地址是0x8000004,当中断来临,STM32的内部硬件机制亦会自动将PC指针定位到“中断向量表”处,并根据中断源取出对应的中断向量执行中断服务程序。最后还需要知道关键的一点,通过修改STM32工程的链接脚本可以修改程序文件写入闪存的起始地址。

    2.2 main 之前干了啥

    启动过程主要完成两部分工作,一个是硬件执行环境,如中断向量表、寄存器、看门狗等,另一个是软件环境,如C库环境、ZI(未初始化的内存变量)等。

    2.2.1 硬件执行环境

    1.初始时钟
    初始化内核时钟,主时钟,各个外设的时钟。

    2.关闭看门狗
    看门狗是用来监控应用程序的异常跑飞而复位CPU,在初始化阶段,由于没有“喂狗”这一动作,有可能导致CPU不断复位,因此,首先会关闭看门狗,初始化完,再开启。

    3.建立中断向量表
    中断向量表,中断源的识别标志,可用来形成相应的中断服务程序的入口地址,或者中断服务程序入口地址的偏移量和段基值。CPU利用中断向量表转入中断服务程序处理相关事务。

    4.初始化堆栈寄存器
    堆栈的作用一个就是保存现场(上下文),如函数调用或者中断发送时,将当前执行地址压栈,调用完成再返回此处执行程序。另一个作用就是保存参数,如临时变量。因此,在启动阶段需初始化堆栈寄存器、堆栈的大小、起始地址等。

    5.内存初始化
    选择内部或者外部RAM。

    2.2.2 软件环境

    1.把RO,RW从它们的加载域复制到它们的运行域中去。

    2.初始化(清零)ZI域。

    3.初始化堆栈指针

    4.初始化C库环境
    包括C库所需的内存空间、程序执行所需资源、C库初始化。

    2.2.3 CortexM3启动

    在这里插入图片描述

    CortexM3有3种启动方式

    1、BOOT1=1BOOT0=1,中断向量表定位于SRAM区,即起始地址为0x2000000,同时复位后PC指针位于0x2000000处。

    2、BOOT1=xBOOT0=0,中断向量表定位于FLASH区,即起始地址为0x8000000,同时复位后PC指针位于0x8000000处。

    3、BOOT1=0BOOT0=1,中断向量表定位于内置Bootloader区,此时可通过串口下载程序的二进制文件到flash区。

    而Cortex-M3内核规定,起始地址必须存放堆顶指针,而第二个地址则必须存放复位中断入口向量地址,这样在Cortex-M3内核复位后,会自动从起始地址的下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。对比ARM7/ARM9内核,Cortex-M3内核则是固定了中断向量表的位置而起始地址是可变化的。即是对于flash启动来说(正常工作也是flash启动),0x8000000地址存放的是栈顶地址__initial_sp,0x8000004地址存放的是复位中断向量Reset_Handler入口地址(STM32使用32位总线,存储空间为4字节对齐);在编写多段程序时,偏移地址空间需注意,如编写一个BootLoader,从BootLoader到应用程序段的相互跳转。

    2.3 流程

    关于STM32上电启动的流程,我理解的是这样:

    • 根据boot引脚的电平,确定程序起始地址,同时PC指针指向该地址。(假设从内部flash启动,起始地址0x08000000);
    • 从0x08000000取出MSP栈顶指针;(设置堆栈)
    • 从0x08000004取出值赋给PC,即reset_handler的地址,然后执行reset_handler程序。(想想2.1的那张图)。在reset_handler中完成功能:
      • 时钟初始化、看门狗、中断向量表、内存初始化、堆栈初始化、初始化运行环境(一些库)等。(此处顺序如何目前2020-12-19还不知道)
    • 执行main

    参考文献

    [1] losingamong. http://bbs.eeworld.com.cn/thread-294115-1-1.html

    [2] 电子说. 一文知道MCU上电复位启动过程. 电子发烧友. 2019.10.
    http://m.elecfans.com/article/1087849.html

    [3] 冷面水手. STM32启动BOOT0 BOOT1设置方法. 简书. 2017.01.
    https://www.jianshu.com/p/38c4a90bac19

    [4] 夜色稠. 【2.0】bootloader工作流程、MCU启动流程. CSDN. 2019.10
    https://blog.csdn.net/jaydianyu/article/details/102469037

    附录A

    启动文件startup_stm32f10x_md.s

    ;******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
    ;* File Name          : startup_stm32f10x_md.s
    ;* Author             : MCD Application Team
    ;* Version            : V3.5.0
    ;* Date               : 11-March-2011
    ;* Description        : STM32F10x Medium Density Devices vector table for MDK-ARM 
    ;*                      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 >>>   
    ;*******************************************************************************
    ; THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
    ; WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
    ; AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
    ; INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
    ; CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
    ; INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
    ;*******************************************************************************
    
    ; Amount of memory (in bytes) allocated for Stack
    ; Tailor this value to your application needs
    ; <h> Stack Configuration
    ;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
    ; </h>
    
    Stack_Size      EQU     0x00000400
    
                    AREA    STACK, NOINIT, READWRITE, ALIGN=3
    Stack_Mem       SPACE   Stack_Size
    __initial_sp
    
    
    ; <h> Heap Configuration
    ;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
    ; </h>
    
    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
                    DCD     HardFault_Handler          ; Hard Fault Handler
                    DCD     MemManage_Handler          ; MPU Fault Handler
                    DCD     BusFault_Handler           ; Bus Fault Handler
                    DCD     UsageFault_Handler         ; Usage Fault Handler
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     SVC_Handler                ; SVCall Handler
                    DCD     DebugMon_Handler           ; Debug Monitor Handler
                    DCD     0                          ; Reserved
                    DCD     PendSV_Handler             ; PendSV Handler
                    DCD     SysTick_Handler            ; SysTick Handler
    
                    ; External Interrupts
                    DCD     WWDG_IRQHandler            ; Window Watchdog
                    DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
                    DCD     TAMPER_IRQHandler          ; Tamper
                    DCD     RTC_IRQHandler             ; RTC
                    DCD     FLASH_IRQHandler           ; Flash
                    DCD     RCC_IRQHandler             ; RCC
                    DCD     EXTI0_IRQHandler           ; EXTI Line 0
                    DCD     EXTI1_IRQHandler           ; EXTI Line 1
                    DCD     EXTI2_IRQHandler           ; EXTI Line 2
                    DCD     EXTI3_IRQHandler           ; EXTI Line 3
                    DCD     EXTI4_IRQHandler           ; EXTI Line 4
                    DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1
                    DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2
                    DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3
                    DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4
                    DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5
                    DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6
                    DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7
                    DCD     ADC1_2_IRQHandler          ; ADC1_2
                    DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX
                    DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0
                    DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1
                    DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE
                    DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5
                    DCD     TIM1_BRK_IRQHandler        ; TIM1 Break
                    DCD     TIM1_UP_IRQHandler         ; TIM1 Update
                    DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation
                    DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare
                    DCD     TIM2_IRQHandler            ; TIM2
                    DCD     TIM3_IRQHandler            ; TIM3
                    DCD     TIM4_IRQHandler            ; TIM4
                    DCD     I2C1_EV_IRQHandler         ; I2C1 Event
                    DCD     I2C1_ER_IRQHandler         ; I2C1 Error
                    DCD     I2C2_EV_IRQHandler         ; I2C2 Event
                    DCD     I2C2_ER_IRQHandler         ; I2C2 Error
                    DCD     SPI1_IRQHandler            ; SPI1
                    DCD     SPI2_IRQHandler            ; SPI2
                    DCD     USART1_IRQHandler          ; USART1
                    DCD     USART2_IRQHandler          ; USART2
                    DCD     USART3_IRQHandler          ; USART3
                    DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
                    DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI Line
                    DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
    __Vectors_End
    
    __Vectors_Size  EQU  __Vectors_End - __Vectors
    
                    AREA    |.text|, CODE, READONLY
    
    ; Reset handler
    Reset_Handler    PROC
                     EXPORT  Reset_Handler             [WEAK]
         IMPORT  __main
         IMPORT  SystemInit
                     LDR     R0, =SystemInit
                     BLX     R0
                     LDR     R0, =__main
                     BX      R0
                     ENDP
    
    ; Dummy Exception Handlers (infinite loops which can be modified)
    
    NMI_Handler     PROC
                    EXPORT  NMI_Handler                [WEAK]
                    B       .
                    ENDP
    HardFault_Handler\
                    PROC
                    EXPORT  HardFault_Handler          [WEAK]
                    B       .
                    ENDP
    MemManage_Handler\
                    PROC
                    EXPORT  MemManage_Handler          [WEAK]
                    B       .
                    ENDP
    BusFault_Handler\
                    PROC
                    EXPORT  BusFault_Handler           [WEAK]
                    B       .
                    ENDP
    UsageFault_Handler\
                    PROC
                    EXPORT  UsageFault_Handler         [WEAK]
                    B       .
                    ENDP
    SVC_Handler     PROC
                    EXPORT  SVC_Handler                [WEAK]
                    B       .
                    ENDP
    DebugMon_Handler\
                    PROC
                    EXPORT  DebugMon_Handler           [WEAK]
                    B       .
                    ENDP
    PendSV_Handler  PROC
                    EXPORT  PendSV_Handler             [WEAK]
                    B       .
                    ENDP
    SysTick_Handler PROC
                    EXPORT  SysTick_Handler            [WEAK]
                    B       .
                    ENDP
    
    Default_Handler PROC
    
                    EXPORT  WWDG_IRQHandler            [WEAK]
                    EXPORT  PVD_IRQHandler             [WEAK]
                    EXPORT  TAMPER_IRQHandler          [WEAK]
                    EXPORT  RTC_IRQHandler             [WEAK]
                    EXPORT  FLASH_IRQHandler           [WEAK]
                    EXPORT  RCC_IRQHandler             [WEAK]
                    EXPORT  EXTI0_IRQHandler           [WEAK]
                    EXPORT  EXTI1_IRQHandler           [WEAK]
                    EXPORT  EXTI2_IRQHandler           [WEAK]
                    EXPORT  EXTI3_IRQHandler           [WEAK]
                    EXPORT  EXTI4_IRQHandler           [WEAK]
                    EXPORT  DMA1_Channel1_IRQHandler   [WEAK]
                    EXPORT  DMA1_Channel2_IRQHandler   [WEAK]
                    EXPORT  DMA1_Channel3_IRQHandler   [WEAK]
                    EXPORT  DMA1_Channel4_IRQHandler   [WEAK]
                    EXPORT  DMA1_Channel5_IRQHandler   [WEAK]
                    EXPORT  DMA1_Channel6_IRQHandler   [WEAK]
                    EXPORT  DMA1_Channel7_IRQHandler   [WEAK]
                    EXPORT  ADC1_2_IRQHandler          [WEAK]
                    EXPORT  USB_HP_CAN1_TX_IRQHandler  [WEAK]
                    EXPORT  USB_LP_CAN1_RX0_IRQHandler [WEAK]
                    EXPORT  CAN1_RX1_IRQHandler        [WEAK]
                    EXPORT  CAN1_SCE_IRQHandler        [WEAK]
                    EXPORT  EXTI9_5_IRQHandler         [WEAK]
                    EXPORT  TIM1_BRK_IRQHandler        [WEAK]
                    EXPORT  TIM1_UP_IRQHandler         [WEAK]
                    EXPORT  TIM1_TRG_COM_IRQHandler    [WEAK]
                    EXPORT  TIM1_CC_IRQHandler         [WEAK]
                    EXPORT  TIM2_IRQHandler            [WEAK]
                    EXPORT  TIM3_IRQHandler            [WEAK]
                    EXPORT  TIM4_IRQHandler            [WEAK]
                    EXPORT  I2C1_EV_IRQHandler         [WEAK]
                    EXPORT  I2C1_ER_IRQHandler         [WEAK]
                    EXPORT  I2C2_EV_IRQHandler         [WEAK]
                    EXPORT  I2C2_ER_IRQHandler         [WEAK]
                    EXPORT  SPI1_IRQHandler            [WEAK]
                    EXPORT  SPI2_IRQHandler            [WEAK]
                    EXPORT  USART1_IRQHandler          [WEAK]
                    EXPORT  USART2_IRQHandler          [WEAK]
                    EXPORT  USART3_IRQHandler          [WEAK]
                    EXPORT  EXTI15_10_IRQHandler       [WEAK]
                    EXPORT  RTCAlarm_IRQHandler        [WEAK]
                    EXPORT  USBWakeUp_IRQHandler       [WEAK]
    
    WWDG_IRQHandler
    PVD_IRQHandler
    TAMPER_IRQHandler
    RTC_IRQHandler
    FLASH_IRQHandler
    RCC_IRQHandler
    EXTI0_IRQHandler
    EXTI1_IRQHandler
    EXTI2_IRQHandler
    EXTI3_IRQHandler
    EXTI4_IRQHandler
    DMA1_Channel1_IRQHandler
    DMA1_Channel2_IRQHandler
    DMA1_Channel3_IRQHandler
    DMA1_Channel4_IRQHandler
    DMA1_Channel5_IRQHandler
    DMA1_Channel6_IRQHandler
    DMA1_Channel7_IRQHandler
    ADC1_2_IRQHandler
    USB_HP_CAN1_TX_IRQHandler
    USB_LP_CAN1_RX0_IRQHandler
    CAN1_RX1_IRQHandler
    CAN1_SCE_IRQHandler
    EXTI9_5_IRQHandler
    TIM1_BRK_IRQHandler
    TIM1_UP_IRQHandler
    TIM1_TRG_COM_IRQHandler
    TIM1_CC_IRQHandler
    TIM2_IRQHandler
    TIM3_IRQHandler
    TIM4_IRQHandler
    I2C1_EV_IRQHandler
    I2C1_ER_IRQHandler
    I2C2_EV_IRQHandler
    I2C2_ER_IRQHandler
    SPI1_IRQHandler
    SPI2_IRQHandler
    USART1_IRQHandler
    USART2_IRQHandler
    USART3_IRQHandler
    EXTI15_10_IRQHandler
    RTCAlarm_IRQHandler
    USBWakeUp_IRQHandler
    
                    B       .
    
                    ENDP
    
                    ALIGN
    
    ;*******************************************************************************
    ; User Stack and Heap initialization
    ;*******************************************************************************
                     IF      :DEF:__MICROLIB           
                    
                     EXPORT  __initial_sp
                     EXPORT  __heap_base
                     EXPORT  __heap_limit
                    
                     ELSE
                    
                     IMPORT  __use_two_region_memory
                     EXPORT  __user_initial_stackheap
                     
    __user_initial_stackheap
    
                     LDR     R0, =  Heap_Mem
                     LDR     R1, =(Stack_Mem + Stack_Size)
                     LDR     R2, = (Heap_Mem +  Heap_Size)
                     LDR     R3, = Stack_Mem
                     BX      LR
    
                     ALIGN
    
                     ENDIF
    
                     END
    
    ;******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE*****
    
    
    

    附录B

    system_stm32f10x.c中的SystemInit 函数

    void SystemInit (void)
    {
      /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
      /* Set HSION bit */
      RCC->CR |= (uint32_t)0x00000001;
    
      /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
    #ifndef STM32F10X_CL
      RCC->CFGR &= (uint32_t)0xF8FF0000;
    #else
      RCC->CFGR &= (uint32_t)0xF0FF0000;
    #endif /* STM32F10X_CL */   
      
      /* Reset HSEON, CSSON and PLLON bits */
      RCC->CR &= (uint32_t)0xFEF6FFFF;
    
      /* Reset HSEBYP bit */
      RCC->CR &= (uint32_t)0xFFFBFFFF;
    
      /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
      RCC->CFGR &= (uint32_t)0xFF80FFFF;
    
    #ifdef STM32F10X_CL
      /* Reset PLL2ON and PLL3ON bits */
      RCC->CR &= (uint32_t)0xEBFFFFFF;
    
      /* Disable all interrupts and clear pending bits  */
      RCC->CIR = 0x00FF0000;
    
      /* Reset CFGR2 register */
      RCC->CFGR2 = 0x00000000;
    #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
      /* Disable all interrupts and clear pending bits  */
      RCC->CIR = 0x009F0000;
    
      /* Reset CFGR2 register */
      RCC->CFGR2 = 0x00000000;      
    #else
      /* Disable all interrupts and clear pending bits  */
      RCC->CIR = 0x009F0000;
    #endif /* STM32F10X_CL */
        
    #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
      #ifdef DATA_IN_ExtSRAM
        SystemInit_ExtMemCtl(); 
      #endif /* DATA_IN_ExtSRAM */
    #endif 
    
      /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
      /* Configure the Flash Latency cycles and enable prefetch buffer */
      SetSysClock();
    
    #ifdef VECT_TAB_SRAM
      SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
    #else
      SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
    #endif 
    }
    
    展开全文
  • 单片机启动过程

    2020-08-23 23:32:44
    单片机启动过程是加电后,先运行芯片内部固有程序(这个程序是用户访问不到也改写不了的),即启动代码。启动代码程序建立完运行环境后,会去读串口状态,就是用户下载程序用到的各个端口,判断用户是否正在使用...

    启动过程简介

    单片机的启动过程是加电后,先运行芯片内部固有程序(这个程序是用户访问不到也改写不了的),即启动代码。启动代码程序建立完运行环境后,会去读串口状态,就是用户下载程序用到的各个端口,判断用户是否正在使用端口准备下载程序,如果是,就按用户要求,把用户程序下载到指定地址上。如果不是,就跳转到已经下载过的用户程序入口,从而把芯片控制权交给用户程序。如果是新的芯片还没有下载过,那么就停留在读取串口状态的循环中。

    启动代码通常都烧写在flash中,它是系统一上电就执行的一段程序,它运行在任何用户C代码之前。上电后,arm处理器处于arm态,运行于管理模式,同时系统所有中断被禁止,PC到地址0处取指令执行。一个可执行映像文件必须有个入口点,而能放在rom起始处的映像文件的入口地址也必须设置为0。在汇编语言中,可以自行定义定义一个程序的入口点,当工程中有多个入口点时,需要在连接器中使用-entry指出程序的入口点。如果用户创建的程序中,包含了main函数,则与C库初始化代码对应的也会有个入口点。 总的来说,启动代码主要完成两方面的工作,一是初始化执行环境,例如中断向量表、堆栈、I/O等;二是初始化c库和用户应用程序。

    在第一阶段,启动代码的过程可以描述为:

    (1)建立中断向量表;
    (2)初始化存储器;
    (3)初始化堆栈寄存器;
    (4)初始化i/o以及其他必要的设备;
    (5)根据需要改变处理器的状态。

    (1)建立中断向量表
    初始化代码必须建立好中断向量表,以备应用程序后续使用。如果系统的地址0处是rom,则中断向量表直接是一些跳转指令就可以了,他们转到相应的中断处理函数执行。如果系统的0地址处不是rom,则中断向量表是通过动态的方式创建的,这主要是通过存储器映射的方式来实现:即上电后,rom中的地址被映射到地址0,它首先开始执行以便完成环境的初始化,最重要的它会将中断向量表拷贝到ram中,然后通过地址映射将ram地址映射为0,这样ram中的中断向量就可以使用了。
    (2)初始化存储系统
    对于有mmu的处理器,需要正确初始化mmu,没有的只需正确初始化存储控制器,为每个bank配置正确的参数就可以了。
    (3)初始化堆栈指针
    初始化代码必须初始化处理器各种模式下的堆栈指针,所有系统或用户程序会涉及的处理器模式对应的堆栈指针都应该被初始化。通常未定义指令和预取指终止异常对应模式的堆栈指针不需要配置,除非用户需要使用它们作为调试使用。
    (4)初始化i/o以及其他必要设备
    关键的输入输出模块必须在中断打开之前被配置,例如看门狗,否则它们会在系统启动后产生复位信号。
    (5)改变处理器状态和模式
    启动代码运行时,处理器状态认为管理模式,如果用户程序需要运行在用户模式,可以切换转入用户模式;所有处理器上电后是处于arm状态的,如果需要改变处理器状态,也可以在启动代码里切换到thumb态。

    第二阶段

    在执行环境建立起来后,接下来就是应用程序的初始化,简单点就是讲用户程序加载到他们相应的运行地址,初始化数据区等,这个阶段完成后,才能进入用户最终的C代码区域。用户应用程序的初始化过程包括:将rw段的数据拷贝到他们的运行地址处,同时在rw段后面初始化相应大小的字段数据,把他们初始化为0,使用了库函数的程序(工程中有main函数)是在库函数_main中自动完成这些工作的。

    C51的启动过程

    当用keil作为开发环境,创建一个工程时,需要选择所使用的单片机型号,然后Keil会将相应单片机的startup.A51文件拷贝到工程目录下,在编译时,该文件会被编译到最终的目标文件中。一般情况下,这个文件是不需要我们做修改的,保持默认状态即可。

    startup.A51文件主要完成了如下过程:

    1. 初始化8051硬件堆栈的大小和堆栈指针;
    2. 初始化中断向量表,分配每个中断的入口地址和中断服务函数;
    3. 初始化内部RAM空间,即DATA/IDATA,将内容清零;
    4. 初始化外部RAM空间,即XDATA/PDATA,将内容清零;
    5. 初始化SMALL/COMPACT/LARGE模式下reentrant函数使用的堆栈指针;
    6. 调用main()函数,去执行我们编写的代码。

    STM32的启动过程

    参考:

    https://blog.csdn.net/qq_15391889/article/details/82723461

    http://www.elecfans.com/emb/danpianji/20181109811542.html

     

     

    参考资料

    1. 单片机的启动过程

    2. 8051 MCU学习之分析单片机的启动过程

    展开全文
  • STM8单片机启动过程

    千次阅读 2015-11-22 23:18:04
    大学的时候,学过一学期的STM8单片机,当时也算下了挺大的功夫,用的是我挺佩服的一个老师的课本,是用汇编语言教的。不过佩服归佩服,这本书其实现在想起来,一些基础的东西讲得不是很明白,比如说第一章中讲单片机...

    大学的时候,学过一学期的STM8单片机,当时也算下了挺大的功夫,用的是我挺佩服的一个老师的课本,是用汇编语言教的。不过佩服归佩服,这本书其实现在想起来,一些基础的东西讲得不是很明白,比如说第一章中讲单片机实现原理,居然用51单片机来讲,也用了51单片机的代码,可这本书是STM8好么!用51也要说一下吧,明显是出书出得有一些仓促了。而且书中出现了一些错别字,对我这种强迫症的人来讲,呵呵。当然好的地方就是里面有很多工程实际的东西,也讲到了用STM8汇编实现多任务的例子,和数字滤波等在我当时看来很奇妙很有趣的东西。我还是挺佩服他(潘永雄)的,这是实话,这本书我翻了n多遍,一直不舍等捐掉,其它的什么电路啊,模电啊,数电啊都已经捐给别人了。
    这里写图片描述
    好吧,进入主题。在讲STM8单片机的启动过程前,大家先要对STM8的存储映射(Memory Map)有一个基本的认识, 这个信息可以从STM8的data sheet上面找到。以下是截图(当然这是stm8其中一个系列的存储映射,其它的可能不一样):
    stm8s
    大家可以看到一个叫“2 Kbyte boot Rom”的存储区域,硬件复位(从关机到开机)的复位向量就在这个区域里面,这个很特殊,因为下面有一个叫“32 interrupt vectors”的存储区域,其它所有的中断向量(见下表)都存在这个区域里面,只有硬件复位向量不是。
    这里写图片描述
    所以当硬件复位后,也即STM8从关机到开机后,最先执行的是在boot Rom上的代码。boot Rom上面的代码叫做bootloader,bootloader的主要功能是通过单片机集成的外设(UART,SPI,CAN)来烧写单片机程序到单片机里面而不需要使用ST-Link,不过这是在单片机第一次烧写或者Option bytes(这个也在存储映射那个图里)里的BL和NBL字节分别设置为55和AA并且内存的读保护没有启用的时候才可以烧写的,如果不满足条件了,可以使用ST-Link连接单片机在STVP里面设置Option bytes使之满足。从boot Rom启动后的具体流程图可以看下图(该图来自于官方的UM0560),也可以直接看文字。
    这里写图片描述
    满足前面所讲的条件之后,STM8会检测是否有来自主机(通常为电脑端)的同步信号,若有同步信号则STM8交给主机控制,主机就可以向STM8下载程序了(下载完后由主机指定程序开始执行的地址)。STM8若没有检测到主机的同步信号,则等待1秒钟后超时,超时后判断单片机是否还没有烧写过程序,如果是则回到硬件复位的状态,重新上面从硬件复位开始的流程。而如果之前有烧写过程序了,则到“32 interrupt vectors”里面找到复位向量的入口,进入向量所指的地址(通常就是我们所说的main函数了)开始执行程序。
    那如果bootloader在开始执行的时候就不满足可以烧写程序的条件呢?也是到“32 interrupt vectors”里面找到复位向量的入口,进入向量所指的地址开始执行程序。
    以上就是STM8单片机的启动过程了。

    展开全文
  • 8051 MCU学习之分析单片机启动过程

    千次阅读 2017-03-15 17:50:48
    接触单片机有几年的时间了,一直专注于如何在单片机上写一些应用,对单片机如何启动的知之甚少,惭愧惭愧。。。今天得空整理了一下,加深了对单片机的认识,如为什么定义data区里的变量重新开机的初始值为0。单片机...
  • 单片机启动流程分析

    2020-11-07 14:40:28
    单片机启动流程概述 单片机上电后一直到准备好C语言运行环境并跳转到main函数执行总共经历了5个步骤: 1.内核初始化; 2.强制PC指针指向中断向量表的复位中断向量执行复位中断函数; 3.在复位中断函数中调用 ...
  • AURIX TC377,TC387,TC397用户启动程序流程用户启动程序是在Boot Firmware之后运行的程序(即用户程序里...AURITX 2代芯片的主要启动过程如下(该阶段只有在Cold Power on Reset时才会执行,其他的Reset是不会执行...
  • 单片机启动过程(从上电到main)

    万次阅读 2017-08-03 20:16:43
    一个是加载视图和运行试图,一个是单片机的存储空间。 这篇文章会涉及两个新内容,而加载视图又涉及启动代码和Scatter文件。 所以通过集成环境讲解启动代码总显得力不从心。 这里我们从编译器和链接器开始...
  • 1. MCU 代码如何启动首先我们需要澄清一个问题,什么是 Startup Code,什么是 Bootloader?因为总看到有同学混用这两个概念。Bootloader 可以译为引导程序。早期的单片机是没有 Bootloader 这种概念的。如大家熟悉的...
  • 1.MCU 代码如何启动 首先我们需要澄清一个问题,什么是 Startup Code,什么是 Bootloader?因为总看到有同学混用这两个概念。 Bootloader 可以译为引导程序。早期的单片机是没有 Bootloader 这种概念的。如大家...
  • 达芬奇(DaVinci)数字媒体技术平台TMS320DM6446/3采用了ARM+DSP双核的架构,本文从芯片的硬件结构入手介绍达芬奇DMSoC硬件部分及Linux OS的启动过程。 达芬奇DMSoC硬件概述  如图1所示,达芬奇数字媒体片上...
  •  所谓“冷启动”是指掉电后再启动,而热启动过程是不掉电的。单片机内部RAM在掉电再上电后的值在理论上是随机的(实际上大多会是0x00或0xff),这样你可以在某几个RAM中写上一些特定的值,例如0x55,0xaa,在启动时...
  • 1 电脑程序运行过程单片机的区别 由于电脑中的程序是存储在磁盘中的,而磁盘的读取速度非常慢,因此我们不可能从磁盘中直接读取当前要执行的代码,这样必然导致程序阻塞。好在,电脑的内存非常大,所以在程序执行...
  • 启动即是芯片上电复位要运行的程序,启动作为一个模块独立于操作系统而在,因为操作系统需要通过启动这个模块来加载和引导的。所以启动的英文术语是boot loader。我对boot loader的定义包括两部分:1.加载os 2. 为了...
  • stm32启动过程

    2020-07-31 11:51:17
    一次性搞定stm32启动模式与启动过程一、stm32启动模式二、从flash启动过程2.1 数据在堆栈中存储方式2.2 stm32的正常启动过程三、总结 一、stm32启动模式 这三种模式请看下列图示 三个不同作用的空间在单片机里面占...
  • stm32 启动过程

    千次阅读 2016-01-21 19:55:02
    解析 STM32 的启动过程 解析STM32的启动过程 当前的嵌入式应用程序开发过程里,并且C语言成为了绝大部分场合的最佳选择。如此一来main函数似乎成为了理所当然的起点——因为C程序往往从main函数开始执行。但一个...
  • 单片机过程考核.zip

    2020-06-17 13:29:45
    1.24s倒计时 做一个这样的计时器 你可以用软件 延时1s (不要求特别的精确),然后用动态显示的方法 ,进行倒计时数码管显示,开始时显示23s 结束时 显示00 ...三角波,将工程目录拍下,编译过程、演示过程记录 15分
  • 为了减小异步电动机启动过程中对电网的冲击,消除传统降压启动设备对异步电动机的冲击,改善异步电动机的启动特性,提出一种以AVR8535单片机为核心高性能的异步电动机软启动器。利用单片机控制集成脉冲触发器TC787的移...
  • S5PV210启动过程

    2018-07-17 20:46:51
    常用器件特性 ...单片机中:内存需求量小,而且希望开发尽量简单,适合全部用SRAM 嵌入式系统:内存需求量大,而且没有NorFlash等可启动介质 PC机: 内存需求量大,而且软件复杂,不在乎DRAM的初始化...
  • 详解 STM32的上电启动过程

    千次阅读 2019-12-30 23:07:29
    答案当然是否定的,在main函数之前单片机最先执行的是硬件设置SP、PC然后是“启动文件”,一般主要是项目文件里面的startup_xxxxx.s文件。其实这个就是我们常说的Bootloader。 其实不光STM32系列单片机是这样,我们...
  • 一、概述 1、说明  每一款芯片的启动文件... STM32作为一款高端Cortex-M3系列单片机,有必要了解它的启动文件。打好基础,为以后优化程序,写出高质量的代码最准备。  本文以一个实际测试代码--START_TEST为例...
  • 为了获得稳定的大电流, 设计了基于单片机控制的智能软启动大功率恒流源, 电流范围0~8 A,最大峰值可达10 A....该方法设计的电源在软启动过程中超调量很小,具有很好的稳定性;在恒流源工作时,稳定性也很好。
  • 0 引 言 在教学实验及科学实验中,我们常常需要了解充电的电压、电流曲线、放电的电压曲线,记录并整理数据,画曲线,这里使用单片机数据采集系统可以直观了解RC电路的过渡过程,用数据采集系统得出的数据计算该RC...

空空如也

空空如也

1 2 3 4 5 ... 19
收藏数 376
精华内容 150
关键字:

单片机启动过程