STM32 的啟動


 

 

stm32專題三十八:在SRAM中調試代碼

 

1、啟動文件簡介

  啟動文件由匯編編寫,是系統上電復位后第一個執行的程序。主要做了以下工作:

  (1)初始化堆棧指針 MSP=_initial_sp
  (2)初始化 PC 指針=Reset_Handler
  (3)初始化中斷向量表
  (4)配置系統時鍾
  (5)調用 C 庫函數_main 初始化用戶堆棧,從而最終調用 main 函數去到 C 的世界

2、STM32的啟動流程

  下面這段話引用自《CM3 權威指南 CnR2》—復位序列, CM4 的復位序列跟 CM3 一樣。

  在離開復位狀態后, CM3 做的第一件事就是讀取下列兩個 32 位整數的值:

  (1)從地址 0x0000,0000(FLASH 的地址 0x08000000,因為STM32設計的Flash起始地址是在0x0800 0000開始的)處取出 MSP 的初始值。
  (2)從地址 0x0000,0004(FLASH 的地址 0x08000004,因為STM32設計的Flash起始地址是在0x0800 0000開始的)處取出 PC 的初始值——這個值是復位向量, LSB 必須是1, 然后從這個值所對應的地址處取值。

 

  請注意,這與傳統的 ARM 架構不同——其實也和絕大多數的其它單片機不同。傳統的 ARM 架構總是從 0 地址開始執行第一條指令。它們的 0 地址處總是一條跳轉指令。 在CM3 中,在 0 地址處提供 MSP 的初始值,然后緊跟着就是向量表。 向量表中的數值是 32位的地址,而不是跳轉指令。向量表的第一個條目指向復位后應執行的第一條指令,就是我們剛剛分析的 Reset_Handler 這個函數。

 

           初始化 MSP 和 PC 的一個范例 

  因為 CM3 使用的是向下生長的滿棧,所以 MSP 的初始值必須是堆棧內存的末地址加1。舉例 來說,如果我們的堆棧區域在 0x20007C00-0x20007FFF 之間,那么 MSP 的初始值就必須是 0x20008000。

  向量表跟隨在 MSP 的初始值之后——也就是第 2 個表目。要注意因為 CM3 是在Thumb 態下執行,所以向量表中的每個數值都必須把 LSB 置 1(也就是奇數)。正是因為這個原因,上 圖中使用 0x101 來表達地址 0x100。當 0x100 處的指令得到執行后,就正式開始了程序的執行(即去到 C 的世界) 。在此之前初始化 MSP 是必需的,因為可能第 1條指令還沒來得及執行,就發生了 NMI 或是其它 fault。 MSP 初始化好后就已經為它們的服務例程准備好了堆棧。

  現在,程序就進入了我們熟悉的 C 世界,現在我們也應該明白 main 並不是系統執行的第一個程序了。

4、STM32 的啟動方式

  上面講到STM32在離開復位狀態后的工作過程如下,見下圖:

  (1) 從地址 0x00000000(FLASH 的首地址 0x08000000)處取出棧指針 MSP 的初始值,該值就是棧頂的地址。

  (2) 從地址 0x00000004(FLASH 的首地址 0x08000004) 處取出程序指針 PC 的初始值,該值指向復位后應執行的第一條指令。

  

(1)從地址 0x00000000 處取出棧指針 MSP 的初始值,該值就是棧頂的地址;

(2)從地址 0x00000004 處取出程序指針 PC 的初始值,該值指向復位后應執行的第一條指令;

上述過程由內核自動設置運行環境並執行主體程序,因此它被稱為自舉過程。

這個實際上和啟動文件是相對應的:

 

 

 

 

  雖然內核是固定訪問 0x00000000 和 0x00000004 地址的,但實際上這兩個地址可以被重映射到其它地址空間,因為STM32設計的Flash起始地址是在0x0800 0000位置開始的。以 STM32F429 為例,根據芯片引出的 BOOT0 及 BOOT1 引腳的電平情況,這兩個地址可以被映射到內部 FLASH、內部 SRAM 以及系統存儲器中,不同的映射配置下表。

BOOT1

BOOT0

映射到的存儲器

0x00000000地址映射到

0x00000004地址映射到

x

0

內部 FLASH

0x08000000

0x08000004

1

1

內部 SRAM

0x20000000

0x20000004

0

1

系統存儲器

0x1FFFB000

