eCos啟動過程詳解,基於Cortex M架構

2021-06-18 19:12:40 字數 4579 閱讀 2850

ecos是開源免版稅的搶占式實時作業系統。其最大亮點是可配置,與其配套的圖形化配置工具提供元件管理、選項配置、自動化單元測試等。ecos核心元件包括硬體抽象層(hal)、裝置驅動(io)、實時核心(兩種排程演算法可選)、執行緒安全的c庫、posix相容層、檔案系統(fat、jffs2、romfs)、協議棧(lwip、openbsd、freebsd)、圖形系統(nano-x)等,同時支援第三方擴充套件元件。官網中文專業論壇

mingdu.zheng gmail com

cortex-m將執行模式分成handler模式和thread模式,進入異常或中斷處理則進入handler模式,其他情況則為thread模式。cortex-m有兩個執行級別,分別為特權級和使用者級(非特權級),handler模式總是執行在特權級,而thread模式可以執行在特權級也可以執行在使用者級,這通過control特殊暫存器控制。cortex-m的堆疊暫存器sp對應兩個物理暫存器msp和psp,msp為主堆疊,psp為程序堆疊,handler模式總是使用msp作為堆疊,thread模式可以選擇使用msp或psp作為堆疊,同樣通過control特殊暫存器控制。

復位後,cortex-m進入thread模式、特權級、使用msp堆疊,並從向量表項0處取sp暫存器值,從向量表項1處取pc暫存器值,然後從pc暫存器值處開始執行,一般情況下預設向量表儲存在位址0x00000000處,不同的變種其預設向量表可能不同。

cortex-m復位後首先從預設向量表處讀取sp初始值和pc初始值。為了讓cortex-m復位後立即有可用的復位向量,必須將向量表儲存在rom中,然後在初始化過程可選地將向量表位址對映到其它區域。ecos為cortex-m準備的向量表主要是儲存在ram中,因為ecos需要支援修改向量表項,但是仍然要為復位動作準備儲存在rom中的向量表,rom中的向量表僅有兩項,分別為sp初始值和pc初始值,剛好滿足cortex-m復位的需求。

// hal/cortexm/arch//src/vectors.s:79

.section ".vectors","ax"

.global hal_vsr_table

hal_vsr_table_init:

.long hal_startup_stack

.long hal_reset_vsr

(2)通過.section偽指令將向量表儲存在.vectors節,.vectors會在target.ld鏈結控制檔案中特殊對待,將其定位到指定的位址,一般情況下為0x00000000,這是cortex-m復位後的向量表起始位址。

(5)向量表項0為堆疊位址,cortex-m的堆疊為遞減的滿棧,因此這裡的值應當為堆疊最高位址+1,例如堆疊空間分配在0x20001000~0x20001fff,那麼這裡應當為0x20002000。hal_startup_stack符號是在target.ld中定義的。

(6)向量表項1為復位向量,儲存初始化函式位址,這裡為hal_reset_vsr,是在hal_misc.c中定義的c函式。

在除錯過程中,不會產生復位來初始化sp和pc,為了能夠配合除錯軟體模擬復位過程的sp和pc暫存器的初始化,ecos提供了偽入口,偽入口將初始化sp,並跳轉到初始化函式hal_reset_vsr。

// hal/cortexm/arch//src/vectors.s:100

.type reset_vector, %function

reset_vector:

ldr sp,=hal_startup_stack

b hal_reset_vsr

(2)reset_vector是個普通函式,不需要定位到特殊位置,target.ld將reset_vector設定為入口位址,偵錯程式引導程式後會將pc指向reset_vector所在的位址。

(4)模擬復位時讀取向量0初始化sp的過程。

(5)模擬復位時跳轉到向量1所指函式的過程,這裡是hal_reset_vsr。

整個初始化過程主要由hal_reset_vsr函式完成,hal_reset_vsr函式的基本流程:呼叫平台相同的系統初始化、初始化異常向量表、更改執行模式、初始化資料區、初始化中斷向量表、呼叫變種初始化函式、呼叫平台初始化函式、呼叫全域性靜態物件建構函式、呼叫cyg_start進入使用者**。

// hal/cortexm/arch//src/hal_misc.c:131

void hal_reset_vsr( void )

(4)初始化ram中.data段,初始化資料被儲存在rom中,因此將rom中的初始化資料拷貝到ram即可,這裡ram可能是晶元內部sram的一部分,也有可能是外部擴充套件的sram或dram,根據系統配置不同而不同。

(12)初始化sram中的.data段,初始化資料被儲存在rom中,因此將rom中的初始化資料拷貝到ram即可,sram指的是晶元內部的sram。

(20)將.bss段的資料清零,凡是儲存在.bss段的資料,要麼其定義時的初始值被賦值為0,要麼沒有定義初始值,這兩種情況下,均將其清零。

