STM32啟動檔案執行步驟分析

2021-10-11 18:55:37 字數 3042 閱讀 8252

啟動檔案由彙編編寫,是系統上電復位後第乙個執行的程式。主要做了以下工作:

1、初始化堆疊指標 sp=_initial_sp

2、初始化 pc 指標=reset_handler

3、初始化中斷向量表

4、配置系統時鐘

5、呼叫 c 庫函式_main 初始化使用者堆疊,從而最終呼叫 main 函式去到 c 的世界

1 stack_size equ 0x00000400

23 area stack, noinit, readwrite, align=

34 stack_mem space stack_size

5 __initial_sp

開闢棧的大小為 0x00000400(1kb),名字為 stack,noinit 即不初始化,可讀可寫,8(2^3)位元組對齊。

棧的作用是用於區域性變數,函式呼叫,函式形參等的開銷,棧的大小不能超過內部sram 的大小。

equ:巨集定義的偽指令,相當於等於,類似與 c 中的 define。

area:告訴彙編器彙編乙個新的**段或者資料段。stack 表示段名,這個可以任

意命名;noinit表示不初始化;readwrite表示可讀可寫,align=3,表示按照 2^3對

齊,即 8 位元組對齊。

space:用於分配一定大小的記憶體空間,單位為位元組。這裡指定大小等於 stack_size。

標號__initial_sp緊挨著 space語句放置,表示棧的結束位址,即棧頂位址,棧是由高

向低生長的。

1 heap_size equ 0x00000200

23 area heap, noinit, readwrite, align=

34 __heap_base

5 heap_mem space heap_size

6 __heap_limit

preserve8

thumb

開闢堆的大小為 0x00000200(512 位元組),名字為 heap,noinit 即不初始化,可讀可寫,8(2^3)位元組對齊。

堆主要用來動態記憶體的分配,像 malloc()函式申請的記憶體就在堆上面。這個在 stm32裡面用的比較少。

preserve8:指定當前檔案的堆疊按照 8 位元組對齊。

thumb:表示後面指令相容 thumb 指令。

1 area reset, data, readonly

2 export __vectors

3 export __vectors_end

4 export __vectors_size

定義乙個資料段,名字為 reset,可讀。

當核心響應了乙個發生的異常後,對應的異常服務例程(esr)就會執行。為了決定 esr的入口位址, 核心使用了「向量表查表機制」。

export:宣告乙個標號可被外部的檔案使用,使標號具有全域性屬性。如果是 iar 編譯器,則使用的是 global 這個指令。

1 area |

.text|

, code, readonly

定義乙個名稱為.text 的**段,可讀。

1 reset_handler proc

2 export reset_handler [weak]

3 import systeminit

4 import __main

56 ldr r0,

=systeminit

7 blx r0

8 ldr r0,

=__main

9 bx r0

10 endp

復位子程式是系統上電後第乙個執行的程式,呼叫 systeminit 函式初始化系統時鐘,然後呼叫 c 庫函式_mian,最終呼叫 main 函式去到 c 的世界。

weak:表示弱定義,如果外部檔案優先定義了該標號則首先引用該標號,如果外部檔案沒有宣告也不會出錯。

import:表示該標號來自外部檔案,跟 c 語言中的 extern 關鍵字類似。

systeminit()是乙個標準的庫函式,在 system_stm32f10x.c這個庫檔案總定義。主要作用是配置系統時鐘,這裡呼叫這個函式之後,微控制器的系統時鐘配被配置為 72m。

__main 是乙個標準的 c 庫函式,主要作用是初始化使用者堆疊,並在函式的最後呼叫main 函式去到 c 的世界。這就是為什麼我們寫的程式都有乙個 main 函式的原因。

在啟動檔案裡面已經幫我們寫好所有中斷的中斷服務函式,跟我們平時寫的中斷服務函式不一樣的就是這些函式都是空的,真正的中斷復服務程式需要我們在外部的 c 檔案裡面重新實現,這裡只是提前佔了乙個位置而已。

1 nmi_handler proc ;系統異常

2 export nmi_handler [weak]

3 b .

4 endp

518 ltdc_irqhandler

19 ltdc_er_irqhandler

20 dma2d_irqhandler

21 b .

b:跳轉到乙個標號。這裡跳轉到乙個『.』,即表示無線迴圈。

1 align
1

;使用者棧和堆初始化,由 c 庫函式_main 來完成

2 if :def:__microlib ;這個巨集在 keil 裡面開啟

34 export __initial_sp

5 export __heap_base

6 export __heap_limit

7

首先判斷是否定義了__microlib ,如果定義了這個巨集則賦予標號__initial_sp(棧頂位址)、__heap_base(堆起始位址)、__heap_limit(堆結束位址)全域性屬性,可供外部檔案呼叫。然後堆疊的初始化就由 c 庫函式_main 來完成。

如果編寫的程式比較大,定義的區域性變數很多,那麼就需要修改棧的大小。如果某一天,你寫的程式出現了莫名奇怪的錯誤,並進入了硬 fault 的時候,這時你就要考慮下是不是棧不夠大,溢位了。

stm32啟動檔案分析

這篇文章主要是分析stm32啟動檔案,啟動檔案是由彙編編寫的,檔名為startup stm32f40 41 s。啟動檔案最主要的功能就是初始化堆疊指標sp,執行復位程式進入c語言main函式 1.初始化堆疊空間大小,定義棧頂位置 堆起始位置等等 2.定義中斷向量表,初始化sp指標 3.reset h...

STM32啟動檔案分析

1.啟動檔案主要作用 a.初始化指標大小 b.初始化堆指標大小 c.初始化中斷向量表 d.初始化系統時鐘 e.呼叫 main,實現堆疊的初始化,最終跳轉到c的main當中 2.棧主要儲存程式的變數,當程式變數較多時,可以將棧分配的更大,但不能超過內部sram的大小 mdk中,全域性變數和區域性變數都...

STM32 啟動檔案

先來看看啟動 中的偽操作和偽指令 equ 用於定義常量,相當於c中的巨集定義 如stack size equ 0x00000400 define stack size 0x00000400 align 位元組對齊方式 align 3 export 相當於宣告了乙個全域性變數 export vecto...