0x1FFFB004

  內核在離開復位狀態后會從映射的地址中取值給棧指針 MSP 及程序指針 PC,然后執行指令,我們一般以存儲器的類型來區分自舉過程,例如內部 FLASH 啟動方式、內部SRAM 啟動方式以及系統存儲器啟動方式。

  (1) 內部 FLASH 啟動方式

    當芯片上電后采樣到 BOOT0 引腳為低電平時, 0x00000000 和 0x00000004 地址被映射到內部 FLASH 的首地址 0x08000000 和 0x08000004。因此,內核離開復位狀態后,讀取內部 FLASH 的 0x08000000 地址空間存儲的內容,賦值給棧指針 MSP,作為棧頂地址,再讀取內部 FLASH 的0x08000004 地址空間存儲的內容,賦值給程序指針PC,作為將要執行的第一條指令所在的地址。具備這兩個條件后,內核就可以開始從PC 指向的地址中讀取指令執行了。

  (2) 內部 SRAM 啟動方式

    類似地,當芯片上電后采樣到 BOOT0 和 BOOT1 引腳均為高電平時, 0x00000000和 0x00000004 地址被映射到內部 SRAM 的首地址 0x20000000 和 0x20000004,內核從SRAM 空間獲取內容進行自舉。

    在實際應用中,由啟動文件 starttup_stm32f429_439xx.s 決 定 了 0x00000000 和0x00000004 地址存儲什么內容,鏈接時,由分散加載文件(sct)決定這些內容的絕對地址,即分配到內部 FLASH 還是內部 SRAM。

  (3) 系統存儲器啟動方式

    當芯片上電后采樣到 BOOT0 引腳為高電平, BOOT1 為低電平時,內核將從系統存儲器的 0x1FFFF000 及 0x1FFFF004 獲取 MSP 及 PC 值進行自舉。系統存儲器是一段特殊的空間,用戶不能訪問, ST 公司在芯片出廠前就在系統存儲器中固化了一段代碼。

    因而使用系統存儲器啟動方式時,內核會執行該代碼,該代碼運行時,會為 ISP 提供支持(In System Program),如檢測 USART1/2、 CAN2 及 USB 通訊接口傳輸過來的信息,並根據這些信息更新自己內部 FLASH 的內容,達到升級產品應用程序的目的,因此這種啟動方式也稱為 ISP 啟動方式。

      (4)在 RAM 中調試代碼的優點

               (5)在 RAM 中調試代碼的缺點

  4.1、內部 FLASH 的啟動過程

  下面我們以最常規的內部 FLASH 啟動方式來分析自舉過程,主要理解 MSP 和 PC 內容是怎樣被存儲到 0x08000000 和 0x08000004 這兩個地址的。

  如下圖所示,這是 STM32F4 默認的啟動文件的代碼,啟動文件的開頭定義了一個大小為 0x400 的棧空間,且棧頂的地址使用標號“__initial_sp”來表示;在圖下方定義了一個名為“ Reset_Handler”的子程序,它就是我們總是提到的在芯片啟動后第一個執行的代碼。

  在匯編語法中,程序的名字和標號都包含它所在的地址,因此,我們的目標是把“ __initial_sp”和“ Reset_Handler”賦值到 0x08000000 和 0x08000004 地址空間存儲,這樣內核自舉的時候就可以獲得棧頂地址以及第一條要執行的指令了。在啟動代碼的中間部分,使用了匯編關鍵字“ DCD” 把“ __initial_sp”和“ Reset_Handler”定義到了最前面的地址空間。

                                                  啟動代碼中存儲的 MSP 及 PC 指針內容 

  在啟動文件中把設置棧頂及首條指令地址到了最前面的地址空間,但這並沒有指定絕對地址,各種內容的絕對地址是由鏈接器根據分散加載文件(*.sct)分配的,STM32F429IGT6 型號的默認分散加載文件配置見代碼清單。

