網站首頁 編程語言 正文
1. 任務和協程(Co-routines)
應用程序可以使用任務也可以使用協程,或者兩者混合使用,但是任務和協程使用不同的API函數,因此在任務和協程之間不能使用同一個隊列或信號量傳遞數據。
通常情況下,協程僅用在資源非常少的微處理器中,特別是RAM非常稀缺的情況下。目前協程很少被使用到,因此對于協程FreeRTOS作者既沒有把它刪除也沒有進一步開發。
所以本系列文章以后不會對協程過多描述,包括其API函數。
1.1任務的特性
簡而言之:使用RTOS的實時應用程序可認為是一系列獨立任務的集合。每個任務在自己的環境中運行,不依賴于系統中的其它任務或者RTOS調度器。在任何時刻,只有一個任務得到運行,RTOS調度器決定運行哪個任務。調度器會不斷的啟動、停止每一個任務,宏觀看上去就像整個應用程序都在執行。作為任務,不需要對調度器的活動有所了解,在任務切入切出時保存上下文環境(寄存器值、堆棧內容)是調度器主要的職責。為了實現這點,每個任務都需要有自己的堆棧。當任務切出時,它的執行環境會被保存在該任務的堆棧中,這樣當再次運行時,就能從堆棧中正確的恢復上次的運行環境。
1.2任務概要
- 簡單
- 沒有使用限制
- 支持完全搶占
- 支持優先級
- 每個任務都有自己的堆棧,消耗RAM較多
- 如果使用搶占,必須小心的考慮可重入問題
2. 任務狀態
一個任務可為下面中的一個:
運行:如果一個任務正在執行,那么說這個任務處于運行狀態。此時它占用處理器。
就緒:就緒的任務已經具備執行的能力(不同于阻塞和掛起),但是因為有一個同優先級或者更高優先級的任務處于運行狀態而還沒有真正執行。
阻塞:如果任務當前正在等待某個時序或外部中斷,我們就說這個任務處于阻塞狀態。比如一個任務調用vTaskDelay()后會阻塞到延時周期到為止。任務也可能阻塞在隊列或信號量事件上。進入阻塞狀態的任務通常有一個“超時”周期,當事件超時后解除阻塞。
掛起:處于掛起狀態的任務同樣對調度器無效。僅當明確的分別調用vTaskSuspend() 和xTaskResume() API函數后,任務才會進入或退出掛起狀態。不可以指定超時周期事件(不可以通過設定超時事件而退出掛起狀態)
3.任務優先級
每個任務都要被指定一個優先級,從0~configMAX_PRIORITIES,configMAX_PRIORITIES定義在FreeRTOSConfig.h中。
如果某架構硬件支持CLZ(或類似)指令(計算前導零的數目,Cortex-M3是支持該指令的,從ARMv6T2才支持這個指令),并且打算在移植層使用這個特性來優化任務調度機制,需要有一些步驟,首先將FreeRTOSConfig.h中configUSE_PORT_OPTIMISED_TASK_SELECTION設置為1,并且最大優先級數目configMAX_PRIORITIES不能大于32。除此之外,configMAX_PRIORITIES可以設置為任意值,但是考慮到configMAX_PRIORITIES設置越大,RAM消耗也越大,一般設置為滿足使用的最小值。
低優先級數值代表低優先級。空閑任務(idle task)的優先級為0(tskIDLE_PRIORITY)。
FreeRTOS調度器確保處于最高優先級的就緒或運行態任務獲取處理器,換句話說,處于運行狀態的任務,只有其中的最高優先級任務才會運行。
任何數量的任務可以共享同一個優先級。如果宏configUSE_TIME_SLICING未定義或著宏configUSE_TIME_SLICING定義為1,處于就緒態的多個相同優先級任務將會以時間片切換的方式共享處理器。
4.實現一個任務
一個任務具有以下結構:
void vATaskFunction( void *pvParameters ) { for( ;; ) { /*-- 應用程序代碼放在這里. --*/ } /* 任務不可以從這個函數返回或退出。在較新的FreeRTOS移植包中,如果 試圖從一個任務中返回,將會調用configASSERT()(如果定義的話)。 如果一個任務確實要退出函數,那么這個任務應調用vTaskDelete(NULL) 函數,以便處理一些清理工作。*/ vTaskDelete( NULL ); }
任務函數返回為void,參數只有一個void類型指針。所有的任務函數都應該是這樣。void類型指針可以向任務傳遞任意類型信息。
任務函數決不應該返回,因此通常任務函數都是一個死循環。
任務由xTaskCreate()函數創建,由vTaskDelete()函數刪除。
5.空閑任務和空閑任務鉤子(idle task和Idle Task hook)
5.1空閑任務
空閑任務是啟動RTOS調度器時由內核自動創建的任務,這樣可以確保至少有一個任務在運行。空閑任務具有最低任務優先級,這樣如果有其它更高優先級的任務進入就緒態就可以立刻讓出CPU。
刪除任務后,空閑任務用來釋放RTOS分配給被刪除任務的內存。因此,在應用中使用vTaskDelete()函數后確保空閑任務能獲得處理器時間就很重要了。除此之外,空閑任務沒有其它有效功能,所以可以被合理的剝奪處理器時間,并且它的優先級也是最低的。
應用程序任務共享空閑任務優先級(tskIDLE_PRIORITY)也是可能的。這種情況如何配置可以參考configIDLE_SHOULE_YIELD配置參數類獲取更多信息。
5.2空閑任務鉤子
空閑任務鉤子是一個函數,每一個空閑任務周期被調用一次。如果你想將任務程序功能運行在空閑優先級上,可以有兩種選擇:
在一個空閑任務鉤子中實現這個功能:因為FreeRTOS必須至少有一個任務處于就緒或運行狀態,因此鉤子函數不可以調用可能引起空閑任務阻塞的API函數(比如vTaskDelay()或者帶有超時事件的隊列或信號量函數)。
創建一個具有空閑優先級的任務去實現這個功能:這是個更靈活的解決方案,但是會帶來更多RAM開銷。
創建一個空閑鉤子步驟如下:
- 在FreeRTOSConfig.h頭文件中設置configUSE_IDLE_HOOK為1;?
- 定義一個函數,名字和參數原型如下所示:
void vApplicationIdleHook( void );
通常,使用這個空閑鉤子函數設置CPU進入低功耗模式。
原文鏈接:https://blog.csdn.net/zhzht19861011/article/details/50312443
相關推薦
- 2022-05-28 python中數組和列表的簡單實例_python
- 2022-03-24 android?Launcher?AppWidget添加步驟介紹_Android
- 2022-03-30 C語言中循環語句練習實例_C 語言
- 2022-07-08 Python數據分析Pandas?Dataframe排序操作_python
- 2022-10-29 編寫字符設備驅動控制樹莓派io口
- 2022-09-25 Linux基礎組件之基于循環數組的無鎖隊列
- 2022-09-06 Python中閉包與lambda的作用域解析_python
- 2022-01-22 Redis——docker構建的Redis集群
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支