網站首頁 編程語言 正文
前言
內核控制的一些功能需要移植層提供,為了方便移植,這些API函數用宏來實現,比如上下文切換、進入和退出臨界區、禁止和使能可屏蔽中斷。內核控制函數還包括啟動和停止調度器、掛起和恢復調度器以及用于低功耗模式的調整系統節拍函數。
1.強制上下文切換宏
taskYIELD:用于強制上下文切換的宏。在中斷服務程序中的等價版本為portYIELD_FROM_ISR,這也是個宏,其實現取決于移植層。
用于上下文切換的實際代碼由移植層提供。對于Cortex-M3硬件,這個宏會引起PendSV中斷。
2.進入臨界區宏
taskENTER_CRITICAL:用于進入臨界區的宏。在臨界區中不會發生上下文切換。
進入臨界區的實際代碼由移植層提供,對于Cortex-M3硬件,先禁止所有RTOS可屏蔽中斷,這可以通過向basepri 寄存器寫入configMAX_SYSCALL_INTERRUPT_PRIORITY來實現。
basepri寄存器被設置成某個值后,所有優先級號大于等于此值的中斷都被禁止,但若被設置為0,則不關閉任何中斷,0為默認值。然后臨界區嵌套計數器增1。
3.退出臨界區宏
taskEXIT_CRITICAL:用于退出臨界區的宏。
退出臨界區的實際代碼有移植層提供,對于Cortex-M3硬件,先將臨界區嵌套計數器減1,如果臨界區計數器為零,則使能所有RTOS可屏蔽中斷,這可以通過向basepri 寄存器寫入0來實現。
4.禁止可屏蔽中斷宏
taskDISABLE_INTERRUPTS:禁止所有RTOS可屏蔽中斷。
在調用宏taskENTER_CRITICAL進入臨界區時,也會間接調用該宏禁止所有RTOS可屏蔽中斷。
5.使能可屏蔽中斷宏
taskENABLE_INTERRUPTS:使能所有RTOS可屏蔽中斷。
在調用宏taskEXIT_CRITICAL退出臨界區時,也會間接調用該宏使能所有RTOS可屏蔽中斷。
6.啟動調度器
6.1函數描述
void vTaskStartScheduler( void );
啟動RTOS調度器,之后RTOS內核控制哪個任務執行以及何時執行。
當調用vTaskStartScheduler()后,空閑任務被自動創建。
如果configUSE_TIMERS被設置為1,定時器后臺任務也會被創建。
如果vTaskStartScheduler()成功執行,則該函數不會返回,直到有任務調用了vTaskEndScheduler()。
如果因為RAM不足而無法創建空閑任務,該函數也可能執行失敗,并會立刻返回調用處。
7.停止調度器
7.1函數描述
void vTaskEndScheduler( void );
僅用于x86硬件架構中。
停止RTOS內核系統節拍時鐘。所有創建的任務自動刪除并停止多任務調度。
8.掛起調度器
8.1函數描述
void vTaskSuspendAll( void );
掛起調度器,但不禁止中斷。當調度器掛起時,不會進行上下文切換。調度器掛起后,正在執行的任務會一直繼續執行,內核不再調度(意味著當前任務不會被切換出去),直到該任務調用了xTaskResumeAll ()函數。
內核調度器掛起期間,那些可以引起上下文切換的API函數(如vTaskDelayUntil()、xQueueSend()等)決不可使用。
9.恢復被掛起的調度器
9.1函數描述
BaseType_t xTaskResumeAll( void );
恢復因調用vTaskSuspendAll()函數而掛起的實時內核調度器。
xTaskResumeAll()僅恢復調度器,它不會恢復那些被vTaskSuspend()函數掛起的任務。
9.2返回值
返回pdTRUE 表示恢復調度器引起了一次上下文切換,否則,返回pdFALSE。
9.3用法舉例
voidvTask1( void * pvParameters ) { for( ;; ) { /* 任務代碼寫在這里 */ /* ... */ /* 有些時候,某個任務希望可以連續長時間的運行,但這時不能使用taskENTER_CRITICAL ()/taskEXIT_CRITICAL ()的方法,這樣會屏蔽掉中斷,引起中斷丟失,包括系統節拍時鐘。可以使用vTaskSuspendAll ()停止RTOS內核調度:*/ xTaskSuspendAll (); /* 執行操作代碼放在這里。這樣不用進入臨界區就可以連續長時間執行了。在這期間,中斷仍然會得到響應,RTOS內核系統節拍時鐘也會繼續保持運作 */ /* ... */ /* 操作結束,重新啟動RTOS內核 。我們想強制進行一次上下文切換,但是如果恢復調度器的時候已經執行了上下文切換,再執行一次是沒有意義的,因此會進行一次判斷。*/ if( !xTaskResumeAll () ) { taskYIELD (); } } }
10.調整系統節拍
10.1函數描述
void vTaskStepTick( TickType_txTicksToJump );
如果RTOS使能tickless空閑功能,每當只有空閑任務被執行時,系統節拍時鐘中斷將會停止,微控制器進入低功耗模式。
當微控制器退出低功耗后,系統節拍計數器必須被調整,將進入低功耗的時間彌補上。
如果FreeRTOS移植文件中定義了宏portSUPPRESS_TICKS_AND_SLEEP()實體,則函數vTaskStepTick用于在這個宏portSUPPRESS_TICKS_AND_SLEEP()實體內部調整系統節拍計數器。
函數vTaskStepTick是一個全局函數,所以也可以在宏portSUPPRESS_TICKS_AND_SLEEP()實體中重寫該函數。
在文件FreeRTOSConfig.h中,宏configUSE_TICKLESS_IDLE必須設置為1,此函數才有效。
10.2參數描述
xTickToJump:時間值,單位是系統節拍周期,表示微處理器進入低功耗的時間,函數根據這個值來調整系統節拍計數器的值。
10.3用法舉例
/* 首先定義宏portSUPPRESS_TICKS_AND_SLEEP()。宏參數指定要進入低功耗(睡眠)的時間,單位是系統節拍周期。*/#defineportSUPPRESS_TICKS_AND_SLEEP( xIdleTime ) vApplicationSleep( xIdleTime ) /* 定義被宏portSUPPRESS_TICKS_AND_SLEEP()調用的函數 */void vApplicationSleep(TickType_t xExpectedIdleTime ){ unsigned long ulLowPowerTimeBeforeSleep,ulLowPowerTimeAfterSleep; /* 從時鐘源獲取當前時間,當微控制器進入低功耗的時候,這個時鐘源必須在運行 */ ulLowPowerTimeBeforeSleep =ulGetExternalTime(); /*停止系統節拍時鐘中斷。*/ prvStopTickInterruptTimer(); /* 配置一個中斷,當指定的睡眠時間達到后,將處理器從低功耗中喚醒。這個中斷源必須在微控制器進入低功耗時也可以工作。*/ vSetWakeTimeInterrupt( xExpectedIdleTime ); /*進入低功耗 */ prvSleep(); /* 確定微控制器進入低功耗模式持續的真正時間。因為其它中斷也可能使得微處理器退出低功耗模式。注意:在調用宏portSUPPRESS_TICKS_AND_SLEEP()之前,調度器應該被掛起,portSUPPRESS_TICKS_AND_SLEEP()返回后,再將調度器恢復。因此,這個函數未完成前,不會執行其它任務。*/ ulLowPowerTimeAfterSleep =ulGetExternalTime(); /*調整內核系統節拍計數器。*/ vTaskStepTick( ulLowPowerTimeAfterSleep –ulLowPowerTimeBeforeSleep ); /*重新啟動系統節拍時鐘中斷。*/ prvStartTickInterruptTimer();}/* 首先定義宏portSUPPRESS_TICKS_AND_SLEEP()。宏參數指定要進入低功耗(睡眠)的時間,單位是系統節拍周期。*/ #defineportSUPPRESS_TICKS_AND_SLEEP( xIdleTime ) vApplicationSleep( xIdleTime ) /* 定義被宏portSUPPRESS_TICKS_AND_SLEEP()調用的函數 */ void vApplicationSleep(TickType_t xExpectedIdleTime ) { unsigned long ulLowPowerTimeBeforeSleep,ulLowPowerTimeAfterSleep; /* 從時鐘源獲取當前時間,當微控制器進入低功耗的時候,這個時鐘源必須在運行 */ ulLowPowerTimeBeforeSleep =ulGetExternalTime(); /*停止系統節拍時鐘中斷。*/ prvStopTickInterruptTimer(); /* 配置一個中斷,當指定的睡眠時間達到后,將處理器從低功耗中喚醒。這個中斷源必須在微控制器進入低功耗時也可以工作。*/ vSetWakeTimeInterrupt( xExpectedIdleTime ); /*進入低功耗 */ prvSleep(); /* 確定微控制器進入低功耗模式持續的真正時間。因為其它中斷也可能使得微處理器退出低功耗模式。注意:在調用宏portSUPPRESS_TICKS_AND_SLEEP()之前,調度器應該被掛起,portSUPPRESS_TICKS_AND_SLEEP()返回后,再將調度器恢復。因此,這個函數未完成前,不會執行其它任務。*/ ulLowPowerTimeAfterSleep =ulGetExternalTime(); /*調整內核系統節拍計數器。*/ vTaskStepTick( ulLowPowerTimeAfterSleep –ulLowPowerTimeBeforeSleep ); /*重新啟動系統節拍時鐘中斷。*/ prvStartTickInterruptTimer(); }
原文鏈接:https://freertos.blog.csdn.net/article/details/50553099
相關推薦
- 2022-04-10 pytorch中Parameter函數用法示例_python
- 2023-10-14 關于Smartbi配置Sql Server數據源調用HTTP請求
- 2024-02-29 UNI-APP中webview加載狀態,開始加載,加載完成事件監聽
- 2022-12-01 使用SDLocalize實現高效完成iOS多語言工作_IOS
- 2022-08-12 python關于字典及遍歷的常用方法_python
- 2022-05-22 分享幾種python?變量合并方法_python
- 2022-12-23 Android同步異步任務與多線程及Handler消息處理機制基礎詳細講解_Android
- 2022-03-27 .NET?Core利用動態代理實現AOP(面向切面編程)_實用技巧
- 最近更新
-
- 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同步修改后的遠程分支