復制代碼
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00100000 
{ 
;     load region size_region
    ER_IROM1 0x08000000 0x00100000 
    { 
;         load address = execution address
*        .o (RESET, +First)
*        (InRoot$$Sections)
        .ANY (+RO)
    }
    RW_IRAM1 0x20000000 UNINIT 0x00030000 
    { 
;         RW data
        .ANY (+RW +ZI)
    }
}
復制代碼

  分散加載文件把加載區和執行區的首地址都設置為 0x08000000,正好是內部 FLASH的首地址,因此匯編文件中定義的棧頂及首條指令地址會被存儲到 0x08000000 和0x08000004 的地址空間。

  類似地,如果我們修改分散加載文件,把加載區和執行區的首地址設置為內部 SRAM的首地址 0x20000000,那么棧頂和首條指令地址將會被存儲到 0x20000000 和 0x20000004的地址空間了。

  為了進一步消除疑慮,我們可以查看反匯編代碼及 map 文件信息來了解各個地址空間存儲的內容,見圖 52-3,這是多彩流水燈工程編譯后的信息,它的啟動文件及分散加載文件都按默認配置。其中反匯編代碼是使用 fromelf 工具從 axf 文件生成的。

                             從反匯編代碼及 map 文件查看存儲器的內容 

  從反匯編代碼可了解到,這個工程的 0x08000000 地址存儲的值為 0x20000400,0x08000004 地址存儲的值為 0x080001C1,查看 map 文件,這兩個值正好是棧頂地址__initial_sp 以及首條指令 Reset_Handler 的地址。下載器會根據 axf 文件(bin、 hex 類似)存儲相應的內容到內部 FLASH 中。

  由此可知, BOOT0 為低電平時,內核復位后,從 0x08000000 讀取到棧頂地址為0x20000400,了解到子程序的棧空間范圍,再從 0x08000004 讀取到第一條指令的存儲地址為 0x080001C1,於是跳轉到該地址執行代碼,即從 ResetHandler 開始運行,運行SystemInit、 __main(包含分散加載代碼),最后跳轉到 C 語言的 main 函數。

  對比在內部 FLASH 中運行代碼的過程,可了解到若希望在內部 SRAM 中調試代碼,需要設置啟動方式為從內部 SRAM 啟動,修改分散加載文件控制代碼空間到內部 SRAM地址以及把生成程序下載到芯片的內部 SRAM 中。

  4.2、內部SDRAM的啟動過程 

  一般情況下,我們在 MDK 中編寫工程應用后,調試時都是把程序下載到芯片的內部FLASH 運行測試的,代碼的 CODE 及 RW-data 的內容被寫入到內部 FLASH 中存儲。但在某些應用場合下卻不希望或不能修改內部 FLASH 的內容,這時就可以使用 RAM 調試功能了,它的本質是把原來存儲在內部 FLASH 的代碼(CODE 及 RW-data 的內容)改為存儲到SRAM 中(內部 SRAM 或外部 SDRAM 均可),芯片復位后從 SRAM 中加載代碼並運行。把代碼下載到 RAM 中調試有如下優點:

  (1)下載程序非常快。 RAM 存儲器的寫入速度比在內部 FLASH 中要快得多,且沒有擦除過程,因此在 RAM 上調試程序時程序幾乎是秒下的,對於需要頻繁改動代碼的調試過程,能節約很多時間,省去了煩人的擦除與寫入 FLASH 過程。另外,STM32 的內部 FLASH 可擦除次數為 1 萬次,雖然一般的調試過程都不會擦除這么多次導致 FLASH 失效,但這確實也是一個考慮使用 RAM 的因素。

  (2)不改寫內部 FLASH 的原有程序。

  (3)對於內部 FLASH 被鎖定的芯片,可以把解鎖程序下載到 RAM 上,進行解鎖。相對地,把代碼下載到 RAM 中調試有如下缺點:

  (4)存儲在 RAM 上的程序掉電后會丟失,不能像 FLASH 那樣保存。

  (5)若使用 STM32 的內部 SRAM 存儲程序,程序的執行速度與在 FLASH 上執行速度無異,但 SRAM 空間較小。

  (6)若使用外部擴展的 SDRAM 存儲程序,程序空間非常大,但 STM32 讀取SDRAM 的速度比讀取內部 FLASH 慢,這會導致程序總執行時間增加,因此在SDRAM 中調試的程序無法完美仿真在內部 FLASH 運行時的環境。另外,由於STM32 無法直接從 SDRAM 中啟動且應用程序復制到 SDRAM 的過程比較復雜(下載程序前需要使 STM32 能正常控制 SDRAM),所以在很少會在 STM32 的SDRAM 中調試程序。

5、STM32的啟動文件

  (1)STM32F1的啟動文件

復制代碼
startup_stm32f10x_ld.s: 小容量的STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_ld_vl.s:小容量超值型的STM32F100xx
startup_stm32f10x_md.s:中容量的STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_md_vl.s: 中容量超值型的STM32F100xx
startup_stm32f10x_hd.s :大容量的STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_hd_vl.s :大容量超值型的STM32F100xx
startup_stm32f10x_xl.s: 超大容量FLASH在512K到1024K字節的STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_cl.s: 互聯型的STM32F105xx,STM32F107xx
復制代碼
ld:小容量產品,flash<64K
md:中容量產品,flash = 64k or flash = 128k
hd:大容量產品,flash > 128k
xl:超大容量產品,flash > 512k && flash < 1024k
cl:互聯型產品,stm32f105/107系列
vl:超值型產品,stm32f100系列

  (2)STM32F4的啟動文件

復制代碼
startup_stm32f40_41xxx.s
startup_stm32f40xx.s
startup_stm32f401xx.s
startup_stm32f410xx.s
startup_stm32f411xe.s
startup_stm32f412xg.s
startup_stm32f413_423xx.s
startup_stm32f427_437xx.s
startup_stm32f427x.s
startup_stm32f429_439xx.s
startup_stm32f446xx.s
startup_stm32f469_479xx.s
復制代碼

  以startup_stm32f429_439xx.s為例進行講解:

  啟動文件中用到的匯編指令:

 

