1、STM32 啟動文件與 .sct 文件分析
1) 定義STACK段,{NOINIT,讀寫}:分配一段內存大小為0.5K;
2) 定義HEAP段, {NOINIT,讀寫}:分配一段內存大小為1K;
3) 定義RESET段,{DATA,只讀}:DCD各種中斷向量;
4) 定義|.text|段,{CODE,只讀}:Reset_Handler函數,函數中最后加載了__main;
對剩余的中斷函數進行了弱定義;
在最后還有一段用戶初始化堆棧的代碼__user_initial_stackheap。
那這些代碼都存放在什么位置呢?
5) 分析 .sct 文件:
分散加載文件(即scatter file,后綴為.scf)。
分散加載文件是一個文本文件,通過編寫一個分散加載文件來指定ARM連接器在生成映像文件時如何分配RO,RW,ZI等數據的存放地址。
如果不用SCATTER文件指定,那么ARM連接器會按照默認的方式來生成映像文件,一般情況下我們是不需要使用分散加載文件的。
但在某些場合,我們希望把某些數據放在指定的地址處,那么這時候SCATTER文件就發揮了非常大的作用。
而且SCATTER文件用起來非常簡單好用。
舉個例子:
比如像LPC2378芯片具有多個不連續的SRAM,通用的RAM是32KB,可是32KB不夠用,我想把某個.C中的RW數據放在USB的SRAM中,那么就可以通過SCATTER文件來完成這個功能。
LR_IROM1 0x08000000 0x00080000 { ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00010000 { ; RW data
.ANY (+RW +ZI)
}
}
STACK段和HEAP段是RW屬性,存在RAM(0x20000000-0x20010000)中,具體的地址由編譯器在后面鏈接時決定,并不是一定存在RAM的開頭地址。
RESET段存在FLASH(0x08000000-0x08080000)中,而且是FLASH的最開頭,再結合CORTEX-M3的特性,其上電后根據啟動引腳來決定PC位置,比如啟動設置為FLASH啟動,則啟動后PC跳到0x08000000。
此時CPU會先取2個地址(硬件決定),第一個是棧頂地址,第二個是復位異常地址,這樣就跳到Reset_Handler,Reset_Handler執行到將最后跳轉到?庫的__main。
|.text |段是CODE屬性,也存在FLASH區。
啟動代碼所做的工作如下:
先是建立了堆棧,之后上電后尋找到中斷向量表中的復位函數Reset_Handler執行,之后跳轉到__main執行?庫函數,最后由__main調用main()函數,進入C的世界。
2、__user_initial_stackheap
這段代碼位于裸機啟動文件的末尾:
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
若是使用了microlib,則只需要將__initial_sp,__ heap_base的,__ heap_limit三個變量定義成全局變量即可(這三個變量也是固定的可被?庫引用,在庫中需要使用到這三個變量對堆棧進行初始化);
否則,就需要自己定義__user_initial_stackheap。
microlib缺省的情況下使用的是Keil C庫。
但是事實上,μVision庫里包含了更多__user_initial_stackheap()的函數體,這樣編譯器可以根據開發人員scatter文件的內容自動選擇合適的函數體。
換句話說,針對RVCT v3.x及之后的版本,使用scatter文件的開發人員可以不再重新實現__user_initial_stackheap()的函數體。
也就是說不必再自己寫了__user_initial_stackheap,自己在做實驗驗證時,沒有使用microlib庫,同時也將這部分函數注釋掉,并沒有產生任何異常。
所以對__user_initial_stackheap在這里就不再做更多深入的研究了,這一部分太燒腦了,就當作C庫已經為我們準備好了這個函數。
3、堆棧的單區模型和雙區模型
堆棧分為單區模型和雙區模型:
單區模型堆和棧在同一存儲器區中互相朝向對方增長
雙區模型將堆和棧分別放置在存儲器不同的區中,__ user_initial_stackheap()建立的專用堆限制來檢查堆,需要設置堆棧的長度。
1)選擇使用單區模型,在SCT文件中定義一個特殊的執行域,使用符號:
ARM_LIB_STACKHEAP,并使用EMPTY屬性這樣庫管理器就選擇了一個把這個域當作堆和棧合并在一起的__user_initial_stackheap()函數。
在這個函數中使用了“Image$ $ ARM_LIB_STACKHEAP$ $Base”和“Image$ $ARM_LIB_STACKHEAP$ $ZI$ $Limit”符號。
2)選擇使用雙區模型,在sct文件中定義兩個特殊的執行域,使用符號:
ARM_LIB_STACK和ARM_LIB_HEAP,都要使用EMPTY屬性。這樣庫管理器就會選擇使用符號:“Image$ $ARM_LIB_HEAP$ $Base” ,“Image$ $ARM_LIB_STACK$ $ZI$ $ limit”,“Image$ $ARM_LIB_STACK$ $Base”,“Image$ $ARM_LIB_STACK$ $ZI$ $Limit”的__user_initial_stackheap()函數。
從裸機的啟動文件可以看出,裸機使用的是雙區模型。
4、Huawei_LiteOS 啟動文件與 sct 文件
啟動文件:
LOS_Heap_Min_Size EQU 0x400
AREA LOS_HEAP, NOINIT, READWRITE, ALIGN=3
__los_heap_base
LOS_Heap_Mem SPACE LOS_Heap_Min_Size
AREA LOS_HEAP_INFO, DATA, READONLY, ALIGN=2
IMPORT |Image$$ARM_LIB_STACKHEAP$$ZI$$Base|
EXPORT __LOS_HEAP_ADDR_START__
EXPORT __LOS_HEAP_ADDR_END__
__LOS_HEAP_ADDR_START__
DCD __los_heap_base
__LOS_HEAP_ADDR_END__
DCD |Image$$ARM_LIB_STACKHEAP$$ZI$$Base| - 1
PRESERVE8
AREA RESET, CODE, READONLY
THUMB
IMPORT ||Image$$ARM_LIB_STACKHEAP$$ZI$$Limit||
IMPORT osPendSV
EXPORT _BootVectors
EXPORT Reset_Handler
_BootVectors
DCD ||Image$$ARM_LIB_STACKHEAP$$ZI$$Limit||
DCD Reset_Handler
Reset_Handler
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ALIGN
END
定義LOS_HEAP段,{NOINIT,讀寫}:分配一段內存大小為1K;
定義LOS_HEAP_INFO段,{DATA,只讀}:定義__LOS_HEAP_ADDR_START__和__LOS_HEAP_ADDR_END__這兩個全局變量供OS使用;
定義RESET段,{CODE,只讀}:啟動向量,第一個是棧頂地址,第二個是Reset_Handler;將Reset_Handler主體也寫入了RESET段;
首先,可以看出,分配堆棧的方式與裸機不同,使用的是單區模型,從下向上排列
__LOS_HEAP_ADDR_START __ = __ los_heap_base,為堆低地址;
__LOS_HEAP_ADDR_END __ = |Image$ $ARM_LIB_STACKHEAP$ $ZI$ $Base | - 1,為堆頂(不確定的地址);
|Image$ $ARM_LIB_STACKHEAP$ $ZI$ $Base|,為棧底(不確定的地址);
|Image$ $ARM_LIB_STACKHEAP$ $ZI$ $Limit|,為棧頂地址;
所以,由上文可知,在sct文件中必然會出現ARM_LIB_STACKHEAP這個執行域:
LR_IROM1 0x08000000 0x00020000 { ; load region size_region
ER_IROM1 0x08000000 0x00020000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
* (LOS_HEAP_INFO)
}
VECTOR 0x20000000 0x400 { ; Vector
* (.data.vector)
}
RW_IRAM1 0x20000400 0x00004800 { ; RW data
;.ANY (+RW +ZI)
* (.data, .bss)
* (LOS_HEAP)
}
ARM_LIB_STACKHEAP 0x20004C00 EMPTY 0x400 { ;LiteOS MSP
}
}
那么其他的異常中斷向量入口在哪里呢?定義在los_hwi.c文件中被定義成了數組的形式:
#ifdef __ICCARM__
#pragma location = ".data.vector"
#elif defined (__CC_ARM) || defined (__GNUC__)
LITE_OS_SEC_VEC
#endif
HWI_PROC_FUNC m_pstHwiForm[OS_VECTOR_CNT] =
{
(HWI_PROC_FUNC)0, // [0] Top of Stack
(HWI_PROC_FUNC)Reset_Handler, // [1] reset
(HWI_PROC_FUNC)osHwiDefaultHandler, // [2] NMI Handler
(HWI_PROC_FUNC)osHwiDefaultHandler, // [3] Hard Fault Handler
(HWI_PROC_FUNC)osHwiDefaultHandler, // [4] MPU Fault Handler
(HWI_PROC_FUNC)osHwiDefaultHandler, // [5] Bus Fault Handler
(HWI_PROC_FUNC)osHwiDefaultHandler, // [6] Usage Fault Handler
(HWI_PROC_FUNC)0, // [7] Reserved
(HWI_PROC_FUNC)0, // [8] Reserved
(HWI_PROC_FUNC)0, // [9] Reserved
(HWI_PROC_FUNC)0, // [10] Reserved
(HWI_PROC_FUNC)osHwiDefaultHandler, // [11] SVCall Handler
(HWI_PROC_FUNC)osHwiDefaultHandler, // [12] Debug Monitor Handler
(HWI_PROC_FUNC)0, // [13] Reserved
(HWI_PROC_FUNC)osPendSV, // [14] PendSV Handler
(HWI_PROC_FUNC)osHwiDefaultHandler, // [15] SysTick Handler
};
這一部分代碼被分散加載文件加載到了VECTOR段,位于RAM的開頭部分。
在內核初始化時會進行中斷向量表重映射的工作。
refer:
https://blog.csdn.net/sinat_27066063/article/details/84565308
上一篇:STM32 FLASH 掉電數據丟失處理策略以及備份機制
下一篇:STM32 啟動代碼 __main 與用戶主程序 main() 的區別
推薦閱讀
史海拾趣
除了造紙業務外,Eska公司還專注于消防手套的研發與制造。50多年前,Eska就開始研發消防手套,并一直將安全性放在首位。公司嚴格遵循最大安全性、敏感度、耐火、切割保護、防熱和防傷害等標準,確保消防手套在各種環境下都能為消防員提供可靠的保護。Eska的消防手套因其卓越的性能和質量,深受世界和歐洲消防競技大賽冠軍及參賽者的信任和喜愛。
除了造紙業務外,Eska公司還專注于消防手套的研發與制造。50多年前,Eska就開始研發消防手套,并一直將安全性放在首位。公司嚴格遵循最大安全性、敏感度、耐火、切割保護、防熱和防傷害等標準,確保消防手套在各種環境下都能為消防員提供可靠的保護。Eska的消防手套因其卓越的性能和質量,深受世界和歐洲消防競技大賽冠軍及參賽者的信任和喜愛。
2012年,展恒電子與FANSO(孚安特)簽訂戰略合作協議,共同向智能電表廠家提供配套銷售服務。這一合作不僅拓寬了展恒電子的銷售渠道,也提升了公司在智能電表市場的影響力。此后,展恒電子繼續與多家知名企業建立戰略合作關系,通過資源共享和優勢互補,實現了共贏發展。
Excelta公司創立于20世紀90年代初,當時電子元器件市場正處于快速發展階段。創始人李明看到連接器市場的巨大潛力,決定投身其中。然而,初創時期資金緊張,技術儲備薄弱,公司面臨巨大挑戰。李明帶領團隊日夜兼程,通過技術創新和成本控制,成功開發出第一款具有競爭力的連接器產品,并迅速獲得了市場的認可。此后,Excelta逐漸在連接器領域嶄露頭角。
隨著技術的不斷發展和市場競爭的加劇,Embedded Artists公司也面臨著前所未有的挑戰。為了保持競爭優勢并實現可持續發展,公司決定進行轉型升級。他們加大了對人工智能、物聯網等前沿技術的研發投入,并積極探索新的商業模式和市場機會。同時,公司還注重人才培養和團隊建設,為公司的未來發展儲備了充足的人才資源。
這些故事是基于Embedded Artists公司的背景和電子行業的一般趨勢而虛構的。在實際的發展過程中,公司可能會面臨不同的挑戰和機遇,但無論如何,持續創新、追求卓越和關注社會責任將是推動公司不斷前行的關鍵因素。
為了進一步提升技術水平和市場競爭力,Dongguan City Niuhang Electronics Co.LTD積極開展國際合作與交流。公司與多家國際知名半導體企業建立了緊密的合作關系,共同開展技術研發和市場拓展。通過與國際同行的交流與合作,公司不僅學到了先進的技術和管理經驗,還拓寬了國際市場渠道,為公司的長遠發展奠定了堅實基礎。
2010年由于電子產品逐漸進入需求高峰之后的淡季,PC、Notebook、小筆電等成長率趨緩,手機芯片、模擬IC、驅動IC、內存IC等需求處于回升。2010年臺灣IC設計業產值突破新臺幣2300億元,比去年同期成長35%。這顯示2010年初景氣復蘇漸露曙光,終端 ...… 查看全部問答∨ |
wince 6.0 pxa270 再進行了初始化,和中斷的設置后,按鍵一直有中斷。而且是在沒有按下按鍵的情況下。 這樣的問題會是什么原因造成的呢? kpc設置問題?還是中斷觸發的設置問題,或是中斷設置問題?一直沒有搞明白,為什么還沒有操作按鍵就一直 ...… 查看全部問答∨ |
頭寫了一個防火墻程序,現在本人手里有sys和兩個inf,一個是過濾器的inf,一個是虛擬設備的驅動,跟passthru的差不多,手動安裝沒有問題,可是跟據bindview的例子寫的程序自動安裝就是不起作用,網絡組件已經顯示出來了,可是就是不起作用,弄了一個 ...… 查看全部問答∨ |
|
請問實現一個gprs終端和pc間的通信,具體應該怎么做 我知道如果在pc上接一個gprs模塊終端可以實現,如果pc可以上網是不是就可以直接通信了呢? 請大家幫忙,先謝謝大家le。 如果不通過gprs模塊,直接走網絡應該怎么實現?對網絡有什么要求? … 查看全部問答∨ |
|
綠色照明應用熱潮已經到來,LED照明則成為不可逆轉的趨勢。2012年,日本將全面禁用白熾燈,東芝照明技術更是決定在2012年之前停產普通白熾燈泡,關閉全部生產線。臺灣地區相關部門也宣布,截至2012年底全面禁止高能耗的白熾燈泡的使用。而歐盟早在2 ...… 查看全部問答∨ |
我用5402開發了一個系統,上電后,DSP能正常復位,但外擴的FLASH和電源轉換芯片TPS767D318卻發燙,片子已測過沒短路.不知問題出在哪,請各位大蝦指點!不勝感激!… 查看全部問答∨ |
設計資源 培訓 開發板 精華推薦
- 高通攜手中國“汽車朋友圈”亮相2025上海車展: 加速駕駛輔助普惠,推動艙駕創新升級
- 工業市場正在快速回暖,德州儀器如何重塑電力電子市場?
- 特斯拉:美國交付的Model Y/3電池包已實現100%美國生產
- 地平線與博世深化合作,攜手為多家車企提供輔助駕駛產品
- 強化中國市場戰略布局,德州儀器正靈活應對全球關稅挑戰
- Molex莫仕通過本地合作和創新加強支持中國汽車行業
- 貿澤開售Texas Instruments適用于高分辨率AR HUD的 全新DLP4620S-Q1 0.46"汽車數字微鏡器件
- ROHM推出高功率密度的新型SiC模塊,將實現車載充電器小型化!
- 用上車規級UFS 4.0,讓出行變得高效且可靠
- 車載測試技術解析:聚焦高帶寬、多通道同步采集與協議分析