精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

關于STM32啟動文件startup_stm32f10x_hd.s的代碼

STM32嵌入式開發 ? 來源:ARM與嵌入式 ? 作者:ARM與嵌入式 ? 2022-07-06 17:26 ? 次閱讀

本文對STM32啟動文件startup_stm32f10x_hd.s的代碼進行講解,此文件的代碼在任何一個STM32F10x工程中都可以找到。

啟動文件使用的ARM匯編指令匯總

2cbc5340-fd0b-11ec-ba43-dac502259ad0.png

Stack——棧

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

開辟棧的大小為 0X00000400(1KB),名字為 STACK, NOINIT 即不初始化,可讀可寫, 8(2^3)字節對齊。

棧的作用是用于局部變量,函數調用,函數形參等的開銷,棧的大小不能超過內部SRAM 的大小。如果編寫的程序比較大,定義的局部變量很多,那么就需要修改棧的大小。如果某一天,你寫的程序出現了莫名奇怪的錯誤,并進入了硬 fault 的時候,這時你就要考慮下是不是棧不夠大,溢出了。

EQU:宏定義的偽指令,相當于等于,類似于C 中的 define。

AREA:告訴匯編器匯編一個新的代碼段或者數據段。STACK 表示段名,這個可以任意命名;NOINIT 表示不初始化;READWRITE 表示可讀可寫, ALIGN=3,表示按照 2^3對齊,即 8 字節對齊。

SPACE:用于分配一定大小的內存空間,單位為字節。這里指定大小等于 Stack_Size。

標號__initial_sp 緊挨著 SPACE 語句放置,表示棧的結束地址,即棧頂地址,棧是由高向低生長的。

Heap——堆

2ccf121e-fd0b-11ec-ba43-dac502259ad0.png

開辟堆的大小為 0X00000200(512 字節),名字為 HEAP, NOINIT 即不初始化,可讀可寫, 8(2^3)字節對齊。__heap_base 表示對的起始地址, __heap_limit 表示堆的結束地址。堆是由低向高生長的,跟棧的生長方向相反。

堆主要用來動態內存的分配,像 malloc()函數申請的內存就在堆上面。這個在 STM32里面用的比較少。

PRESERVE8 THUMB

PRESERVE8:指定當前文件的堆棧按照 8 字節對齊。

THUMB:表示后面指令兼容 THUMB 指令。THUBM 是 ARM 以前的指令集, 16bit,現在 Cortex-M 系列的都使用 THUMB-2 指令集, THUMB-2 是 32 位的,兼容 16 位和 32 位的指令,是 THUMB 的超集。關于堆棧的文章:關于C語言堆棧的經典講解。

向量表

AREA RESET, DATA, READONLYEXPORT __VectorsEXPORT __Vectors_EndEXPORT __Vectors_Size

定義一個數據段,名字為 RESET,可讀。并聲明 __Vectors、 __Vectors_End 和__Vectors_Size 這三個標號具有全局屬性,可供外部的文件調用。

EXPORT:聲明一個標號可被外部的文件使用,使標號具有全局屬性。如果是 IAR 編譯器,則使用的是 GLOBAL 這個指令。

當內核響應了一個發生的異常后,對應的異常服務例程(ESR)就會執行。為了決定 ESR的入口地址, 內核使用了―向量表查表機制‖。這里使用一張向量表。向量表其實是一個WORD(32 位整數)數組,每個下標對應一種異常,該下標元素的值則是該 ESR 的入口地址。向量表在地址空間中的位置是可以設置的,通過 NVIC 中的一個重定位寄存器來指出向量表的地址。在復位后,該寄存器的值為 0。因此,在地址 0 (即 FLASH 地址 0) 處必須包含一張向量表,用于初始時的異常分配。要注意的是這里有個另類:0 號類型并不是什么入口地址,而是給出了復位后 MSP 的初值。下圖是F103的向量表。

2ce4a6e2-fd0b-11ec-ba43-dac502259ad0.png

__Vectors DCD __initial_sp ;棧頂地址DCD Reset_Handler ;復位程序地址DCD NMI_HandlerDCD HardFault_HandlerDCD MemManage_HandlerDCD BusFault_HandlerDCD UsageFault_HandlerDCD 0 ; 0 表示保留DCD 0DCD 0DCD 0DCD SVC_HandlerDCD DebugMon_HandlerDCD 0DCD PendSV_HandlerDCD SysTick_Handler;外部中斷開始DCD WWDG_IRQHandlerDCD PVD_IRQHandlerDCD TAMPER_IRQHandler;限于篇幅,中間代碼省略DCD DMA2_Channel2_IRQHandlerDCD DMA2_Channel3_IRQHandlerDCD DMA2_Channel4_5_IRQHandler__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 的代碼段,可讀。