復制代碼
;******************** (C) COPYRIGHT 2016 STMicroelectronics ********************
;* File Name          : startup_stm32f429_439xx.s
;* Author             : MCD Application Team
;* @version           : V1.8.0
;* @date              : 09-November-2016
;* Description        : STM32F429xx/439xx 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 system clock and the external SRAM/SDRAM mounted  
;*                        on STM324x9I-EVAL boards to be used as data memory  
;*                        (optional, to be enabled by user)
;*                      - Branches to __main in the C library (which eventually
;*                        calls main()).
;*                      After Reset the CortexM4 processor is in Thread mode,
;*                      priority is Privileged, and the Stack is set to Main.
;* <<< Use Configuration Wizard in Context Menu >>>   
;*******************************************************************************
; 
; 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.
; 
;*******************************************************************************

; 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        ;開辟1KB的棧

                AREA    STACK, NOINIT, READWRITE, ALIGN=3        ;棧名為STACK, NOINIT即不初始化, READWRITE表示可讀可寫, 3表示8( 2^3)字節對齊
Stack_Mem       SPACE   Stack_Size
__initial_sp

;棧的作用是用於局部變量,函數調用,函數形參等的開銷,棧的大小不能超過內部SRAM 的大小。如果編寫的程序比較大,定義的局部變量很多,那么就需要修改棧的大小。
;如果某一天,你寫的程序出現了莫名奇怪的錯誤,並進入了硬 fault 的時候,這時你就要考慮下是不是棧不夠大,溢出了。
;EQU:宏定義的偽指令,相當於等於,類似與 C 中的 define。
;AREA:告訴匯編器匯編一個新的代碼段或者數據段。 STACK 表示段名,這個可以任意命名; NOINIT 表示不初始化; READWRITE 表示可讀可寫, ALIGN=3,表示按照 2^3對齊,即 8 字節對齊。
;SPACE:用於分配一定大小的內存空間,單位為字節。這里指定大小等於 Stack_Size。
;標號__initial_sp 緊挨着 SPACE 語句放置,表示棧的結束地址,即棧頂地址,棧是由高向低生長的。


;/*************堆****************/
; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00000200        ;開辟512字節的堆

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base                                   ;起始
Heap_Mem        SPACE   Heap_Size
__heap_limit                                  ;結束
 
                PRESERVE8                     ;當前文件的堆按照8字節對齊
                THUMB                         ;表示后面指令兼容THUMB指令

;開辟堆的大小為 0X00000200( 512 字節),名字為 HEAP, NOINIT 即不初始化,可讀可寫, 8( 2^3)字節對齊。 __heap_base 表示對的起始地址, __heap_limit 表示堆的結束地址。堆是由低向高生長的,跟棧的生長方向相反。
;堆主要用來動態內存的分配,像 malloc()函數申請的內存就在堆上面。這個在 STM32里面用的比較少。
;PRESERVE8: 指定當前文件的堆棧按照 8 字節對齊。
;THUMB: 表示后面指令兼容 THUMB 指令。 THUBM 是 ARM 以前的指令集, 16bit,現在 Cortex-M 系列的都使用 THUMB-2 指令集, THUMB-2 是 32 位的,兼容 16 位和 32 位的指令,是 THUMB 的超級。




;/*******************向量表********************/
; Vector Table Mapped to Address 0 at Reset
                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors                      ;向量表起始地址
                EXPORT  __Vectors_End                  ;向量表結束地址
                EXPORT  __Vectors_Size                 ;記錄向量表的大小
                    
;定義一個數據段,名字為 RESET,可讀。並聲明 __Vectors、 __Vectors_End 和__Vectors_Size 這三個標號具有全局屬性,可供外部的文件調用。
;EXPORT: 聲明一個標號可被外部的文件使用,使標號具有全局屬性。如果是 IAR 編譯器,則使用的是 GLOBAL 這個指令。
;當內核響應了一個發生的異常后,對應的異常服務例程(ESR)就會執行。為了決定 ESR的入口地址, 內核使用了―向量表查表機制‖。這里使用一張向量表。向量表其實是一個WORD( 32 位整數)數組,每個下標對應一種異常,該下標元素的值則是該 ESR 的入口地址。向量表在地址空間中的位置是可以設置的,通過 NVIC 中的一個重定位寄存器來指出向量表的地址。在復位后,該寄存器的值為 0。因此,在地址 0 (即 FLASH 地址 0) 處必須包含一張向量表,用於初始時的異常分配。要注意的是這里有個另類: 0 號類型並不是什么入口地址,而是給出了復位后 MSP 的初值。
                    
                            
                    
