FreeRTOS內核源碼解讀之-------系統啓動(一)

  • RTOS多任務運行
  • Cortex-M4對於多任務運行的硬件架構支持特性
    最近研究FreeRTOS的內核源碼,產生了一個疑問?
//創建開始任務
    xTaskCreate((TaskFunction_t )start_task,            //任務函數
                (const char*    )"start_task",          //任務名稱
                (uint16_t       )START_STK_SIZE,        //任務堆棧大小
                (void*          )NULL,                  //傳遞給任務函數的參數
                (UBaseType_t    )START_TASK_PRIO,       //任務優先級
                (TaskHandle_t*  )&StartTask_Handler);   //任務句柄  

//創建TASK1任務
    xTaskCreate((TaskFunction_t )malloc_task,             
                (const char*    )"malloc_task",           
                (uint16_t       )MALLOC_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )MALLOC_TASK_PRIO,        
                (TaskHandle_t*  )&MallocTask_Handler);   
    vTaskDelete(StartTask_Handler); //刪除開始任務

只要通過FreeRTOS提供的任務創建函數API就能夠運行我們應用層寫的代碼。換句話說,FreeRTOS是怎麼找到我們寫的代碼,然後進行運行的呢?首先看一下任務創建函數聲明:

BaseType_t xTaskCreate(	TaskFunction_t pxTaskCode,
							const char * const pcName,
							const uint16_t usStackDepth,
							void * const pvParameters,
							UBaseType_t uxPriority,
							TaskHandle_t * const pxCreatedTask ) 

參數說明如下:
pxTaskCode:我們應用程序編寫的任務函數指針;
pcName:任務的名字,應用層自己設定;
usStackDepth:每一個任務堆棧的深度,我們這裏是32位MCU,那麼堆棧深度爲usStackDepth*4字節;
pvParameters:執行的任務函數時傳遞的參數;
uxPriority:任務的優先級;
pxCreatedTask:任務句柄,實際就是指向任務控制塊指針。
在這裏我要用兩篇博客進行探究上述問題。其中,第一篇會從MCU硬件架構方面是怎麼能夠支持上述功能的(這裏分析的是STM32F407 MCU,該MCU是基於Cortex-M4架構);第二篇會實際分析FreeRTOS具體實現方法。

一、RTOS多任務運行

在這裏插入圖片描述實時操作系統RTOS可用於處理任務調度,它是將處理時間分爲多個時間片且將時間片分配給所需的任務,實現多個任務同時執行。需要一個定時器記錄RTOS中每個人物的運行時間,當時間到之後就會觸發任務調度器執行上下文切換,轉而執行其他任務。

二、Cortex-M4對於多任務運行的硬件架構支持特性

1、寄存器組

在這裏插入圖片描述Cortex-M4處理器的寄存器組中含有16個寄存器,其中13個是32位通用目的寄存器,3個特殊寄存器。
1)R0~R12
前8個被稱作低寄存器,由於指令中可用的空間有限,許多16位指令只能訪問低寄存器。後面4個寄存器被稱爲高寄存器,可以用於32位指令和幾個16位指令。
2)R13,棧指針(SP)
可以通過PUSH和POP操作實現棧存儲的訪問,其實在物理上會有兩個棧指針。MSP被稱爲主棧指針,復位後或者處於處理模式時會使用該針;PSP進程棧指針,只能用於線程模式。在進行PUSH和POP時候總是32位,棧操作的地址必須對齊到32位的字邊界上。一般如果我們的應用程序中沒有涉及到嵌入式OS是不會用到PSP寄存器的,但是如果用到嵌入式OS就必須設置PSP。
3)R14,連接寄存器(LR)
函數或者子程序調用時返回地址的保存,在函數或者子程序結束時,程序控制可以通過將LR的數值加載到PC寄存器中實現返回調用的程序。***當執行函數或者子程序調用後,LR寄存器的數值會自動更新。***因此在調用函數之前要先把LR的數值保存到棧中。
在異常處理期間,LR會被自動更新爲特殊的EXC_RETURN(異常返回)的數值,之後該數值在異常處理結束之後出發異常返回。
4)程序計數器PC
可讀可寫,寫會導致跳轉。

2、EXC_RETURN

在這裏插入圖片描述
在這裏插入圖片描述
處理器進入異常處理或者中斷服務程序時,連接寄存器LR的數值會被更新爲EXC_RETURN。利用BX指令加載到PC寄存器時,該數值就會觸發異常返回機制。由於地址區域0xF0000000~0xFFFFFFFF被架構定義爲不可執行,這樣不會帶來問題。

3、影子棧指針

在這裏插入圖片描述由於在物理上採用兩個棧指針寄存器,因此可以將處理器處於不同模式下使用不同的棧指針,這樣我們在內核和異常處理狀態下使用MSP,在普通任務下使用PSP,使得應用層與內核層完全分離。當我們應用層的代碼出現BUG可以減少對內核層代碼的影響,保證了軟件的健壯性。
5)SVC異常
由SVC指令觸發,異常類型爲11,並且優先級是可編程的。利用SVC可以實現應用任務訪問系統資源的API,如下圖所示:
在這裏插入圖片描述
在FreeRTOS中使用SVC異常從出初始化切換到調度第一個任務。

總結:本文主要介紹了Cortex-m4對於RTOS支持的硬件特性,下一篇文章將會介紹FreeRTOS是怎樣利用這些特性開啓第一個任務的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章