2d195fc2-fd0b-11ec-ba43-dac502259ad0.png

復位子程序是系統上電后第一個執行的程序,調用 SystemInit 函數初始化系統時鐘,然后調用 C 庫函數_mian,最終調用 main 函數去到 C 的世界。

WEAK:表示弱定義,如果外部文件優先定義了該標號則首先引用該標號,如果外部文件沒有聲明也不會出錯。這里表示復位子程序可以由用戶在其他文件重新實現,這里并不是唯一的。

IMPORT:表示該標號來自外部文件,跟 C 語言中的 EXTERN 關鍵字類似。這里表示 SystemInit 和__main 這兩個函數均來自外部的文件。

SystemInit()是一個標準的庫函數,在 system_stm32f10x.c 這個庫文件中定義。主要作用是配置系統時鐘,這里調用這個函數之后,單片機的系統時鐘配被配置為 72M。__main 是一個標準的 C 庫函數,主要作用是初始化用戶堆棧,并在函數的最后調用main 函數去到 C 的世界。這就是為什么我們寫的程序都有一個 main 函數的原因。

LDR、 BLX、 BX 是 CM4 內核的指令,可在《CM3 權威指南 CnR2》第四章-指令集里面查詢到,具體作用見下表:

2d2861ac-fd0b-11ec-ba43-dac502259ad0.png

中斷服務程序

在啟動文件里面已經幫我們寫好所有中斷的中斷服務函數,跟我們平時寫的中斷服務函數不一樣的就是這些函數都是空的,真正的中斷服務程序需要我們在外部的 C 文件里面重新實現,這里只是提前占了一個位置而已。

如果我們在使用某個外設的時候,開啟了某個中斷,但是又忘記編寫配套的中斷服務程序或者函數名寫錯,那當中斷來臨的時,程序就會跳轉到啟動文件預先寫好的空的中斷服務程序中,并且在這個空函數中無線循環,即程序就死在這里。

NMI_Handler PROC ;系統異常EXPORT NMI_Handler [WEAK]B .ENDP;限于篇幅,中間代碼省略SysTick_Handler PROCEXPORT SysTick_Handler [WEAK]B .ENDPDefault_Handler PROC ;外部中斷EXPORT WWDG_IRQHandler [WEAK]EXPORT PVD_IRQHandler [WEAK]EXPORT TAMP_STAMP_IRQHandler [WEAK];限于篇幅,中間代碼省略LTDC_IRQHandlerLTDC_ER_IRQHandlerDMA2D_IRQHandlerB .ENDP

B:跳轉到一個標號。這里跳轉到一個‘.’,即表示無線循環

用戶堆棧初始化

ALIGN

ALIGN:對指令或者數據存放的地址進行對齊,后面會跟一個立即數。缺省表示 4 字節對齊。

;用戶棧和堆初始化,由 C 庫函數_main 來完成IF __MICROLIB ;這個宏在 KEIL 里面開啟EXPORT __initial_spEXPORT __heap_baseEXPORT __heap_limitELSEIMPORT __use_two_region_memory ; 這個函數由用戶自己實現EXPORT __user_initial_stackheap__user_initial_stackheapLDR R0, = Heap_MemLDR R1, =(Stack_Mem + Stack_Size)LDR R2, = (Heap_Mem + Heap_Size)LDR R3, = Stack_MemBX LRALIGNENDIFEND

首先判斷是否定義了__MICROLIB ,如果定義了這個宏則賦予標號__initial_sp(棧頂地址)、 __heap_base(堆起始地址)、 __heap_limit(堆結束地址)全局屬性,可供外部文件調用。有關這個宏我們在 KEIL 里面配置,具體見下圖。然后堆棧的初始化就由 C 庫函數_main 來完成。

2d373236-fd0b-11ec-ba43-dac502259ad0.png

如果沒有定義__MICROLIB,則才用雙段存儲器模式,且聲明標號__user_initial_stackheap 具有全局屬性,讓用戶自己來初始化堆棧。

前文的匯編代碼,需要注意:

IF,ELSE,ENDIF:匯編的條件分支語句,跟 C 語言的 if ,else 類似

原文標題:詳解STM32啟動文件

文章出處:【微信公眾號:STM32嵌入式開發】歡迎添加關注!文章轉載請注明出處。

審核編輯:彭靜
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • STM32
    +關注

    關注

    2258

    文章

    10828

    瀏覽量

    352520
  • 函數
    +關注

    關注

    3

    文章

    4238

    瀏覽量

    61973
  • 代碼
    +關注

    關注

    30

    文章

    4671

    瀏覽量

    67775
  • C 語言
    +關注

    關注

    0

    文章

    18

    瀏覽量

    14097

原文標題:詳解STM32啟動文件

文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    詳解STM32啟動文件

    本文對STM32啟動文件startup_stm32f10x_hd.s代碼進行講解,此文件
    發表于 06-10 17:19 ?899次閱讀
    詳解<b class='flag-5'>STM32</b><b class='flag-5'>啟動</b><b class='flag-5'>文件</b>

    STM32啟動文件startup_stm32f10x_hd.s解析

    STM32啟動文件startup_stm32f10x_hd.s解析
    發表于 08-16 10:01

    匯編編寫的啟動文件startup_stm32f10x_hd.s

    匯編編寫的啟動文件startup_stm32f10x_hd.s: 設置堆棧指針、設置 PC 指針、初始化中斷向量表、配置系統時鐘、調用 C 庫函數 _main 最終去到 C 的世界。時鐘配置
    發表于 08-23 07:03

    startup_stm32f10x_hd.s啟動文件中使用的ARM匯編指令都有哪些呢

    startup_stm32f10x_hd.s啟動文件中使用的ARM匯編指令都有哪些呢?
    發表于 11-26 07:33

    如何去實現startup_stm32f10x_hd.s的匯編文件代碼

    如何去實現startup_stm32f10x_hd.s的匯編文件代碼呢?STM32匯編指令與C語言是如何配合的?怎樣對其進行仿真?
    發表于 11-26 06:30

    startup_stm32f10x_hd.s啟動文件有何功能呢

    startup_stm32f10x_hd.s是什么?startup_stm32f10x_hd.s啟動文件有何功能呢?
    發表于 11-26 06:38

    如何去編寫startup_stm32f10x_hd.s啟動文件代碼

    startup_stm32f10x_hd.s啟動文件有何作用呢?如何去編寫startup_stm32f10x_hd.s啟動
    發表于 11-26 06:44

    談一談startup_stm32f10x_hd.s啟動文件

    startup_stm32f10x_hd.s啟動文件有何功能?STM32F10x.s啟動文件有何
    發表于 11-26 07:13

    如何對startup_stm32f10x_hd.s啟動文件進行注釋呢

    如何對startup_stm32f10x_hd.s啟動文件進行注釋呢?
    發表于 11-26 07:50

    怎么去編寫startup_stm32f10x_hd.s 文件的源代碼

    startup_stm32f10x_hd.s是什么?有何作用?怎么去編寫startup_stm32f10x_hd.s 文件的源代碼呢?
    發表于 11-26 08:07

    詳解STM32啟動文件startup_stm32f10x_hd.s

    詳解STM32啟動文件startup_stm32f10x_hd.s
    發表于 11-29 06:44

    stm32啟動文件startup_stm32f10x_hd.s主要包含哪幾個部分

    stm32啟動文件startup_stm32f10x_hd.s主要包含哪幾個部分?怎樣去編寫startup_stm32f10x_hd.s
    發表于 11-29 06:16

    關于stm32啟動代碼startup_stm32f10x_hd.s的知識點匯總

    關于stm32啟動代碼startup_stm32f10x_hd.s的知識點匯總
    發表于 11-30 07:18

    startup_stm32f10x_hd.s啟動文件有何功能呢

    startup_stm32f10x_hd.s是什么?startup_stm32f10x_hd.s啟動文件有何功能呢?
    發表于 01-19 06:13

    STM32啟動文件startup_stm32f10x_hd.s代碼講解

    本文對STM32啟動文件startup_stm32f10x_hd.s代碼進行講解,此文件
    的頭像 發表于 06-22 10:31 ?4063次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>啟動</b><b class='flag-5'>文件</b><b class='flag-5'>startup_stm32f10x_hd.s</b>的<b class='flag-5'>代碼</b>講解