1. 程式人生 > >STM32啟動過程分析

STM32啟動過程分析

硬體: STM32F1系列

軟體環境:Keil 4.54

注:本文中提到的RTOS以RT-Thread為例,不涵蓋所有RTOS的情況

在Keil MDK中新建工程時會根據所選的device自動生成啟動程式碼檔案startup.s,該檔案的作用可根據其頭部的註釋看出

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 clock system
;* - Branches to __main in the C library (which eventually
;* calls main()).
;* After Reset the CortexM3 processor is in Thread mode,
;* priority is Privileged, and the Stack is set to Main.

 在startup.s中,完成了堆疊大小和中斷向量表的設定。預設的棧大小為400位元組,堆大小為200位元組,可自行更改。這個棧在bare-metal系統中為全域性所使用,在帶RTOS的系統中被作業系統核心和中斷所使用,如果無多層函式巢狀呼叫,通常是夠用的。堆在使用malloc()的時候會被用到。堆疊的設定必須用匯編語言完成,因為C語言通常會用到函式,而函式呼叫是依賴於堆疊的。關於startup.s的詳細分析請參考

004:STM32啟動檔案詳解及SystemInit函式分析一文

 系統上電後,預設從地址為0的地方開始執行。在STM32中,若根據boot引腳選擇從主快閃記憶體儲存器啟動,則主快閃記憶體儲存器被對映到啟動空間(0x0000 0000),但仍然能夠在它原有的地址(0x0800 0000)訪問它。0x08000000開始的一段區域存放的是中斷向量表(即startup.s中__Vectors開始的部分)Assembly程式碼  收藏程式碼
  1. ; Vector Table Mapped to Address 0 at Reset    
  2.                 AREA    RESET, DATA, READONLY  
  3.                 EXPORT  __Vectors  
  4.                 EXPORT  __Vectors_End  
  5.                 EXPORT  __Vectors_Size  
  6. __Vectors       DCD     __initial_sp                    ; Top of Stack  
  7.                 DCD     Reset_Handler                   ; Reset Handler     
 先是執行__initial_sp設定主堆疊指標MSP(相關概念請參考宋巖翻譯的《Cortex-M3權威指南》),而後執行復位操作Reset_HandlerAssembly程式碼  收藏程式碼
  1. Reset_Handler    PROC  
  2.                  EXPORT  Reset_Handler             [WEAK]  
  3.      IMPORT  __main  
  4.      IMPORT  SystemInit  
  5.                  LDR     R0, =SystemInit  
  6.                  BLX     R0  
  7.                  LDR     R0, =__main  
  8.                  BX      R0  
  9.                  ENDP  
 Reset_Handler中首先執行SystemInit()函式(在system_stm32f10x.c檔案中定義),該函式主要完成了RCC時鐘的設定。接著執行__main()處的程式碼。在Keil IDE的工程視窗中,是無法搜尋到__main()的定義的,但在彙編程式碼和工程map檔案中可以找到它的身影Assembly程式碼  收藏程式碼
  1. __main                  0x08000121   Thumb Code     0  entry.o(.ARM.Collect$$$$00000000)  

 推測應該是在entry.c檔案中,而entry.c檔案應該是在Keil自帶的library裡。 

1. __scatterload()把RW/RO輸出段從裝載域地址複製到執行域地址,並完成ZI執行域的初始化工作。

2. __rt_entry()初始化堆疊,完成庫函式的初始化,最後自動跳轉向main()函式。其中__user_initial_stackheap()是在startup.s中定義的

Assembly程式碼  收藏程式碼
  1. EXPORT  __user_initial_stackheap                   
  2. __user_initial_stackheap  
  3.                  LDR     R0, =  Heap_Mem  
  4.                  LDR     R1, =(Stack_Mem + Stack_Size)  
  5.                  LDR     R2, = (Heap_Mem +  Heap_Size)  
  6.                  LDR     R3, = Stack_Mem  
  7.                  BX      LR  

根據AAPCS的規定,棧任何時候都得4位元組對齊,在呼叫入口得8位元組對齊。對於帶RTOS的系統,該函式根據

Assembly程式碼  收藏程式碼
  1. AREA STACK, NOINIT, READWRITE, ALIGN=3  
  2. AREA    HEAP, NOINIT, READWRITE, ALIGN=3  
  3. PRESERVE8  
 保證了主堆疊指標MSP是遵守規定的,而執行緒堆疊指標PSP全靠自己來保證每次進入C世界時是8位元組對齊,通常的做法是在程式中使用__attribute__((aligned(8)))來告知編譯器在分配空間時採用8位元組對齊。在發生中斷時,如果當前正在使用的棧指標不是8位元組對齊,則先把SP-4,調整為8位元組對齊,參考cortex-m3 棧的8位元組對齊一文

相關推薦

STM32啟動過程分析

硬體: STM32F1系列軟體環境:Keil 4.54注:本文中提到的RTOS以RT-Thread為例,不涵蓋所有RTOS的情況在Keil MDK中新建工程時會根據所選的device自動生成啟動程式碼檔案startup.s,該檔案的作用可根據其頭部的註釋看出This module performs:;* -

STM32啟動過程分析學習筆記

 System memory內建了ST提供的boot loader,可以通過該boot loader下載程式到Flash中。 使用者程式實際只能儲存在Flash中,且能在Flash和SRAM中執行(因為cortex-m3核採用哈佛結構,程式

【轉】Android 4.0 Launcher2源碼分析——啟動過程分析

handler flag 這一 第一次啟動 asynctask pla size ontouch wait Android的應用程序的入口定義在AndroidManifest.xml文件中可以找出:[html] <manifest xmlns:android="htt

X86架構下Linux啟動過程分析

重要 ack csdn 檢查 point article span 註意 eap 1、X86架構下的從開機到Start_kernel啟動的整體過程 這個過程簡要概述為: 開機——>BIOS——>GRUB/LILO——>Linux Kernel

Linux開機啟動過程分析

物理內存 登錄 page thread 陷阱門 execute 啟動過程 font 定義 Linux開機啟動過程分析 開機過程指的是從打開計算機電源直到LINUX顯示用戶登錄畫面的全過程。分析LINUX開機過程也是深入了解LINUX核心工作原理的一個很好的途徑。 啟動第一

u-boot-201611 啟動過程分析——基於smdk2410

u-bootu-boot-201611 啟動過程分析——基於smdk2410

linux 系統啟動過程分析

系統root 密碼丟失故障 linux啟動順序主板BIOS加電自檢 檢查硬件--> 讀取硬盤引導扇區(MBR)--> 啟動引導程序(grub)--> 選擇系統--> 加載系統內核(kernel shell)--> 啟動系統讀取相應的默認設置(環境變量,運行級別)--

Ocata Neutron代碼分析(一)——Neutron API啟動過程分析

process fig ddr arch 異常 run tap 文件中 bridge 首先,Neutron Server作為一種服務(neutron-server.service),可以到Neutron項目目錄中的setup.cfg配置文件中找到對應的代碼入口。 [ent

Ocata Neutron代碼分析(二)——Neutron RPC啟動過程分析

gre add ice common multi tween wait函數 tex 依次 RPC啟動跟Neutron API的啟動在同一個函數中執行,neutron.server.wsgi_eventlet.py中的eventlet_wsgi_server。 def ev

Linux進程啟動過程分析do_execve(可執行程序的加載和運行)---Linux進程的管理與調度(十一)

[] flag 表示 conn nali 最終 roc 不同的 recursion execve系統調用 execve系統調用 我們前面提到了, fork, vfork等復制出來的進程是父進程的一個副本, 那麽如何我們想加載新的程序, 可以通過execve來加載和啟動新的程

AliOS Things的啟動過程分析(二)

AliOS Things的啟動過程分析(二) 在AliOS Things的啟動過程分析(一)中分析了developerkit從系統上電到呼叫main函式所經歷的一些步驟,接下來詳細分析一下main函式的一些工作,主要是核心的相關初始化工作。main函式所處的位置位於    

OpenWrt啟動過程分析+新增自啟動指令碼[轉載]

一、OpenWrt啟動過程分析 總結一下OpenWrt的啟動流程:1.CFE->2.linux->3./etc/preinit->4./sbin/init ->5./etc/inittab ->6./etc/init.d/rcS->7./etc/rc.d/S*

OSAL啟動過程分析

一、SimpleBLEBroadcaster  OSAL啟動過程分析: Main() ==> HAL_BOARD_INIT();//初始化硬體 ==> InitBoard( OB_COLD );//初始化板卡IO ==> HalDriverInit();

《16.核心的啟動過程分析

《16.核心的啟動過程分析》 第一部分、章節目錄 2.16.1.做好核心分析的準備工作 2.16.2.head.S檔案分析1 2.16.3.核心啟動的彙編階段 2.16.4.核心啟動的C語言階段1 2.16.5.核心啟動的C語言階段2 2.16.6.核心啟動的C語言階段3 2.16.7.

Linux啟動過程分析(十一)---da850_set_emif_clk_rate()函式分析

/* * 雖然在bootloader中已經把emif的時鐘速率設定為允許的值,但是核心需要重新 *設定以使它支援平臺請求的特定時鐘速率。 */ ret = da850_set_emif_clk_rate()-> static __init int da850_set_emif_c

Linux啟動過程分析(十一)-----customize_machine(註冊開發板相關硬體資訊)

初始化過程進行到下面這一步: c0599c48 t __initcall_customize_machine3 呼叫的函式及其位置如下: Setup.c (arch\arm\kernel):arch_initcall(customize_machine) static int __in

Linux核心啟動過程分析(十)-----RTC驅動分析

參考https://blog.csdn.net/xuao20060793/article/details/46433263這篇博文 RTC驅動分析: Class.c (drivers\rtc):subsys_initcall(rtc_init); static int __init

Android安全/開發基礎--9--Android系統的啟動過程分析

================================================================= 整個Android系統的啟動分為Linux核心的啟動和Android系統的啟動。 Android系統的啟動流程圖中部分名詞簡介:

FreeRTOS(15)---FreeRTOS 排程器啟動過程分析

FreeRTOS 排程器啟動過程分析 使用FreeRTOS,一個最基本的程式架構如下所示: int main(void) { 必要的初始化工作; 建立任務1; 建立任務2; ... vTaskStartSchedule

U-Boot啟動過程分析總結

做為嵌入式開發者,U-Boot的啟動是必須要熟悉的。下面分享U-Boot啟動流程。 U-Boot啟動核心的過程可以分為兩個階段,兩個階段的功能如下: 第一階段功能 硬體裝置初始化 載入U-Boot第二階段程式碼到RAM空間 設定好棧 跳轉到第二階段程式碼入口 第二階段功能 初始化本階