分享到plurk 分享到twitter 分享到facebook

版本 36a9c645d2bd7f41f50de3884f41637bff5916b5

FreeRTOS

組員

  • 梁穎睿 / TheKK
  • 李奇霖 / Shinshipower
  • 方威迪 / waynew30777
  • 陳盈伸 / shin21

共筆

  • Link<https://hackpad.com/FreeRTOSV8.0.0-PU3awKuzHz6#:h=%3Chardware-interfacing%3E>_

FreeRTOS架構

FreeRTOS是一個相對較小的應用程序。最小化的FreeRTOS內核僅包括3個(.c)文件和少數頭文件,總共不到9000行代碼,還包括了註釋和空行。一個典型的編譯後(二進制)代碼映像小於10KB。

FreeRTOS的代碼可以分解為三個主要區塊:任務,通訊,和硬件接口。

●任務:大約有一半的FreeRTOS的核心代碼用來處理多數操作系統首要關注的問題:任務。任務是給定優先級的用戶定義的C函數。 task.c和task.h完成了所有有關創建,調度,和維護任務的繁重工作。

●通訊:任務很重要,不過任務間可以互相通訊則更為重要!它給我們帶來FreeRTOS的第二項任務:通訊。大約40%的FreeRTOS核心代碼是用來處理通訊的。 queue.c和queue.h是負責處理FreeRTOS的通訊的。任務和中斷使用隊列互相發送數據,並且使用信號燈和互斥來發送臨界資源的使用情況。

●硬件接口:接近9000行的代碼拼湊起基本的FreeRTOS,是硬件無關的;相同的代碼都能夠運行,不論FreeRTOS是運行在不起眼的8051,還是最新、最炫的ARM內核上。大約有6%的FreeRTOS的核心代碼,在硬件無關的FreeRTOS內核與硬件相關的代碼間扮演著墊片的角色。我們將在下個部分討論硬件相關的代碼。

硬體方面:

portmacro.h:

定義了硬體相關變數,如資料形態定義,以及硬體相關的函式呼叫的名稱定義(以portXXXXX爲名)等,統一各平臺呼叫函式的

port.c:

定義了包含和硬體相關的程式碼的實作

FreeRTOSConfig.h:

包含Clock speed, heap size, mutexes等等都在此定義

Task的狀態

.. image:: /Task狀態.png

  • Ready : FreeRTOS將各種優先權的Task放在Readylist

  • Running : 透過FreeRTOS的排程,依照優先權的高低依序給CPU執行

  • Block :

  • Suspended :

  • Ready list的資料形態

<> >>變數 char類型:以 c 為字首 short類型:以 s 為字首 long類型:以 l 為字首 float類型:以 f 為字首 double類型:以 d 為字首 Enum變數:以 e 為字首 其他(如struct):以 x 為字首 pointer有一个額外的字首 p , 例如short類型的pointer字首為 ps unsigned類型的變數有一個額外的字首 u , 例如unsigned short類型的變數字首為 us

Functions 文件内:以 prv 為字首 API:以其return類型為字首,按照對變數的定義 名字:以其所在的文件名開頭。如vTaskDelete即在Task.c文件中名稱

  • FreeRTOS使用ready list去管理待準備好要執行的tasks而ready list的資料儲存方式如下圖

.. image:: /freertos-figures-full-ready-list-2.png

  • Context Switch 時選出下一個欲執行的task

下面是在ready list中依照優先度選取執行目標的程式其中,FreeRTOS的優先度排序最小優先權爲0,數字越大則優先權越高

.. code-block:: prettyprint

/* In file: Source/tasks.c */
while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )
{
    configASSERT( uxTopReadyPriority );
    --uxTopReadyPriority;
}
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );

/*In file: Source/include.h */
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )
{
    List_t * const pxConstList = ( pxList );
    /* Increment the index to the next item and return the item, ensuring */
    /* we don't return the marker used at the end of the list.  */
    ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; 
    if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )  \
    {
        ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;
    }
    ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;
}
  • 創造全新task

TCB的資料結構:

.. code-block:: prettyprint

typedef struct tskTaskControlBlock { volatile portSTACK_TYPE pxTopOfStack; / Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */

xListItem xGenericListItem; /* List item used to place the TCB in ready and blocked queues. / xListItem xEventListItem; / List item used to place the TCB in event lists./ unsigned portBASE_TYPE uxPriority; / The priority of the task where 0 is the lowest priority. / portSTACK_TYPE pxStack; /* Points to the start of the stack. / signed char pcTaskName[ configMAX_TASK_NAME_LEN ]; / Descriptive name given to the task when created. Facilitates debugging only. */

#if ( portSTACK_GROWTH > 0 ) portSTACK_TYPE pxEndOfStack; / Used for stack overflow checking on architectures where the stack grows up from low memory. */ #endif

#if ( configUSE_MUTEXES == 1 ) unsigned portBASE_TYPE uxBasePriority; /* The priority last assigned to the task - used by the priority inheritance mechanism. */ #endif

} tskTCB; * 硬體驅動原理 ———– * 以 GPIO</embedded/GPIO>_ 為例 - 參考 STM32Cube_FW_F4_V1.1.0/Projects/STM32F429I-Discovery/Examples/GPIO/GPIO_EXTI/readme.txt 創造全新task TCB的資料結構:

效能表現

參考資料

  • The Architecture of Open Source Applications: FreeRTOS<http://www.aosabook.org/en/freertos.html>_
    • 簡體中文翻譯<http://www.ituring.com.cn/article/4063>_
  • Study of an operating system: FreeRTOS</embedded/FreeRTOS_Melot.pdf>_
  • FreeRTOS 即時核心實用指南</embedded/FreeRTOS-manual-zh.pdf>_