FreeRTOSBug解析:一個任務printf打印一半突然跳轉另一個任務,導致另一個任務無法打印

bug現象:

key任務:

默認任務:

此時兩個任務的優先級相同,搶占式調度,時間片輪轉,空閑任務讓步。

但是會出現一個問題,key任務在發送完隊列之后不會立即跳轉到默認任務的隊列接收函數后的printf,而是會在printf("Send Successfully")打印一半之后再跳轉到默認任務的printf里,但是此時默認任務的printf也無法打印了。具體跳轉步驟如下圖:

原因解析:

步驟“1”執行隊列發送函數的時候,會喚醒等待隊列數據接收的任務,如果任務優先級比當前任務高,那么會立刻搶占cpu,但是現在由于兩個任務的優先級是平級的關系,只能在時間片輪轉的時候進行任務調度,讓默認任務優先運行(等待隊列接收的任務)。

由于不是立即跳轉,導致步驟“2”的printf進行了一半,跳轉到了步驟“3”的printf,由于printf是不可重入函數,所以步驟“3”的printf無法打印。

運行順序為:

步驟“1” -> 步驟“2”一半 ->步驟“3” ->步驟“3”所在任務運行一個時間片(等待隊列接收)->任務調度回到步驟“2”將printf剩下的一半打印完

解決方法:

1 將key任務優先級抬高

當key任務發送隊列喚醒默認任務時,不會在下一個時間片切換任務,而是等key任務主動放棄CPU資源的時候再進行任務調度(先看優先級,再是隊列接收),從而保證printf()不會被多個任務同時調用,保證默認任務中步驟“3”printf的打印正常進行。

2 將默認任務優先級抬高

與方法1同理,將默認任務優先級抬高后可以在發送隊列結束后立即跳轉(默認任務被喚醒,優先級比key任務高,搶占CPU)到默認任務的打印函數(步驟“3”),在默認任務運行到阻塞(等待隊列接收)主動出讓CPU資源后再跳轉到步驟“2”運行printf,這種方法同樣保證了printf同時只被一個任務調用。

3 不更改任務優先級,更改調度方式(不常用,了解即可)

關于調度方式:

這個設置的更改即從“時間片輪轉”變為“非時間片輪轉”,讓任務調度只能通過優先級搶占和主動出讓CPU資源來進行任務切換。

由于key任務和默認任務優先級平級,當取消時間片輪轉后,自然不會出現步驟“2”printf打印一半就被時間片調度跳轉到另一個任務的情況,此時沒有更高優先級的任務,只有key任務主動出讓CPU資源才能切換任務。也保證了printf()函數同時只被一個任務調用。

知識點補充:

立即觸發調度的操作/函數:(deepseek)


關于xQueueSend()或xSemaphoreGive()的調度:(deepseek)

1. 默認行為:有條件觸發調度

