Analyse du fichier de démarrage du système STM32F103

Préface

Cet article analyse le fichier de démarrage STM32F103

1. Étapes de démarrage du système STM32F103

Le fichier de démarrage est startup_stm32f10x_hd.s, qui est écrit par des fichiers d'assemblage et est le premier programme exécuté après la mise sous tension du système.
Le processus est le suivant:
1. Définissez le tas et la taille de la pile, définissez la table vectorielle
2, initialisez le pointeur de pile
3, initialisez le pointeur PC = Rest_Handler
4, initialisez la table vectorielle d'interruption
5, configurez l'horloge système
6, appelez la bibliothèque C function _main pour initialiser la pile utilisateur, implémentez donc la fonction main

2. Analyse du code du fichier de démarrage

Paramètre de taille de pile de pile

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

1. Définissez la taille de la pile sur 0x00000400 (taille 1M)
2. La fonction de la pile: enregistrez les variables locales, les appels de fonction, les paramètres de fonction et autres frais généraux. La taille de la pile ne peut pas dépasser la SRAM interne.
3. AREA: Indiquez à l'assembleur qu'il s'agit d'un segment de code ou d'un segment de données. STACK représente le nom de la pile. Il peut être nommé arbitrairement; NOINIT signifie pas d'initialisation; READWRITE signifie lisible et inscriptible; ALIGN = 3 alignement 2 ^ 3 alignement de puissance, c'est-à-dire un alignement de 8 octets, ESPACE est utilisé pour allouer une certaine taille de mémoire, et le spécifié ici est Stack_Size
4, __Initial_sp, après SPACE, représente l'adresse de fin de la pile, c'est-à-dire l'adresse du haut de la pile, la pile croît de haut en bas

Tas

Heap_Size       EQU     0x00000200
                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit
                PRESERVE8
                THUMB

1. Heap_Size est défini sur 0x00000200 (512 octets)
2. __heap_base représente l'adresse de début du tas et __heap_limit représente l'adresse de fin.
3. Le tas augmente de bas en haut
4. Le tas est utilisé pour allouer dynamiquement de la mémoire. La mémoire allouée par une série de fonctions malloc est sur le tas.
5, PRESERVE8: indique que la pile est alignée selon 8 octets
6, THUMB: indique que le jeu d'instructions du pouce est utilisé

Table de vecteur

; Vector Table Mapped to Address 0 at Reset
                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors
                EXPORT  __Vectors_End
                EXPORT  __Vectors_Size

Définissez un segment de données nommé RESET, qui est uniquement lisible. Et EXPORT déclare __Vectors, __Vectors_End, __Vectors_Size trois attributs à usage externe.

Vecteur d'interruption

Lorsque le noyau répond à une exception, le service d'exception correspondant sera exécuté. Le noyau utilise la table des vecteurs d'interruption pour indiquer l'adresse d'entrée.

__Vectors       DCD     __initial_sp               ; Top of Stack 申请的栈顶,__Vectors对外的向量起始地址
                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
                ; External Interrupts
                DCD     WWDG_IRQHandler            ; Window Watchdog
                DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
                DCD     TAMPER_IRQHandler          ; Tamper
__Vectors_End
          
__Vectors_Size  EQU  __Vectors_End - __Vectors              

La table vectorielle contient des interruptions système et des interruptions périphériques. Il existe de nombreux vecteurs, et beaucoup sont omis ici.
__Vectors est l'adresse de début du vecteur, __Vectors_End est l'adresse de fin et __Vectors_Size est la taille de la pile. La table vectorielle est stockée à partir de l'adresse 0 de FLASH, avec 4 octets comme unité La table d'interruption stocke les noms des fonctions d'interruption.

Extrait de code

AREA    |.text|, CODE, READONLY

Définir un segment de code, lisible

Réinitialiser le programme, fonction d'entrée

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

Le programme de réinitialisation est le premier programme exécuté. Il initialise l'horloge système et passe à la fonction principale. __Main est une bibliothèque de fonctions C standard, qui est principalement utilisée pour initialiser la pile utilisateur et sauter dans le monde du langage C principal.

                 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

Je suppose que tu aimes

Origine blog.csdn.net/WANGYONGZIXUE/article/details/115036140
conseillé
Classement