Understanding the startup code of the medium-capacity STM32 processor

Publisher:SereneMeadow7Latest update time:2019-03-24 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Today I want to introduce the startup code of STM32. I am using the medium-capacity STM32f103c8t6 here. The corresponding startup file is startup_stm32f10x_md.s. My startup file version is V3.6.2


Without further ado, here are the source codes I annotated:


 

/**

  ******************************************************************************

  * @file      startup_stm32f10x_md.s

  * @author    MCD Application Team

  * @version V3.6.2

  * @date      28-February-2013

  * @brief     STM32F10x Medium Density Devices vector table for RIDE7 toolchain.

  *            This module performs:

  * - Set the initial SP - Set the initial SP register value

  * - Set the initial PC == Reset_Handler, - Set the initial PC register value == 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 Cortex-M3 processor is in Thread mode, the priority is privileged and the top of the stack is set to the main function.

  *            priority is Privileged, and the Stack is set to Main.

  ******************************************************************************

  * @attention

  *

  *

© COPYRIGHT 2013 STMicroelectronics

  *

  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");

  * You may not use this file except in compliance with the License.

  * You may obtain a copy of the License at:

  *

  *        http://www.st.com/software_license_agreement_liberty_v2

  *

  * Unless required by applicable law or agreed to in writing, software 

  * distributed under the License is distributed on an "AS IS" BASIS, 

  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

  * See the License for the specific language governing permissions and

  * limitations under the License.

  *

  ******************************************************************************

  */

    

  .syntax unified ; indicates the use of unified assembly language syntax

.cpu cortex-m3; MCU is CM3

.fpu softvfp

.thumb ; instruction set

 

.global g_pfnVectors; global makes g_pfnVectors available to other target files

.global Default_Handler

 

/* start address for the initialization values ​​of the .data section. Initialize the starting address of the .data block. This address is defined in the link script.

defined in linker script */

.word _carrying

/* start address for the .data section. defined in linker script. The starting address of the .data block is defined in the linker script*/  

.word _sdata

/* end address for the .data section. defined in linker script. The end address of the .data block. This address is defined in the linker script*/

.word _edata

/* start address for the .bss section. defined in linker script. The starting address of the .bss block is defined in the linker script*/

.word _sbss

/* end address for the .bss section. defined in linker script. The end address of the .bss block. This address is defined in the linker script*/

.word _ebss

 

.equ BootRAM, 0xF108F85F /*This is similar to the macro definition in C, that is, BootRAM = 0xF108F85F, not involved in compilation*/

/**

 * @brief  This is the code that gets called when the processor first

 *          starts execution following a reset event. Only the absolutely

 *          necessary set is performed, after which the application

 *          supplied main() routine is called. 

 * @param  None

 * @retval : None

*/

 

    .section .text.Reset_Handler

.weak Reset_Handler

.type Reset_Handler, %function

Reset_Handler:

 

/* Copy the data segment initializers from flash to SRAM Copy the initialized data segment from flash to SRAM*/  

  movs r1, #0 ; assign the immediate value 0 to the r1 register

  b LoopCopyDataInit ; The program transfers to LoopCopyDataInit

 

CopyDataInit: ;Copy the code between sdata and edata from FLASH to SRAM

ldr r3, =_sidata ; load _sidata from memory into register r3

ldr r3, [r3, r1] ; read a word (32 bits) from address r3+r1 into r3

str r3, [r0, r1] ; Store the value of register r3 in the memory at address r0+r1

adds r1, r1, #4 ;r1 = r1 + 4

    

LoopCopyDataInit:

ldr r0, =_sdata ; load _sidata from memory into register r0

ldr r3, =_edata ; load _edata from memory into register r3

adds r2, r0, r1                                                               ;r2=r0+r1

cmp r2, r3; Calculate r2 - r3, if it is less than 0, the flag is 0, otherwise it is 1

bcc CopyDataInit ; If the flag is 0 (no borrow), that is, r2

ldr r2, =_sbss ; load _sbss from memory into register r2

b LoopFillZerobss ; jump to LoopFillZerobss unconditionally