這兩個函數在以下場景中可能觸發立即調度:

  • 存在等待的高優先級任務:若調用 xQueueSend()xSemaphoreGive() 時,有更高優先級的任務正在等待隊列數據或信號量,則調度器會立即切換任務(搶占式調度生效)。例如:

    // 任務 A(低優先級)發送數據到隊列

  • xQueueSend(xQueue, &data, 0);

  • // 任務 B(高優先級)正在阻塞等待該隊列

  • // 此時任務 A 會立即被搶占,任務 B 開始運行

    • 配置為搶占式調度:若 FreeRTOS 的調度策略設置為搶占式(默認),則高優先級任務就緒時會立即觸發切換。


    2. 不觸發調度的場景

    以下情況不會立即觸發調度:

    • 無等待任務或優先級不滿足:若沒有任務在等待隊列/信號量,或等待的任務優先級不高于當前任務,則當前任務繼續運行,調度器不會切換。

      • 中斷服務程序ISR)中未顯式請求調度:在 ISR 中調用 xQueueSendFromISR()xSemaphoreGiveFromISR() 時,需手動調用 portYIELD_FROM_ISR() 才會觸發調度。


        3. 與時間片輪轉調度的關系

        若系統啟用了時間片輪轉(configUSE_TIME_SLICING = 1),即使沒有更高優先級任務,同優先級任務也會在時間片用完時切換。但 xQueueSend()xSemaphoreGive() 本身不會強制切換,需依賴時間片中斷。


        總結

        場景

        是否觸發調度

        說明

        發送數據/信號量喚醒更高優先級任務

        立即觸發

        搶占式調度生效,任務切換

        發送數據/信號量喚醒同或低優先級任務

        不觸發

        當前任務繼續運行

        在 ISR 中未手動調用 portYIELD_FROM_ISR()

        不觸發

        需顯式請求調度

        無任務等待隊列/信號量

        不觸發

        無任務需切換

        補充:顯式調度與隱式調度(deepseek)
        1. 顯式觸發調度(Explicit Scheduling)

        含義

        開發者主動調用特定函數來強制觸發任務調度,明確要求系統立即切換到其他就緒任務。

        特點

        • 直接控制調度時機,代碼中可見明確的調度指令。

        • 適用于需要手動讓出CPU的場景,例如協作式多任務或優化關鍵代碼段的執行順序。

        FreeRTOS 中的顯式觸發函數

        • taskYIELD():立即觸發調度器重新選擇任務,即使當前任務的時間片未用完。

          void vTaskFunction(void *pvParameters) { while (1) { // 執行某些操作后主動讓出CPU taskYIELD(); // 顯式觸發調度 } }


          2. 隱式觸發調度(Implicit Scheduling)

          含義

          調度由系統事件或API函數的副作用自動觸發,開發者無需顯式調用調度函數。

          特點

          • 調度時機由系統管理,與任務狀態變化(如阻塞、資源釋放)或中斷事件綁定。

          • 更符合搶占式調度機制,提升系統自動化程度。

          FreeRTOS 中的隱式觸發場景

          • 任務阻塞操作:調用 vTaskDelay()xQueueReceive() 等函數時,任務進入阻塞狀態,調度器自動切換任務。

            vTaskDelay(pdMS_TO_TICKS(100)); // 隱式觸發調度(任務阻塞)

            • 資源釋放喚醒高優先級任務:例如,在 xSemaphoreGive()xQueueSend() 中,若釋放資源后存在更高優先級任務就緒,調度器自動搶占當前任務。

              xSemaphoreGive(xSemaphore); // 隱式觸發調度(若喚醒高優先級任務)

              • 中斷服務程序ISR)中的調度請求:在中斷中調用 xQueueSendFromISR()xSemaphoreGiveFromISR() 后,通過 portYIELD_FROM_ISR() 隱式觸發調度(需結合中斷上下文)。


              對比總結

              特性

              顯式觸發調度

              隱式觸發調度

              觸發方式

              開發者主動調用函數(如 taskYIELD()

              系統自動觸發(如任務阻塞、資源釋放、中斷)

              控制權

              完全由開發者控制

              由系統事件或API邏輯控制

              典型場景

              協作式任務切換、優化執行順序

              搶占式調度、事件驅動任務切換

              代碼可見性

              顯式代碼指令

              隱含在API或系統行為中


              不可重入函數

              顧名思義:不可重入函數就是不可以在它還沒有返回就再次被調用。

              不可重入原因:

              由于函數內部使用了全局變量、靜態變量、或調用了不可重入的函數等,導致函數在執行過程中可能被中斷,并在中斷后繼續執行時出現數據錯誤或不可預料的后果。以下是不可重入函數的幾個特點:

              1. 使用全局變量或靜態變量:如果函數內部使用了全局變量或靜態變量,那么在多任務環境下,多個任務同時調用該函數時,可能會對這些共享變量進行并發修改,導致數據不一致。

              2. 調用不可重入函數:如果函數內部調用了其他不可重入函數,那么這些被調用的函數也可能因為上述原因導致整個調用鏈不可重入。

              3. 使用動態內存分配:函數體內調用了malloc()或者free()函數,由于這些函數維護內部的鏈表,且這個過程不是原子的,因此在多任務環境下可能導致內存管理出現問題。

              4. 使用標準I/O函數:標準I/O函數通常使用全局數據結構,因此在多任務環境下也可能導致不可重入問題。

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

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

              相關文章

              操作系統八股文整理(一)

              操作系統八股文整理 一、進程和線程的區別二、進程與線程的切換過程一、進程切換進程切換的步驟: 二、線程切換線程切換的步驟: 三、進程切換與線程切換的對比四、上下文切換的優化 三、系統調用一、系統調用的觸發二、從用戶空間切換到內核空間三、執行…

              卷積神經網絡(CNN)之 EfficientNet

              在深度學習領域,模型的計算效率與性能之間的平衡一直是一個核心挑戰。隨著卷積神經網絡(CNN)在圖像分類、目標檢測等任務中取得顯著成果,模型的復雜度和計算需求也急劇增加。2019年,Google Research 提出的 EfficientN…

              學生選課管理系統數據庫設計報告

              學生選課管理系統數據庫設計報告 一、需求分析 (一)項目背景 學生選課管理系統是高校教學管理的重要組成部分,旨在實現學生選課、課程管理、成績錄入與查詢等功能的自動化和信息化。通過該系統,學生可以方便地選擇課程&#xf…

              工具介紹《Awsome-Redis-Rogue-Server 與 redis-rogue-server》

              1. 核心功能與攻擊場景 redis-rogue-server 基于Redis主從復制漏洞(CVE未公開),針對Redis 4.x~5.0.5版本設計,通過偽造惡意主節點強制同步惡意模塊(.so文件)實現遠程代碼執行(RCE)。…

              Razor C# 變量

              Razor C# 變量 引言 在ASP.NET MVC和Razor視圖引擎中,變量是構建動態網頁的基礎。理解Razor C#變量的使用對于開發者來說至關重要。本文將詳細介紹Razor C#變量的概念、類型、作用域以及如何在實際項目中有效使用它們。 一、Razor C# 變量的概念 Razor C# 變量是存儲在Raz…

              【QA】模板方法模式在Qt中有哪些應用?

              在 Qt 框架中,模板方法模式(Template Method Pattern)被廣泛應用于框架的設計中,通過定義算法骨架并允許子類在不改變結構的情況下重寫部分步驟。以下是 Qt 中典型的應用場景及示例: 1. 事件處理(Event Ha…

              有趣的算法實踐:整數反轉與回文檢測(Java實現)

              題目描述:整數反轉與回文檢測 要求實現兩個功能: 將輸入的整數反轉(保留符號,如輸入-123返回-321)判斷反轉后的數是否為回文數(正反讀相同) 示例: 輸入:123 → 反轉結…

              【協作開發】低成本一鍵復刻github的gitea

              在閱讀 next-public 時,反思原本的需求,是否本未倒置,故而重新調研當下開源現狀。發現 gitea 完全滿足商業軟件的開發要求,并且價格足夠低,使用足夠方便,其他同類軟件完全不用看了,真是世界級的…

              基于“動手學強化學習”的知識點(二):第 15 章 模仿學習(gym版本 >= 0.26)

              第 15 章 模仿學習(gym版本 > 0.26) 摘要 摘要 本系列知識點講解基于動手學強化學習中的內容進行詳細的疑難點分析!具體內容請閱讀動手學強化學習! 對應動手學強化學習——模仿學習 # -*- coding: utf-8 -*-import gy…

              JAVA面試_進階部分_Java JVM:垃圾回收(GC 在什么時候,對什么東西,做了什么事情)

              在什么時候: 首先需要知道,GC又分為minor GC 和 Full GC(major GC)。Java堆內存分為新生代和老年代,新生代 中又分為1個eden區和兩個Survior區域。 一般情況下,新創建的對象都會被分配到eden區&#xff…

              2024年消費者權益數據分析

              📅 2024年315消費者權益數據分析 數據見:https://mp.weixin.qq.com/s/eV5GoionxhGpw7PunhOVnQ 一、引言 在數字化時代,消費者維權數據對于市場監管、商家誠信和行業發展具有重要價值。本文基于 2024年315平臺線上投訴數據,采用數…

              設計模式Python版 訪問者模式

              文章目錄 前言一、訪問者模式二、訪問者模式示例 前言 GOF設計模式分三大類: 創建型模式:關注對象的創建過程,包括單例模式、簡單工廠模式、工廠方法模式、抽象工廠模式、原型模式和建造者模式。結構型模式:關注類和對象之間的組…

              安全無事故連續天數計算,python 時間工具的高效利用

              安全天數計算,數據系統時間直取,安全標準高效便捷好用。 筆記模板由python腳本于2025-03-17 23:50:52創建,本篇筆記適合對python時間工具有研究欲的coder翻閱。 【學習的細節是歡悅的歷程】 博客的核心價值:在于輸出思考與經驗&am…

              大型語言模型(LLM)部署中的內存消耗計算

              在部署大型語言模型(LLM)時,顯存(VRAM)的合理規劃是決定模型能否高效運行的核心問題。本文將通過詳細的公式推導和示例計算,系統解析模型權重、鍵值緩存(KV Cache)、激活內存及額外開…

              Mysql表的查詢

              一:創建一個新的數據庫(companydb),并查看數據庫。 二:使用該數據庫,并創建表worker。 mysql> use companydb;mysql> CREATE TABLE worker(-> 部門號 INT(11) NOT NULL,-> 職工號 INT(11) NOT NULL,-> 工作時間 D…

              ASP.NET Webform和ASP.NET MVC 后臺開發 大概80%常用技術

              本文涉及ASP.NET Webform和ASP.NET MVC 后臺開發大概80%技術 2019年以前對標 深圳22K左右 廣州18K左右 武漢16K左右 那么有人問了2019年以后的呢? 答:吉祥三寶。。。 So 想繼續看下文的 得有自己的獨立判斷能力。 C#.NET高級筆試題 架構 優化 性能提…

              首頁性能優化

              首頁性能提升是前端優化中的核心任務之一,因為首頁是用戶訪問的第一入口,其加載速度和交互體驗直接影響用戶的留存率和轉化率。 1. 性能瓶頸分析 在優化之前,首先需要通過工具分析首頁的性能瓶頸。常用的工具包括: Chrome DevTo…

              一周學會Flask3 Python Web開發-SQLAlchemy刪除數據操作-班級模塊

              鋒哥原創的Flask3 Python Web開發 Flask3視頻教程&#xff1a; 2025版 Flask3 Python web開發 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 首頁list.html里加上刪除鏈接&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta c…

              改變一生的思維模型【12】笛卡爾思維模型

              目錄 基本結構 警惕認知暗礁 案例分析應用 一、懷疑階段:破除慣性認知 二、解析階段:拆解問題為最小單元 三、整合階段:重構邏輯鏈條 四、檢驗階段:多維驗證解決方案 總結與啟示 笛卡爾說,唯獨自己的思考是可以相信的。 世界上所有的事情,都是值得被懷疑的,但是…

              需求文檔(PRD,Product Requirement Document)的基本要求和案例參考:功能清單、流程圖、原型圖、邏輯能力和表達能力

              文章目錄 引言I 需求文檔的基本要求結構清晰內容完整語言準確圖文結合版本管理II 需求文檔案例參考案例1:電商平臺“商品中心”功能需求(簡化版)案例2:教育類APP“記憶寶盒”非功能需求**案例3:軟件項目的功能需求模板3.1 功能需求III 需求文檔撰寫技巧1. **從核心邏輯出發…