;各個中斷對應的中斷函數的地址
;__Vectors :向量表的起始地址
__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          ;0表示保留
                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   SysTick定時器中斷函數

                ;外部中斷開始
                ; External Interrupts
                DCD     WWDG_IRQHandler                   ; Window WatchDog                                        
                DCD     PVD_IRQHandler                    ; PVD through EXTI Line detection                        
                DCD     TAMP_STAMP_IRQHandler             ; Tamper and TimeStamps through the EXTI line            
                DCD     RTC_WKUP_IRQHandler               ; RTC Wakeup through the EXTI line                       
                DCD     FLASH_IRQHandler                  ; FLASH                                           
                DCD     RCC_IRQHandler                    ; RCC   
                    
                DCD     EXTI0_IRQHandler                  ; EXTI Line0                                             
                DCD     EXTI1_IRQHandler                  ; EXTI Line1                                             
                DCD     EXTI2_IRQHandler                  ; EXTI Line2                                             
                DCD     EXTI3_IRQHandler                  ; EXTI Line3                                             
                DCD     EXTI4_IRQHandler                  ; EXTI Line4  
                    
                DCD     DMA1_Stream0_IRQHandler           ; DMA1 Stream 0                                   
                DCD     DMA1_Stream1_IRQHandler           ; DMA1 Stream 1                                   
                DCD     DMA1_Stream2_IRQHandler           ; DMA1 Stream 2                                   
                DCD     DMA1_Stream3_IRQHandler           ; DMA1 Stream 3                                   
                DCD     DMA1_Stream4_IRQHandler           ; DMA1 Stream 4                                   
                DCD     DMA1_Stream5_IRQHandler           ; DMA1 Stream 5                                   
                DCD     DMA1_Stream6_IRQHandler           ; DMA1 Stream 6                                   
                DCD     ADC_IRQHandler                    ; ADC1, ADC2 and ADC3s                            
                DCD     CAN1_TX_IRQHandler                ; CAN1 TX                                                
                DCD     CAN1_RX0_IRQHandler               ; CAN1 RX0                                               
                DCD     CAN1_RX1_IRQHandler               ; CAN1 RX1                                               
                DCD     CAN1_SCE_IRQHandler               ; CAN1 SCE  
                    
                DCD     EXTI9_5_IRQHandler                ; External Line[9:5]s   
                    
                DCD     TIM1_BRK_TIM9_IRQHandler          ; TIM1 Break and TIM9                   
                DCD     TIM1_UP_TIM10_IRQHandler          ; TIM1 Update and TIM10                 
                DCD     TIM1_TRG_COM_TIM11_IRQHandler     ; TIM1 Trigger and Commutation and TIM11
                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              ; External Line[15:10]s    
                    
                DCD     RTC_Alarm_IRQHandler              ; RTC Alarm (A and B) through EXTI Line                  
                DCD     OTG_FS_WKUP_IRQHandler            ; USB OTG FS Wakeup through EXTI line                        
                DCD     TIM8_BRK_TIM12_IRQHandler         ; TIM8 Break and TIM12                  
                DCD     TIM8_UP_TIM13_IRQHandler          ; TIM8 Update and TIM13                 
                DCD     TIM8_TRG_COM_TIM14_IRQHandler     ; TIM8 Trigger and Commutation and TIM14
                DCD     TIM8_CC_IRQHandler                ; TIM8 Capture Compare                                   
                DCD     DMA1_Stream7_IRQHandler           ; DMA1 Stream7                                           
                DCD     FMC_IRQHandler                    ; FMC                                             
                DCD     SDIO_IRQHandler                   ; SDIO                                            
                DCD     TIM5_IRQHandler                   ; TIM5                                            
                DCD     SPI3_IRQHandler                   ; SPI3                                            
                DCD     UART4_IRQHandler                  ; UART4                                           
                DCD     UART5_IRQHandler                  ; UART5                                           
                DCD     TIM6_DAC_IRQHandler               ; TIM6 and DAC1&2 underrun errors                   
                DCD     TIM7_IRQHandler                   ; TIM7                   
                DCD     DMA2_Stream0_IRQHandler           ; DMA2 Stream 0                                   
                DCD     DMA2_Stream1_IRQHandler           ; DMA2 Stream 1                                   
                DCD     DMA2_Stream2_IRQHandler           ; DMA2 Stream 2                                   
                DCD     DMA2_Stream3_IRQHandler           ; DMA2 Stream 3                                   
                DCD     DMA2_Stream4_IRQHandler           ; DMA2 Stream 4                                   
                DCD     ETH_IRQHandler                    ; Ethernet                                        
                DCD     ETH_WKUP_IRQHandler               ; Ethernet Wakeup through EXTI line                      
                DCD     CAN2_TX_IRQHandler                ; CAN2 TX                                                
                DCD     CAN2_RX0_IRQHandler               ; CAN2 RX0                                               
                DCD     CAN2_RX1_IRQHandler               ; CAN2 RX1                                               
                DCD     CAN2_SCE_IRQHandler               ; CAN2 SCE                                               
                DCD     OTG_FS_IRQHandler                 ; USB OTG FS                                      
                DCD     DMA2_Stream5_IRQHandler           ; DMA2 Stream 5                                   
                DCD     DMA2_Stream6_IRQHandler           ; DMA2 Stream 6                                   
                DCD     DMA2_Stream7_IRQHandler           ; DMA2 Stream 7                                   
                DCD     USART6_IRQHandler                 ; USART6                                           
                DCD     I2C3_EV_IRQHandler                ; I2C3 event                                             
                DCD     I2C3_ER_IRQHandler                ; I2C3 error                                             
                DCD     OTG_HS_EP1_OUT_IRQHandler         ; USB OTG HS End Point 1 Out                      
                DCD     OTG_HS_EP1_IN_IRQHandler          ; USB OTG HS End Point 1 In                       
                DCD     OTG_HS_WKUP_IRQHandler            ; USB OTG HS Wakeup through EXTI                         
                DCD     OTG_HS_IRQHandler                 ; USB OTG HS                                      
                DCD     DCMI_IRQHandler                   ; DCMI                                            
                DCD     CRYP_IRQHandler                   ; CRYP crypto                                     
                DCD     HASH_RNG_IRQHandler               ; Hash and Rng
                DCD     FPU_IRQHandler                    ; FPU
                DCD     UART7_IRQHandler                  ; UART7
                DCD     UART8_IRQHandler                  ; UART8
                DCD     SPI4_IRQHandler                   ; SPI4
                DCD     SPI5_IRQHandler                   ; SPI5
                DCD     SPI6_IRQHandler                   ; SPI6
                DCD     SAI1_IRQHandler                   ; SAI1
                DCD     LTDC_IRQHandler                   ; LTDC
                DCD     LTDC_ER_IRQHandler                ; LTDC error
                DCD     DMA2D_IRQHandler                  ; DMA2D
                                         
