FreeRTOS初步认识
源:FreeRTOS初步認識
?
用了半天時間對FreeRTOS有了一個初步的認識,大概總結一下,其中混雜了系統實現和實際應用方面的問題。
現只是以應用為目的,實現方面待以后進一步研究。
1.FreeRTOS提供的功能包括:任務管理、時間管理、信號量、消息隊列、內存管理。與平臺有關的文件包含在portable文件夾中,主要是port.c, portmacro.h兩個文件。平臺無關的文件主要是:list.c(基本鏈表結構), queue.c(包括消息隊列,信號量的實現), croutine.c,tasks.c(任務管理,時間管理)。
命名協定
RTOS內核與范例程序源代碼使用下面的協定:
?
變量
char類型的變量以 c 為前綴
short類型的變量以 s 為前綴
long類型的變量以 l 為前綴
float類型的變量以 f 為前綴?
????? double類型的變量以 d 為前綴
枚舉變量以 e 為前綴 其他類型(如結構體)以 x 為前綴
指針有一個額外的前綴 p , 例如short類型的指針前綴為 ps
無符號類型的變量有一個額外的前綴 u , 例如無符號short類型的變量前綴為 us
?
函數
文件內部函數以prv為前綴
API函數以其返回值類型為前綴,按照前面對變量的定義
函數的名字以其所在的文件名開頭。如vTaskDelete函數在Task.c文件中定義
數據類型
數據類型并不直接在RTOS內核內部引用。相反,每個平臺都有其自身的定義方式。例如,char類型定義為portCHAR,short類型定義為portSHORT等。范例程序源代碼使用的就是這種符號,但這并不是必須的,你可以在你的程序中使用任何你喜歡的符號。
此外,有兩種額外的類型要為每種平臺定義。分別是:
portTickType
可配置為16位的無符號類型或32位的無符號類型。參考API文檔中的 定制部分獲取詳細信息。
portBASE_TYPE
為特定體系定義的最有效率的數據類型。
如果portBASE_TYPE定義為char則必須要特別小心的保證用來作為函數返回值的signed char可以為負數,用于指示錯誤。
?
2. FreeRTOS內核支持優先級調度算法,每個任務可根據重要程度的不同被賦予一定的優先級,CPU總是讓處于就緒態的、 優先級最高的任務先運行。FreeRT0S內核同時支持輪換調度算法,系統允許不同的任務使用相同的優先級,在沒有更高優先級任務就緒的情況下,同一優先級的任務共享CPU的使用時間。
?
3.freertos既可以配置為可搶占內核也可以配置為不可搶占內核。當FreeRTOS被設置為可剝奪型內核時,處于就緒態的高優先級任務能剝奪低優先級任務的CPU使用權,這樣可保證系統滿足實時性的要求;當FreeRTOS被設置為不可剝奪型內核時,處于就緒態的高優先級任務只有等當前運行任務主動釋放CPU的使用權后才能獲得運行,這 樣可提高CPU的運行效率。
?
4.任務管理
系統為每個任務分配一個TCB結構
typedef struct tskTaskControlBlock {volatile portSTACK_TYPE *pxTopOfStack;//指向堆棧頂xListItem xGenericListItem; //通過它將任務連入就緒鏈表或者延時鏈表或者掛起鏈表中, xListItem包含其TCB指針xListItem xEventListItem;//通過它把任務連入事件等待鏈表unsigned portBASE_TYPE uxPriority;//優先級portSTACK_TYPE *pxStack; //指向堆棧起始位置 signed portCHAR pcTaskName[ configMAX_TASK_NAME_LEN ];//......省略一些次要結構 } tskTCB;?
系統的全局變量:
static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; 就緒隊列static xList xDelayedTaskList1; static xList xDelayedTaskList2; 兩個延時任務隊列 static xList * volatile pxDelayedTaskList; static xList * volatile pxOverflowDelayedTaskList; 兩個延時隊列的指針,應該是可互換的。static xList xPendingReadyList; static volatile xList xTasksWaitingTermination; 等待結束隊列static volatile unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0; 結束隊列中的個數?????static xList xSuspendedTaskList; 掛起隊列static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks;記錄了當前系統任務的數目static volatile portTickType xTickCount;是自啟動以來系統運行的ticks數static unsigned portBASE_TYPE uxTopUsedPriority;記錄當前系統中被使用的最高優先級,static volatile unsigned portBASE_TYPE uxTopReadyPriority;記錄當前系統中處于就緒狀態的最高優先級。static volatile signed portBASE_TYPE xSchedulerRunning ;表示當前調度器是否在運行,也即內核是否啟動了?
任務建立和刪除,掛起和喚醒
?
?
5.時間管理 ?????
操作系統總是需要個時鐘節拍的,這個需要硬件支持。freertos同樣需要一個time tick產生器,通常是用處理器的硬件定時器來實現這個功能。(時間片輪轉調度中和延時時間控制??)
它周期性的產生定時中斷,所謂的時鐘節拍管理的核心就是這個定時中斷的服務程序。freertos的時鐘節拍isr中除去保存現場,灰度現場這些事情外,核心的工作就是調用vTaskIncrementTick()函數。vTaskIncrementTick()函數主要做兩件事情:維護系統時間(以tick為單位,多少個節拍);處理那些延時的任務,如果延時到期,則喚醒任務。
?
任務可用的延時函數:vTaskDelay();vTaskDelayUntil();
特別之處在于vTaskDelayUntil()是一個周期性任務可以利用它可以保證一個固定的(確定的)常數執行頻率,而vTaskDelay()無法保證。
?
6.任務間的通信(詳見“FreeRTOS任務間通訊”)
1)當然可以用全局變量的形式通信,但是不安全。
2)隊列(xQueueHandle)是FreeRTOS中通信所需的主要數據結構。
3)信號量(xSemaphoreHandle),有二進制信號量,計數信號量和互斥信號量,其都是以隊列為基礎結構建立。
二進制信號量可以用于中斷和任務間的同步。也就是說希望任務隨外部中斷而執行。即外設給出“數據已就緒”信號,系統中斷,任務收到此中斷信號接收數據。
互斥一般用于都共享資源或數據結構的保護。因為任務調度不能保證數據不被破壞。當一個任務需要訪問資源,它必須先獲得 ('take') 令牌;當訪問結束后,它必須釋放令牌 - 允許其他任務能夠訪問這個資源。(對此還有待進一步實驗研究)。
?
7.系統配置
freeRTOS 配置在:FREERTOS_CONFIG.H 里面,條目如下:?
/* 是否配置成搶先先多任務內核,是1的時候,優先級高的任務優先執行。 為0任務就沒有優先級之說,用時間片輪流執行 */
#define configUSE_PREEMPTION??????????????? 1?
?
/* IDLE任務的HOOK函數,用于OS功能擴展,需要你自己編相應函數, 名字是void vApplicationIdleHook( void ) */
#define configUSE_IDLE_HOOK?????????????????? 0????
?
/* SYSTEM TICK的HOOK函數,用于OS功能擴展,需要你自己編相應函數, 名字是 void vApplicationTickHook(void ) */
?#define configUSE_TICK_HOOK???????????????? 0?
?
/* 系統CPU頻率,單位是Hz */
#define configCPU_CLOCK_HZ????????????????? 58982400?
?
/* 系統SYSTEM TICK每秒鐘的發生次數, 數值越大系統反應越快,但是CPU用在任務切換的開銷就越多 */
#define configTICK_RATE_HZ?????????????????? ?? 250?
/* 系統任務優先級數。5 說明任務有5級優先度。這個數目越大耗費RAM越多 */
#define configMAX_PRIORITIES????????????????????? 5??
?
/* 系統最小堆棧尺寸,注意128不是128字節,而是128個入棧。比如ARM32位,128個入棧就是512字節 */?
#define configMINIMAL_STACK_SIZE??????????? 128?
?
/* 系統可用內存。一般設成除了操作系統和你的程序所用RAM外的最大RAM。 比如20KRAM你用了2K,系統用了3K,剩下15就是最大HEAP 尺寸。你可以先設小然后看編譯結果往大里加*/
#define configTOTAL_HEAP_SIZE?????????????????????? 10240
?
/* 任務的PC名字最大長度,因為函數名編譯完了就不見了,所以追蹤時不知道哪個名字。16表示16個char */
#define configMAX_TASK_NAME_LEN???????????? 16
?
/* 是否設定成追蹤,由PC端TraceCon.exe記錄,也可以轉到系統顯示屏上 */
#define configUSE_TRACE_FACILITY???????????????? ?0
?
/* 就是SYSTEM TICK的長度,16是16位,如果是16位以下CPU, 一般選1;如果是32位系統,一般選0 */
#define configUSE_16_BIT_TICKS????????????????????????? 0
?
/* 簡單理解以下就是和IDLE TASK同樣優先級的任務執行情況。建議設成1,對系統影響不大 */
#define configIDLE_SHOULD_YIELD???????????????????? 1
?
/* 是否用MUTEXES。 MUTEXES是任務間通訊的一種方式,特別是用于任務共享資源的應用,比如打印機,任務A用的時候就排斥別的任務應用,用完了別的任務才可以應用 */
#define configUSE_MUTEXES??????????????????????????????? ???? 0??
?
/* ?確定是否用遞歸式的MUTEXES */
#define configUSE_RECURSIVE_MUTEXES????????????? 0
?
/* 是否用計數式的SEMAPHORES,SEMAPHORES也是任務間通訊的一種方式 */
#define configUSE_COUNTING_SEMAPHORES?????? 0
?
/* 是否應用可切換式的API。freeRTOS 同一功能API有多個,有全功能但是需求資源和時間較多的,此項使能后就可以用較簡單的API, 節省資源和時間,但是應用限制較多 */
#define configUSE_ALTERNATIVE_API????????????????????? ?0
?
?/* 此項用于DEBUG,來看是否有棧溢出,需要你自己編相應檢查函數void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed portCHAR *pcTaskName )? */
#define configCHECK_FOR_STACK_OVERFLOW????? 0
?
/* 用于DEBUG,登記SEMAPHORESQ和QUEUE的最大個數,需要在任務用應用函數vQueueAddToRegistry()和vQueueUnregisterQueue()? */
#define configQUEUE_REGISTRY_SIZE??????????????????????? 10?
?
?/* 設定可以改變任務優先度 */
?#define INCLUDE_vTaskPrioritySet????????????????????????????? ?1
?
?/* 設定可以查詢任務優先度 */
#define INCLUDE_uxTaskPriorityGet???????????????????????????? ?1
?
?/* 設定可以刪除任務 */
?#define INCLUDE_vTaskDelete?????????????????????????????????????? 1????
?
/* 據說是可以回收刪除任務后的資源(RAM等)*/
?#define INCLUDE_vTaskCleanUpResources???????????????? 0?
?
/* 設置可以把任務掛起 */
#define INCLUDE_vTaskSuspend?????????????????????????????????????1?
?
/* 設置可以從中斷恢復(比如系統睡眠,由中斷喚醒 */
#define INCLUDE_vResumeFromISR?????????????????????????????? ?1?
?
?/* 設置任務延遲的絕對時間,比如現在4:30,延遲到5:00。時間都是絕對時間 */
#define INCLUDE_vTaskDelayUntil????????????????????????????????? 1?
?
?/* 設置任務延時,比如延遲30分鐘,相對的時間,現在什么時間,不需要知道 */
#define INCLUDE_vTaskDelay???????????????????????????????????????????1??
?
/* 設置 取得當前任務分配器的狀態 */
#define INCLUDE_xTaskGetSchedulerState????????????????????? 1
?
/* 設置當前任務是由哪個任務開啟的 */
#define INCLUDE_xTaskGetCurrentTaskHandle????????????? 1?
?
/* 是否使能這一函數,還數的目的是返回任務執行后任務堆棧的最小未用數量,同樣是為防止堆棧溢出 */
#define INCLUDE_uxTaskGetStackHighWaterMark?????? 0?
?
/* 是用用協程。協程公用堆棧,節省RAM,但是沒有任務優先級高,也無法和任務通訊 */
#define configUSE_CO_ROUTINES?????????????????????????????????? 0???
?
?/* 所有協程的最大優先級數,協程優先級永遠低于任務。就是系統先執行任務,所有任務執行完了才執行協程。*/
#define configMAX_CO_ROUTINE_PRIORITIES????????? 1?
?
/*? 系統內核的中斷優先級,中斷優先級越低,越不會影響其他中斷。一般設成最低 */
#define configKERNEL_INTERRUPT_PRIORITY??????????? [dependent of processor]?
?
/* 系統SVC中斷優先級,這兩項都在在M3和PIC32上應用 */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY??[dependent on processor and application]?
?
#endif /* FREERTOS_CONFIG_H */
?
一般來說,如果用不上的功能都要設成0,可以減少代碼和資源。
?
轉載于:https://www.cnblogs.com/LittleTiger/p/4907268.html
總結
以上是生活随笔為你收集整理的FreeRTOS初步认识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Git更新到最新版本
- 下一篇: JavaScript之三:jQuery插