/* Zero fill the bss segment. */  

FillZerobss:

movs r3, #0 ; store the immediate value 0 into register r3

str r3, [r2], #4; store the value of register r3 to the address of register r2, r2 = r2 + 4

    

LoopFillZerobss:

ldr r3, = _ebss ; load _ebss from memory into register r3

cmp r2, r3 ; compare r2, r3, and then update the flag bit

bcc FillZerobss ; If the flag is 0 (no borrow), jump to FillZerobss

/* Call the clock system intitialization function.*/

/* bl  SystemInit */

/* Call the application's entry point.*/

bl main ; transfer to the beginning of the main function

bx lr ; transfer to address lr

.size Reset_Handler, .-Reset_Handler; equivalent to mov pc lr lr is register r14

 

/**

 * @brief  This is the code that gets called when the processor receives an 

 *         unexpected interrupt. This simply enters an infinite loop, preserving

 *         the system state for examination by a debugger.

 * @param  None     

 * @retval None       

*/

    .section .text.Default_Handler,"ax",%progbits

Default_Handler:

Infinite_Loop:                                                                           

b Infinite_Loop ; Unconditional jump to Infinite_Loop

.size Default_Handler, .-Default_Handler

/******************************************************************************

*

* The minimal vector table for a Cortex M3. Note that the proper constructs Cortex M3's minimal vector table

* must be placed on this to ensure that it ends up at physical address

* 0x0000.0000.

*

******************************************************************************/    

  .section .isr_vector,"a",%progbits ; define the data segment of the interrupt vector table

.type g_pfnVectors, %object

.size g_pfnVectors, .-g_pfnVectors

    

    

g_pfnVectors:

.word _estack ; Place a word value at the current position, this value is _estack; the same applies to the following

.word Reset_Handler; This block of code means that g_pfnVectors is used as the initial address, and then

.word NMI_Handler ; write corresponding data in word units

.word HardFault_Handler

.word MemManage_Handler

.word BusFault_Handler

.word UsageFault_Handler

.word 0

.word 0

.word 0

.word 0

.word SVC_Handler

.word DebugMon_Handler

.word 0

.word PendSV_Handler

.word SysTick_Handler

.word WWDG_IRQHandler

.word PVD_IRQHandler

.word TAMPER_IRQHandler

.word RTC_IRQHandler

.word FLASH_IRQHandler

.word RCC_IRQHandler

.word EXTI0_IRQHandler

.word EXTI1_IRQHandler

.word EXTI2_IRQHandler

.word EXTI3_IRQHandler

.word EXTI4_IRQHandler

.word DMA1_Channel1_IRQHandler

.word DMA1_Channel2_IRQHandler

.word DMA1_Channel3_IRQHandler

.word DMA1_Channel4_IRQHandler

.word DMA1_Channel5_IRQHandler

.word DMA1_Channel6_IRQHandler

.word DMA1_Channel7_IRQHandler

.word ADC1_2_IRQHandler

.word USB_HP_CAN1_TX_IRQHandler

.word USB_LP_CAN1_RX0_IRQHandler

.word CAN1_RX1_IRQHandler

.word CAN1_SCE_IRQHandler

.word EXTI9_5_IRQHandler

.word TIM1_BRK_IRQHandler

.word TIM1_UP_IRQHandler

.word TIM1_TRG_COM_IRQHandler

.word TIM1_CC_IRQHandler

.word TIM2_IRQHandler

.word TIM3_IRQHandler

.word TIM4_IRQHandler

.word I2C1_EV_IRQHandler

.word I2C1_ER_IRQHandler

.word I2C2_EV_IRQHandler

.word I2C2_ER_IRQHandler

.word SPI1_IRQHandler

.word SPI2_IRQHandler

.word USART1_IRQHandler

.word USART2_IRQHandler

.word USART3_IRQHandler

.word EXTI15_10_IRQHandler

.word RTCAlarm_IRQHandler

.word USBWakeUp_IRQHandler

  .word 0

.word 0

.word 0

.word 0

.word 0

.word 0