__Vectors_End         ;向量表結束地址

__Vectors_Size  EQU  __Vectors_End - __Vectors          ;計算向量表大小
    
    
;Vectors 為向量表起始地址, __Vectors_End 為向量表結束地址,兩個相減即可算出向量表大小。
;向量表從 FLASH 的 0 地址開始放置,以 4 個字節為一個單位,地址 0 存放的是棧頂地址, 0X04 存放的是復位程序的地址,以此類推。從代碼上看,向量表中存放的都是中斷服務函數的函數名,可我們知道 C 語言中的函數名就是一個地址。
;DCD:分配一個或者多個以字為單位的內存,以四字節對齊,並要求初始化這些內存。在向量表中, DCD 分配了一堆內存,並且以 ESR 的入口地址初始化它們。





;/****************復位程序***************/
                AREA    |.text|, CODE, READONLY        ;定義一個名稱為.text 的代碼段,可讀


; Reset handler
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit         ;外部文件
        IMPORT  __main             ;外部文件

                 LDR     R0, =SystemInit               ;調用SystemInit()函數配置系統時鍾
                 BLX     R0
                 LDR     R0, =__main                   ;初始化用戶棧,並在函數的最后調用main函數進入C的世界
                 BX      R0
                 ENDP
                     
;復位子程序是系統上電后第一個執行的程序,調用 SystemInit 函數初始化系統時鍾,然后調用 C 庫函數_mian,最終調用 main 函數去到 C 的世界。
;WEAK:表示弱定義,如果外部文件優先定義了該標號則首先引用該標號,如果外部文件沒有聲明也不會出錯。這里表示復位子程序可以由用戶在其他文件重新實現,這里並不是唯一的。
;IMPORT:表示該標號來自外部文件,跟 C 語言中的 EXTERN 關鍵字類似。這里表示 SystemInit 和__main 這兩個函數均來自外部的文件。
;SystemInit()是一個標准的庫函數,在 system_stm32f4xx.c 這個庫文件總定義。主要作用是配置系統時鍾,這里調用這個函數之后, F429 的系統時鍾配被配置為 180M。
;__main 是一個標准的 C 庫函數,主要作用是初始化用戶堆棧,最終調用 main 函數去到 C 的世界。這就是為什么我們寫的程序都有一個 main 函數的原因。如果我們在這里不調用__main,那么程序最終就不會調用我們 C 文件里面的 main,如果是調皮的用戶就可以修改主函數的名稱,然后在這里面 IMPORT 你寫的主函數名稱即可。
                          




