FreeRTOS學習筆記——空閑任務prvIdleTask

文章目錄

    • 任務創建
    • 任務的內容
      • 推薦閱讀

任務創建

prvIdleTask任務,是由任務調度函數vTaskStartScheduler創建的,任務優先級0,任務堆棧深度由配置選項configMINIMAL_STACK_SIZE定義。

void vTaskStartScheduler(void)
{/* 其他代碼*//* Add the idle task at the lowest priority. */xReturn = xTaskCreate(prvIdleTask,configIDLE_TASK_NAME,configMINIMAL_STACK_SIZE,(void *) NULL,portPRIVILEGE_BIT, &xIdleTaskHandle); /* 其他代碼*/
}

任務的內容

這里貼上源碼,然后對源碼做解析。

static portTASK_FUNCTION(prvIdleTask, pvParameters)
{/* Stop warnings. */(void) pvParameters;/** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE* SCHEDULER IS STARTED. **//* In case a task that has a secure context deletes itself, in which case* the idle task is responsible for deleting the task's secure context, if* any. */portALLOCATE_SECURE_CONTEXT(configMINIMAL_SECURE_STACK_SIZE);for(; ;){/* See if any tasks have deleted themselves - if so then the idle task* is responsible for freeing the deleted task's TCB and stack. */prvCheckTasksWaitingTermination();#if (configUSE_PREEMPTION == 0){/* If we are not using preemption we keep forcing a task switch to* see if any other task has become available.  If we are using* preemption we don't need to do this as any task becoming available* will automatically get the processor anyway. */taskYIELD();}#endif /* configUSE_PREEMPTION */#if ((configUSE_PREEMPTION == 1) && (configIDLE_SHOULD_YIELD == 1)){/* When using preemption tasks of equal priority will be* timesliced.  If a task that is sharing the idle priority is ready* to run then the idle task should yield before the end of the* timeslice.** A critical region is not required here as we are just reading from* the list, and an occasional incorrect value will not matter.  If* the ready list at the idle priority contains more than one task* then a task other than the idle task is ready to execute. */if(listCURRENT_LIST_LENGTH(&(pxReadyTasksLists[ tskIDLE_PRIORITY ])) > (UBaseType_t) 1){taskYIELD();}else{mtCOVERAGE_TEST_MARKER();}}#endif /* ((configUSE_PREEMPTION == 1) && (configIDLE_SHOULD_YIELD == 1)) */#if (configUSE_IDLE_HOOK == 1){extern void vApplicationIdleHook(void);/* Call the user defined function from within the idle task.  This* allows the application designer to add background functionality* without the overhead of a separate task.* NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,* CALL A FUNCTION THAT MIGHT BLOCK. */vApplicationIdleHook();}#endif /* configUSE_IDLE_HOOK *//* This conditional compilation should use inequality to 0, not equality* to 1.  This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when* user defined low power mode  implementations require* configUSE_TICKLESS_IDLE to be set to a value other than 1. */#if (configUSE_TICKLESS_IDLE != 0){TickType_t xExpectedIdleTime;/* It is not desirable to suspend then resume the scheduler on* each iteration of the idle task.  Therefore, a preliminary* test of the expected idle time is performed without the* scheduler suspended.  The result here is not necessarily* valid. */xExpectedIdleTime = prvGetExpectedIdleTime();if(xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP){vTaskSuspendAll();{/* Now the scheduler is suspended, the expected idle* time can be sampled again, and this time its value can* be used. */configASSERT(xNextTaskUnblockTime >= xTickCount);xExpectedIdleTime = prvGetExpectedIdleTime();/* Define the following macro to set xExpectedIdleTime to 0* if the application does not want* portSUPPRESS_TICKS_AND_SLEEP() to be called. */configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING(xExpectedIdleTime);if(xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP){traceLOW_POWER_IDLE_BEGIN();portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime);traceLOW_POWER_IDLE_END();}else{mtCOVERAGE_TEST_MARKER();}}(void) xTaskResumeAll();}else{mtCOVERAGE_TEST_MARKER();}}#endif /* configUSE_TICKLESS_IDLE */}
}
  • portTASK_FUNCTION是一個宏定義,專門用來定義任務函數,如下圖。
    在這里插入圖片描述

  • portALLOCATE_SECURE_CONTEXT(configMINIMAL_SECURE_STACK_SIZE);
    portALLOCATE_SECURE_CONTEXT是一個用于在 FreeRTOS 中分配安全上下文的函數,一般用在使用了TrustZone 技術的系統中。通過分配和初始化安全堆棧,它為非安全任務提供了必要的支持,以便在需要時與安全區域進行交互。

    TrustZone技術是由ARM公司開發的一種硬件安全技術,旨在通過將處理器和系統資源分為安全和非安全兩部分來增強系統的安全性。它廣泛應用于需要高安全性的嵌入式系統中,如智能手機、物聯網設備和支付系統。

  • prvCheckTasksWaitingTermination();
    檢查是否有需要釋放內存的被刪除任務,當有任務調用函數vTaskDelete()刪除自身的話,此任務就會添加到列表xTasksWaitingTermination中。函數prvCheckTasksWaitingTermination()會檢查列表xTasksWaitingTermination是否為空,如果不為空的話就依次將列表中所有任務對應的內存釋放掉(任務控制塊 TCB 和任務堆棧的內存)。

  • 使用搶占式內核并且 configIDLE_SHOULD_YIELD 為 1,說明空閑任務需要讓出時間片給同優先級的其他就緒任務。

  • 檢查優先級為tskIDLE_PRIORITY(空閑任務優先級)的就緒任務列表是否為空,如果不為空的話就調用函數taskYIELD()進行一次任務切換。

  • 如果使能了空閑任務鉤子函數的話就執行這個鉤子函數,空閑任務鉤子函數的函數名為vApplicationIdleHook(),這個函數需要用戶自行編寫!在編寫這個這個鉤子函數的時候一定不能調用任何可以阻塞空閑任務的 API 函數。通常,使用這個空閑鉤子函數設置CPU進入低功耗模式。

  • 剩下的都是Tickless模式的代碼
    configUSE_TICKLESS_IDLE不為 0,說明使能了 FreeRTOS 的低功耗 Tickless 模式。

    一般而言,在RTOS中為了降低功耗。運行空閑任務時需要進入低功耗模式,在處理應用層任務時需要將處理器從低功耗模式中喚醒。一般會在空閑任務的鉤子函數中執行低功耗相關處理,比如設置處理器進入低功耗模式、關閉其他外設時鐘、降低系統主頻等。

    但FreeRTOS中的時鐘是由滴答定時器(一般頻率為1000Hz)來提供的,這會導致當處理器進入低功耗模式時會被滴答定時器中斷頻繁喚醒,導致低功耗模式作用大大降低。因此引入了Tickless模式——當處理器進入空閑任務周期后,就關閉滴答定時器中斷,只有當其他中斷發生或者其他任務需要處理的時候,處理器才會被從低功耗模式中喚醒。

    但這將面臨兩個問題: 其一是關閉系統節拍中斷會導致系統節拍計數器停止,系統時鐘就會停止。 FreeRTOS 的系統時鐘是依賴于系統節拍中斷(滴答定時器中斷)的,如果關閉了系統節拍中斷的話就會導致系統時鐘停止運行,這是絕對不允許的!解決方法為–記錄下系統節拍中斷的關閉時間,當系統節拍中斷再次開啟運行的時候補上這段時間,因此這段時間也稱為補償時間。這時候就需要另外一個定時器來記錄這段補償時間,而F103是繼續采用滴答定時器來完成這個功能。

    其二是當處理器進入睡眠模式之后,除了及時響應中斷外,還需要響應應用層的就緒任務,但是中斷可以喚醒睡眠模式,應用層任務卻不能主動將處理器從睡眠中喚醒。為了解決上述問題,采用記錄處理器在進入低功耗模式之前的待運行任務阻塞時間(也稱為低功耗持續時間),FreeRTOS中提供了prvGetExpectedIdleTime()函數來獲取這段時間。

推薦閱讀

空閑任務與鉤子函數

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/90065.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/90065.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/90065.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

初識卷積神經網絡CNN

卷積神經網絡CNN 全連接神經網絡存在的問題: 輸入的形式應該是列向量,但是卷積神經網絡中的輸入是圖像(2D矩陣),那么就需要對圖片進行展平處理,原本圖像中蘊含的空間等信息就被打亂了輸入的特征多了,那么神經元的參數就會很多&…

高層功能架構詳解 - openExo

高層功能架構詳解1. 系統整體結構與模塊化設計2. 兩大核心類:ExoData 與 ExoA. ExoDataB. ExoC. 數據結構的層級關系3. 多微控制器協作與BLE通信4. 主控軟件運行流程(主循環偽代碼)5. 架構優點小結6. 與 Code Structure 的關系實用建議1. 系統…

【西北工業大學公開課】導引系統原理(全61講)周軍 -個人筆記版 5000字

【嚴正聲明】此文檔為個人筆記:僅供個人與同學參考學習,記錄學習過程,嚴謹商業轉載,或商業售賣!感謝西北工業大學公開課知識分享,公開資料開源!視頻鏈接:【【西北工業大學】導引系統…

《命令行參數與環境變量:從使用到原理的全方位解析》

前言 當我們在終端輸入 ls -l /home 查看目錄詳情,或用 gcc -o hello hello.c 編譯代碼時,或許很少思考:這些空格分隔的 “指令 選項 路徑” 是如何被程序識別的?為什么 PATH 變量能讓系統找到可執行文件,而 HOME 變…

C++設計模式:單例模式 (現代C++主流實現方式Meyer‘s Singleton + 使用CRTP模板化)

文章目錄單例模式創建單例類餓漢式or懶漢式現代C單例模式的主流實現方式——Meyers Singleton使用 CRTP 模板化單例類單例模式 單例模式是指程序中只需要一個實例化對象,在全局作用域或整個代碼架構中,此對象只被實例化一次,就可以達到在整個…

Eureka 和 Nacos

一、基本介紹EurekaEureka 是 Netflix 公司開發的一款基于 REST 風格的服務注冊與發現組件,專為分布式系統設計。它遵循 AP 原則(可用性、分區容錯性優先),強調在網絡分區等異常情況下的服務可用性,是 Spring Cloud Ne…

文件IO筆試題

目錄前言一、核心概念:二、關鍵操作步驟:三、為什么需要文件IO?四、常見類型:五、標準IO源碼六、筆試真題和練習1.代碼實現1代碼實現22.代碼實現3.代碼實現4.代碼實現5.代碼實現七、總結前言 文件IO(文件輸入/輸出&am…

前端學習 5:DFT

DFT技術 DFT (design for testability):指在設計系統和電路的同時,考慮測試的需求,通過增加一定的硬件開銷,獲得最大可測性的設計過程。(因為增加了硬件,所以也帶來了不足&#xff…

最長遞增子序列(LIS)問題詳解

最長遞增子序列LIS問題詳解一、問題定義與核心特征1.1 問題描述1.2 核心特征二、基礎解法:動態規劃(DP)2.1 解法思路2.2 Java代碼實現2.3 復雜度分析三、優化解法:二分查找貪心3.1 核心思路3.2 二分查找的作用3.3 Java代碼實現代碼…

什么是HTTP長連接、短連接?誰更能抗DoS攻擊?

想象你在快餐店點餐: 你:“一個漢堡”收銀員:“好的,15元”交易結束,你離開隊伍你想加杯可樂,重新排隊你:“一杯可樂”收銀員:“好的,8元”再次離開… 這種每次溝通后立即…

微軟徽標認證是什么?如何快速獲取驅動簽名?

在Windows系統中安裝硬件驅動時,是否遇到過“無法驗證發布者”的警告?這正是驅動數字簽名在背后發揮作用。對于軟件開發者而言,驅動數字簽名不僅是系統兼容性的保障,更是企業品牌信任度的核心。一、驅動數字簽名的核心作用驅動數字…

Apache Ignite緩存基本操作

這段內容主要講解了 Apache Ignite 中緩存(IgniteCache)的基本操作,包括獲取緩存、創建緩存、銷毀緩存、執行原子操作以及異步操作等。下面我將用中文對這些內容進行詳細解釋,幫助你更好地理解。一、獲取緩存實例(Gett…

最新基于R語言結構方程模型分析與實踐技術應用

現代統計學理論和方法的不斷完善,使科研工作對統計方法的要求也越來越高,面對紛繁復雜的數據,如何選擇最為合適的數據分析方法已成為科研工作者,尤其是廣大剛處于科研生涯起步階段的研究生們最為棘手問題。隨著科學的發展&#xf…

物聯網_TDengine_EMQX_性能測試

一、Tdengine接口開發文檔 1、數據庫 1.創建數據庫 URL /dp/createdb/ method post 請求示例 {"db_name":"demo01" // 必填 }響應示例 // 成功 {"code": 1,"data": {"成功創建數據庫": "demo04"},"error…

從分析到優化:Amazon Q CLI 助力 EKS 網絡調用鏈剖析與運維實踐

1. 引言 在 Amazon EKS(Elastic Kubernetes Service)環境中,理解從 ALB(Application Load Balancer)到 Pod 的完整網絡調用鏈對運維人員至關重要。本文將展示如何利用 Amazon Q CLI 這一 AI 助手工具,通過…

Class10簡潔實現

Class10簡潔實現 import torch from torch import nn from d2l import torch as d2l# 輸入為28*28,輸出為10類,第1、2隱藏層256神經元 num_inputs, num_outputs, num_hiddens1, num_hiddens2 784, 10, 256, 256 # 第1個隱藏層丟棄率為0.2,第…

【多線程篇22】:ConcurrentHashMap的并發安全原理剖析

文章目錄一、HashMap 的“不安全”:問題的根源1. 數據結構回顧 (JDK 1.8)2. 并發下的致命缺陷:put 操作二、ConcurrentHashMap 的安全之道 (JDK 1.8)1. 核心數據結構2. 安全的 put 操作:分場景精細化加鎖3. 安全的 size() 計算:并…

【Java + Vue 實現圖片上傳后 導出圖片及Excel 并壓縮為zip壓縮包】

系統環境: Java JDK:1.8.0_202 Node.js:v12.2.0 Npm:6.9.0 Java后端實現 Controller /*** xxxx-導出* param response 返回信息體* param files 上傳的圖片文件* param param1 參數1* param param2 參數2*/PostMapping("/ex…

安科瑞:能源微電網助力工業園區“綠色”發展

朱以真近日,廈門市工業和信息化局印發工業園區綠色智慧微電網建設,擬開展全市工業園區綠色智慧微電網試點通知,那么對于如何實現綠色園區的建設是今天的話題。對工業園區綠色智慧微電網建設需求,其核心價值體現在“源-網-荷-儲-充…

VUE2 學習筆記3 v-on、事件修飾符、鍵盤事件

事件處理v-on用于事件交互。語法:v-on:要綁定的事件“事件觸發時執行的函數” (函數這里可以寫括號,也可以不寫,沒有影響)簡寫::事件觸發時要執行的函數,在Vue配置參數中,通過method…