疑問:.data被分成內部ram和外部ram兩種情況,為什麼.bss欄位沒有考慮兩部分呢?

// hal/cortexm/arch//src/hal_misc.c:240

}

(5)將儲存器管理fault異常、匯流排fault異常、用法fault異常的優先順序設定為0,在ecos中,中斷的優先順序至少大於0,因此這三個異常比任何中斷的優先順序都高,這也是合理的,異常比中斷更要緊。優先順序暫存器是8位的,這裡使用32位方式寫,一次寫4個優先順序。

(6)將svc異常優先順序設定為0xff,這是cortex-m的最低優先順序,也就是說svc異常的優先順序低於任何中斷優先順序。

(7)將pendsvc異常優先順序設定為0xff,systick異常優先順序設定為0。

(9)設定systick的中斷服務函式為預設中斷服務函式hal_default_isr,上文提到過,ecos將cortex-m中16個系統異常中的systick異常作為中斷處理,而且是第0號中斷。

(13)將其餘的中斷服務函式均設定成預設中斷服務函式hal_default_isr。

(14)設定中斷優先順序初始值為0x80,這個優先順序高於svc異常和pendsvc異常的優先順序,低於fault異常的優先順序。但systick的優先順序被設定為0。

疑問:systick是否應該和其它中斷一致對待,設定其預設優先順序為0x80?

接下來使能用法fault異常、匯流排fault異常和儲存器管理fault異常,這讓ecos有機會捕獲異常並通知偵錯程式或核心。在fault異常遮蔽的情況,如果發生異常將會上訪成硬體fault異常。

// hal/cortexm/arch//src/hal_misc.c:278

hal_read_uint32( base+cygarc_reg_nvic_shcsr, shcsr );

shcsr |= cygarc_reg_nvic_shcsr_usgfaultena;

shcsr |= cygarc_reg_nvic_shcsr_busfaultena;

shcsr |= cygarc_reg_nvic_shcsr_memfaultena;

hal_write_uint32( base+cygarc_reg_nvic_shcsr, shcsr );

同樣是基於cortex-m,不同的晶元系列會有不同的外設,每個系列有其對應的變體hal層,通過hal_variant_init初始化變體層hal。

// hal/cortexm/arch//src/hal_misc.c:287

hal_variant_init();

相同的晶元還被應用於不同的目標機,每個目標機都有其對應的平台hal層,通過hal_platform_init初始化平台層hal,平台層初始化可以包括部分外圍器件的初始化。

// hal/cortexm/arch//src/hal_misc.c:288

hal_platform_init();

滴答定時器是作業系統的脈搏,這裡初始化滴答定時器,需要注意的是,這裡進行的初始化工作進行設定合適的暫存器值,然後讓滴答定時器自由執行,並不會產生中斷,滴答定時器的中斷向量安裝和中斷使能通過核心的時鐘模組完成。

// hal/cortexm/arch//src/hal_misc.c:291

hal_clock_initialize( cygnum_hal_rtc_period );

參考《ecos元件初始化》

// hal/cortexm/arch//src/hal_misc.c:307

cyg_hal_invoke_constructors();

// hal/cortexm/arch//src/hal_misc.c:307

cyg_start();

for(;;);

(2)進入使用者**cyg_start,如果使用者**入口不是cyg_start,那麼ecos將提供預設實現的cyg_start,並在cyg_start中呼叫使用者入口**cyg_user_start或者main。

(3)嵌入式系統中,進入使用者**後,無論有沒有包括核心支援都不應該返回到這裡,如果萬一返回到這裡,那麼將進入死迴圈,除了消耗cpu週期啥也不做。

iOS APP啟動過程詳解

int argc,char argv,nsstring principalclassname,nsstring delegateclassname 應用程式啟動完畢。當由於其它方法開啟應用程式 如url指定或者連線 通知委託啟動完畢 通知委託,應用程式將在關閉 退出,請做一些清理工作。通知委託,應用...

PC啟動過程詳解

系統啟動過程 1.預引導 pre boot 階段 2.引導階段 3.載入核心階段 4.初始化核心階段 5.使用者登入階段 基本概念 bios 即 basic input output system 基本輸入輸出系統 它是一組被 固化 在計算機主機板上的一塊rom中直接關聯硬體的程式,儲存著計算機最重...

tomcat啟動過程詳解

基於j a的web 應用程式是 servlet jsp 頁面 靜態頁面 類和其他資源的集合,它們可以用標準方式打包,並執行在來自多個 商的多個容器。web 應用程式存在於結構化層次結構的目錄中,該層次結構是由 j a servlet 規範定義的。web 應用程式的根目錄包含直接儲存或儲存在子資料夾中...