; /*************中斷復位函數,異常常處理函數***************************/
; 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  TAMP_STAMP_IRQHandler             [WEAK]         
                EXPORT  RTC_WKUP_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_Stream0_IRQHandler           [WEAK]                                
                EXPORT  DMA1_Stream1_IRQHandler           [WEAK]                                   
                EXPORT  DMA1_Stream2_IRQHandler           [WEAK]                                   
                EXPORT  DMA1_Stream3_IRQHandler           [WEAK]                                   
                EXPORT  DMA1_Stream4_IRQHandler           [WEAK]                                   
                EXPORT  DMA1_Stream5_IRQHandler           [WEAK]                                   
                EXPORT  DMA1_Stream6_IRQHandler           [WEAK]                                   
                EXPORT  ADC_IRQHandler                    [WEAK]                         
                EXPORT  CAN1_TX_IRQHandler                [WEAK]                                                
                EXPORT  CAN1_RX0_IRQHandler               [WEAK]                                               
                EXPORT  CAN1_RX1_IRQHandler               [WEAK]                                                
                EXPORT  CAN1_SCE_IRQHandler               [WEAK]                                                
                EXPORT  EXTI9_5_IRQHandler                [WEAK]                                    
                EXPORT  TIM1_BRK_TIM9_IRQHandler          [WEAK]                  
                EXPORT  TIM1_UP_TIM10_IRQHandler          [WEAK]                
                EXPORT  TIM1_TRG_COM_TIM11_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  RTC_Alarm_IRQHandler              [WEAK]                  
                EXPORT  OTG_FS_WKUP_IRQHandler            [WEAK]                        
                EXPORT  TIM8_BRK_TIM12_IRQHandler         [WEAK]                 
                EXPORT  TIM8_UP_TIM13_IRQHandler          [WEAK]                 
                EXPORT  TIM8_TRG_COM_TIM14_IRQHandler     [WEAK] 
                EXPORT  TIM8_CC_IRQHandler                [WEAK]                                   
                EXPORT  DMA1_Stream7_IRQHandler           [WEAK]                                          
                EXPORT  FMC_IRQHandler                    [WEAK]                                             
                EXPORT  SDIO_IRQHandler                   [WEAK]                                             
                EXPORT  TIM5_IRQHandler                   [WEAK]                                             
                EXPORT  SPI3_IRQHandler                   [WEAK]                                             
                EXPORT  UART4_IRQHandler                  [WEAK]                                            
                EXPORT  UART5_IRQHandler                  [WEAK]                                            
                EXPORT  TIM6_DAC_IRQHandler               [WEAK]                   
                EXPORT  TIM7_IRQHandler                   [WEAK]                    
                EXPORT  DMA2_Stream0_IRQHandler           [WEAK]                                  
                EXPORT  DMA2_Stream1_IRQHandler           [WEAK]                                   
                EXPORT  DMA2_Stream2_IRQHandler           [WEAK]                                    
                EXPORT  DMA2_Stream3_IRQHandler           [WEAK]                                    
                EXPORT  DMA2_Stream4_IRQHandler           [WEAK]                                 
                EXPORT  ETH_IRQHandler                    [WEAK]                                         
                EXPORT  ETH_WKUP_IRQHandler               [WEAK]                     
                EXPORT  CAN2_TX_IRQHandler                [WEAK]                                               
                EXPORT  CAN2_RX0_IRQHandler               [WEAK]                                               
                EXPORT  CAN2_RX1_IRQHandler               [WEAK]                                               
                EXPORT  CAN2_SCE_IRQHandler               [WEAK]                                               
                EXPORT  OTG_FS_IRQHandler                 [WEAK]                                       
                EXPORT  DMA2_Stream5_IRQHandler           [WEAK]                                   
                EXPORT  DMA2_Stream6_IRQHandler           [WEAK]                                   
                EXPORT  DMA2_Stream7_IRQHandler           [WEAK]                                   
                EXPORT  USART6_IRQHandler                 [WEAK]                                           
                EXPORT  I2C3_EV_IRQHandler                [WEAK]                                              
                EXPORT  I2C3_ER_IRQHandler                [WEAK]                                              
                EXPORT  OTG_HS_EP1_OUT_IRQHandler         [WEAK]                      
                EXPORT  OTG_HS_EP1_IN_IRQHandler          [WEAK]                      
                EXPORT  OTG_HS_WKUP_IRQHandler            [WEAK]                        
                EXPORT  OTG_HS_IRQHandler                 [WEAK]                                      
                EXPORT  DCMI_IRQHandler                   [WEAK]                                             
                EXPORT  CRYP_IRQHandler                   [WEAK]                                     
                EXPORT  HASH_RNG_IRQHandler               [WEAK]
                EXPORT  FPU_IRQHandler                    [WEAK]
                EXPORT  UART7_IRQHandler                  [WEAK]
                EXPORT  UART8_IRQHandler                  [WEAK]
                EXPORT  SPI4_IRQHandler                   [WEAK]
                EXPORT  SPI5_IRQHandler                   [WEAK]
                EXPORT  SPI6_IRQHandler                   [WEAK]
                EXPORT  SAI1_IRQHandler                   [WEAK]
                EXPORT  LTDC_IRQHandler                   [WEAK]
                EXPORT  LTDC_ER_IRQHandler                [WEAK]
                EXPORT  DMA2D_IRQHandler                  [WEAK]