.word 0

.word BootRAM /* @0x108. This is for boot in RAM mode for STM32F10 series medium capacity series devices in RAM mode

                            STM32F10x Medium Density devices. */

   

/*******************************************************************************

*

* Provide weak aliases for each Exception handler to the Default_Handler. 

* As they are weak aliases, any function with the same name will override 

* this definition.

*

*******************************************************************************/

    

  .weak NMI_Handler ; define a weak alias NMI_Handler

.thumb_set NMI_Handler,Default_Handler; If this weak alias is not overridden, the default Default_Handler is executed by default, otherwise the overridden NMI_Handler is executed


  .weak HardFault_Handler

.thumb_set HardFault_Handler,Default_Handler


  .weak MemManage_Handler

.thumb_set MemManage_Handler,Default_Handler


  .weak BusFault_Handler

.thumb_set BusFault_Handler,Default_Handler

 

.weak UsageFault_Handler

.thumb_set UsageFault_Handler,Default_Handler

 

.weak SVC_Handler

.thumb_set SVC_Handler,Default_Handler

 

.weak DebugMon_Handler

.thumb_set DebugMon_Handler,Default_Handler

 

.weak PendSV_Handler

.thumb_set PendSV_Handler,Default_Handler

 

.weak SysTick_Handler

.thumb_set SysTick_Handler,Default_Handler

 

.weak WWDG_IRQHandler

.thumb_set WWDG_IRQHandler,Default_Handler

 

.weak PVD_IRQHandler

.thumb_set PVD_IRQHandler,Default_Handler

 

.weak TAMPER_IRQHandler

.thumb_set TAMPER_IRQHandler,Default_Handler

 

.weak RTC_IRQHandler

.thumb_set RTC_IRQHandler,Default_Handler

 

.weak FLASH_IRQHandler

.thumb_set FLASH_IRQHandler,Default_Handler

 

.weak RCC_IRQHandler

.thumb_set RCC_IRQHandler,Default_Handler

 

.weak EXTI0_IRQHandler

.thumb_set EXTI0_IRQHandler,Default_Handler

 

.weak EXTI1_IRQHandler

.thumb_set EXTI1_IRQHandler,Default_Handler

 

.weak EXTI2_IRQHandler

.thumb_set EXTI2_IRQHandler,Default_Handler

 

.weak EXTI3_IRQHandler

.thumb_set EXTI3_IRQHandler,Default_Handler

 

.weak EXTI4_IRQHandler

.thumb_set EXTI4_IRQHandler,Default_Handler

 

.weak DMA1_Channel1_IRQHandler

.thumb_set DMA1_Channel1_IRQHandler,Default_Handler

 

.weak DMA1_Channel2_IRQHandler

.thumb_set DMA1_Channel2_IRQHandler,Default_Handler

 

.weak DMA1_Channel3_IRQHandler

.thumb_set DMA1_Channel3_IRQHandler,Default_Handler

 

.weak DMA1_Channel4_IRQHandler

.thumb_set DMA1_Channel4_IRQHandler,Default_Handler

 

.weak DMA1_Channel5_IRQHandler

.thumb_set DMA1_Channel5_IRQHandler,Default_Handler

 

.weak DMA1_Channel6_IRQHandler

.thumb_set DMA1_Channel6_IRQHandler,Default_Handler

 

.weak DMA1_Channel7_IRQHandler

.thumb_set DMA1_Channel7_IRQHandler,Default_Handler

 

.weak ADC1_2_IRQHandler

.thumb_set ADC1_2_IRQHandler,Default_Handler

 

.weak USB_HP_CAN1_TX_IRQHandler

.thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler

 

.weak USB_LP_CAN1_RX0_IRQHandler

.thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler

 

.weak CAN1_RX1_IRQHandler

.thumb_set CAN1_RX1_IRQHandler,Default_Handler

 

.weak CAN1_SCE_IRQHandler

.thumb_set CAN1_SCE_IRQHandler,Default_Handler

 

.weak EXTI9_5_IRQHandler

.thumb_set EXTI9_5_IRQHandler,Default_Handler

 

.weak TIM1_BRK_IRQHandler

.thumb_set TIM1_BRK_IRQHandler,Default_Handler

 

.weak TIM1_UP_IRQHandler

.thumb_set TIM1_UP_IRQHandler,Default_Handler

 

.weak TIM1_TRG_COM_IRQHandler

.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler

 

.weak TIM1_CC_IRQHandler

.thumb_set TIM1_CC_IRQHandler,Default_Handler

 

.weak TIM2_IRQHandler

.thumb_set TIM2_IRQHandler,Default_Handler

 

.weak TIM3_IRQHandler

.thumb_set TIM3_IRQHandler,Default_Handler

 

.weak TIM4_IRQHandler

.thumb_set TIM4_IRQHandler,Default_Handler

 

.weak I2C1_EV_IRQHandler

.thumb_set I2C1_EV_IRQHandler,Default_Handler

 

.weak I2C1_ER_IRQHandler

.thumb_set I2C1_ER_IRQHandler,Default_Handler

 

.weak I2C2_EV_IRQHandler

.thumb_set I2C2_EV_IRQHandler,Default_Handler

 

.weak I2C2_ER_IRQHandler

.thumb_set I2C2_ER_IRQHandler,Default_Handler

 

.weak SPI1_IRQHandler

.thumb_set SPI1_IRQHandler,Default_Handler

 

.weak SPI2_IRQHandler

.thumb_set SPI2_IRQHandler,Default_Handler

 

.weak USART1_IRQHandler

.thumb_set USART1_IRQHandler,Default_Handler

 

.weak USART2_IRQHandler

.thumb_set USART2_IRQHandler,Default_Handler

 

.weak USART3_IRQHandler

.thumb_set USART3_IRQHandler,Default_Handler

 

.weak EXTI15_10_IRQHandler

.thumb_set EXTI15_10_IRQHandler,Default_Handler

 

.weak RTCAlarm_IRQHandler

.thumb_set RTCAlarm_IRQHandler,Default_Handler

 

.weak USBWakeUp_IRQHandler

.thumb_set USBWakeUp_IRQHandler,Default_Handler

 

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


If there are any inaccuracies in the comments, I hope you can point them out to me. Thank you~~




Here, taking the STM32 program running process as the axis, the process of microcontroller startup is introduced one by one.


  Before powering on the microcontroller, first set the initial position for program startup by connecting high and low levels to BOOT0 and BOOT1. There are three positions for STM32 program startup:


  1:Main Flash memory


  It is the built-in Flash of STM32. Generally, when we use JTAG or SWD mode to download the program, it is downloaded to this, and the program is started directly from here after restart.


  2:System memory


  Boot from system memory. The program functions started in this mode are set by the manufacturer. Generally speaking, this boot mode is rarely used.


  3:Embedded Memory


  Built-in SRAM. Since it is SRAM, it naturally has no program storage capability. This mode is generally used for program debugging.


 


  The first method is the most commonly used among these three methods. The following is an introduction to the first startup method as an example:


  When the chip is restarted, the value of the BOOT pin will be latched at the fourth rising edge of SYSCLK. Then enter the startup file, the specific startup file is startup_stm32f10x_md.s.


  First, there is a Reset_Handler in the startup file. This assembly function has two functions:


   a. Copy the program code in FLASH to SRAM


   b. Initialize the system stack (clear to 0)


  Then enter main and thus enter the world of c.




But the startup file does not end here, there is another part.


The function of this part is to define a segment to store the interrupt vector table, and then fill in the interrupt pointers in the form of words.


There is another part after this. The purpose of this part is to define a weak alias for the interrupt service. The purpose of this weak alias is that after an interrupt is triggered, if the corresponding weak alias is not overwritten, the program will execute the default interrupt handler function (Default_Handler) by default, otherwise it will execute the overwritten interrupt handler function


Reference address:Understanding the startup code of the medium-capacity STM32 processor

Previous article:Solve STM32 HardFault_Handler error logging
Next article:STM32 cannot start after hardware reset

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号