WWDG_IRQHandler                                                       
PVD_IRQHandler                                      
TAMP_STAMP_IRQHandler                  
RTC_WKUP_IRQHandler                                
FLASH_IRQHandler                                                       
RCC_IRQHandler                                                            
EXTI0_IRQHandler                                                          
EXTI1_IRQHandler                                                           
EXTI2_IRQHandler                                                          
EXTI3_IRQHandler                                                         
EXTI4_IRQHandler                                                          
DMA1_Stream0_IRQHandler                                       
DMA1_Stream1_IRQHandler                                          
DMA1_Stream2_IRQHandler                                          
DMA1_Stream3_IRQHandler                                          
DMA1_Stream4_IRQHandler                                          
DMA1_Stream5_IRQHandler                                          
DMA1_Stream6_IRQHandler                                          
ADC_IRQHandler                                         
CAN1_TX_IRQHandler                                                            
CAN1_RX0_IRQHandler                                                          
CAN1_RX1_IRQHandler                                                           
CAN1_SCE_IRQHandler                                                           
EXTI9_5_IRQHandler                                                
TIM1_BRK_TIM9_IRQHandler                        
TIM1_UP_TIM10_IRQHandler                      
TIM1_TRG_COM_TIM11_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                                            
RTC_Alarm_IRQHandler                            
OTG_FS_WKUP_IRQHandler                                
TIM8_BRK_TIM12_IRQHandler                      
TIM8_UP_TIM13_IRQHandler                       
TIM8_TRG_COM_TIM14_IRQHandler  
TIM8_CC_IRQHandler                                               
DMA1_Stream7_IRQHandler                                                 
FMC_IRQHandler                                                            
SDIO_IRQHandler                                                            
TIM5_IRQHandler                                                            
SPI3_IRQHandler                                                            
UART4_IRQHandler                                                          
UART5_IRQHandler                                                          
TIM6_DAC_IRQHandler                            
TIM7_IRQHandler                              
DMA2_Stream0_IRQHandler                                         
DMA2_Stream1_IRQHandler                                          
DMA2_Stream2_IRQHandler                                           
DMA2_Stream3_IRQHandler                                           
DMA2_Stream4_IRQHandler                                        
ETH_IRQHandler                                                         
ETH_WKUP_IRQHandler                                
CAN2_TX_IRQHandler                                                           
CAN2_RX0_IRQHandler                                                          
CAN2_RX1_IRQHandler                                                          
CAN2_SCE_IRQHandler                                                          
OTG_FS_IRQHandler                                                    
DMA2_Stream5_IRQHandler                                          
DMA2_Stream6_IRQHandler                                          
DMA2_Stream7_IRQHandler                                          
USART6_IRQHandler                                                        
I2C3_EV_IRQHandler                                                          
I2C3_ER_IRQHandler                                                          
OTG_HS_EP1_OUT_IRQHandler                           
OTG_HS_EP1_IN_IRQHandler                            
OTG_HS_WKUP_IRQHandler                                
OTG_HS_IRQHandler                                                   
DCMI_IRQHandler                                                            
CRYP_IRQHandler                                                    
HASH_RNG_IRQHandler
FPU_IRQHandler  
UART7_IRQHandler                  
UART8_IRQHandler                  
SPI4_IRQHandler                   
SPI5_IRQHandler                   
SPI6_IRQHandler                   
SAI1_IRQHandler                   
LTDC_IRQHandler                   
LTDC_ER_IRQHandler                 
DMA2D_IRQHandler                  
                B       .                ;跳轉到一個標號。這里跳轉到一個‘ .’,即表示無線循環

                ENDP

;在啟動文件里面已經幫我們寫好所有中斷的中斷服務函數,跟我們平時寫的中斷服務函數不一樣的就是這些函數都是空的,真正的中斷復服務程序需要我們在外部的 C 文件里面重新實現,這里只是提前占了一個位置而已。
;如果我們在使用某個外設的時候,開啟了某個中斷,但是又忘記編寫配套的中斷服務程序或者函數名寫錯,那當中斷來臨的時,程序就會跳轉到啟動文件預先寫好的空的中斷服務程序中,並且在這個空函數中無線循環,即程序就死在這里。




;/****************用戶堆與棧的初始化*************/ ALIGN ;對指令或者數據存放的地址進行對齊,后面會跟一個立即數。缺省表示 4 字節對齊。 ;******************************************************************************* ; User Stack and Heap initialization ;******************************************************************************* IF :DEF:__MICROLIB ;這個宏在keil里面開啟 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 ;判斷是否定義了__MICROLIB ,如果定義了則賦予標號__initial_sp(棧頂地址)、__heap_base(堆起始地址)、 __heap_limit(堆結束地址)全局屬性,可供外部文件調用。如果沒有定義(實際的情況就是我們沒定義__MICROLIB)則使用默認的 C 庫,然后初始化用戶堆棧大小,這部分有 C 庫函數__main 來完成,當初始化完堆棧之后,就調用 main函數去到 C 的世界。 ;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM