STM32手動移植FreeRTOS

📦 準備工作

  1. 獲取FreeRTOS源碼:

    • 訪問?FreeRTOS官網?或其?GitHub倉庫?下載最新版內核源碼。

    • 你也可以使用Git克隆(注意要包含子模塊):git clone https://github.com/FreeRTOS/FreeRTOS.git --recurse-submodules

  2. 準備STM32基礎工程:

    • 使用?STM32CubeMX?生成一個針對你芯片型號的裸機工程(例如一個簡單的LED閃爍工程),配置好時鐘樹、調試接口(如SYS)和你需要的外設(如GPIO、USART等)。

    • 確保這個基礎工程在你的開發板上能夠編譯并通過(例如,LED能閃爍)。

📁 文件組織與添加

在你的STM32工程目錄下(通常與CoreDrivers等文件夾同級),創建一個用于存放FreeRTOS源碼的文件夾,例如Middlewares/FreeRTOS。然后按照下表的指引將必要的文件復制到相應位置:

所需文件源路徑 (基于FreeRTOS源碼根目錄)目標路徑 (你的工程目錄)作用描述
核心源文件(.c)FreeRTOS/Source/*.c?(如?tasks.c,?queue.c,?list.c等)Middlewares/FreeRTOS/SourceFreeRTOS內核的核心功能實現
核心頭文件(.h)FreeRTOS/Source/include/*.hMiddlewares/FreeRTOS/Source/includeFreeRTOS內核的頭文件,提供API和數據類型定義
移植層文件FreeRTOS/Source/portable/[Compiler]/[Architecture]/*Middlewares/FreeRTOS/Source/portable與編譯器及CPU架構相關的移植代碼(關鍵選擇,見下文說明
內存管理實現FreeRTOS/Source/portable/MemMang/heap_x.c?(選一個)Middlewares/FreeRTOS/Source/portable/MemMangFreeRTOS的動態內存管理方案(五選一,通常推薦heap_4.c
配置文件FreeRTOS/Demo/[Demo項目]/FreeRTOSConfig.h通常放在工程Inc目錄或Middlewares/FreeRTOSFreeRTOS內核的配置文件(需根據你的芯片和需求修改

🔧 關鍵選擇說明:

  • 移植層文件 ([Compiler]和[Architecture]):

    • [Compiler]: 根據你使用的開發環境選擇。

      • Keil MDK: 選擇?RVDS?目錄。

      • IAR: 選擇?IAR?目錄。

      • GCC (如STM32CubeIDE, CLion): 選擇?GCC?目錄。

    • [Architecture]: 根據你STM32芯片的Cortex內核型號選擇。

      • Cortex-M0:?ARM_CM0

      • Cortex-M3:?ARM_CM3

      • Cortex-M4?(無FPU):?ARM_CM4F

      • Cortex-M7?(有FPU):?ARM_CM7

      • *例如,STM32F103是Cortex-M3,STM32F407是Cortex-M4。*

  • 內存管理實現 (heap_x.c):
    FreeRTOS提供了5種內存管理方案,通常選擇?heap_4.c支持內存分配與釋放,并能有效減少碎片)。對于極其簡單或從不釋放內存的應用,也可考慮?heap_1.c

📝 操作步驟:

  1. 在你的工程目錄下(例如Middlewares/FreeRTOS)創建相應的子文件夾:Source,?Source/include,?Source/portable

  2. 根據上表和你的芯片、編譯器情況,將FreeRTOS源碼包中對應的文件復制到剛剛創建的相應文件夾中。

  3. 從FreeRTOS源碼包的Demo文件夾里,找一個與你芯片型號相近的Demo工程,將其中的FreeRTOSConfig.h文件復制到你的工程目錄下(通常放在Inc目錄下便于包含)。

?? 工程配置與修改

1. 添加文件到IDE工程

  • 打開你的Keil MDK(或其他IDE)工程。

  • 在IDE中創建新的分組(Group),例如 "FreeRTOS_CORE", "FreeRTOS_PORTABLE"。

  • 將剛才復制到Middlewares/FreeRTOS/Source下的.c文件(如tasks.c,?queue.c等)添加到 "FreeRTOS_CORE" 分組。

  • 將你選擇的內存管理文件(如heap_4.c)和移植層文件(如port.c)添加到 "FreeRTOS_PORTABLE" 分組。

  • 不要添加其他未選擇的內存管理文件和移植層文件。

2. 添加頭文件路徑

在IDE的工程設置("Options for Target" -> "C/C++" -> "Include Paths")中,添加以下頭文件路徑35:

  • ../Middlewares/FreeRTOS/Source/include

  • ../Middlewares/FreeRTOS/Source/portable/[Compiler]/[Architecture]?(例如?../Middlewares/FreeRTOS/Source/portable/RVDS/ARM_CM3)

  • 確保也包含了存放FreeRTOSConfig.h文件的路徑(如../Inc)。

3. 修改FreeRTOSConfig.h

FreeRTOSConfig.h是FreeRTOS的核心配置文件,你需要根據你的芯片和項目需求進行修改。以下是一些最關鍵的配置項34:

配置宏說明與典型設置
configCPU_CLOCK_HZ設置為你STM32芯片的主時鐘頻率(Hz),例如STM32F103為72000000,STM32F407為168000000。可直接使用?SystemCoreClock
configTICK_RATE_HZ系統節拍頻率。通常設置為1000Hz,表示1ms一個時鐘節拍。
configTOTAL_HEAP_SIZEFreeRTOS動態內存堆的總大小。根據你計劃創建的任務、隊列等數量估算。如果不夠,任務創建會失敗。例如可先設置為(10 * 1024)(10KB),后續再調整。
configMAX_PRIORITIES系統支持的最大任務優先級數。設置一個夠用的值即可,如5-8,不是越大越好。
configKERNEL_INTERRUPT_PRIORITY``configMAX_SYSCALL_INTERRUPT_PRIORITY中斷優先級配置非常重要!需要根據你芯片的NVIC優先級位數(如STM32F1/F4是4位,即0-15)和你的應用來設置。設置錯誤可能導致系統不穩定或無法運行。務必仔細查閱FreeRTOS手冊和芯片數據手冊
configUSE_PREEMPTION設置為1啟用搶占式調度器,這是最常用的模式。
configUSE_TIMERS``configTIMER_TASK_PRIORITY``configTIMER_QUEUE_LENGTH``configTIMER_TASK_STACK_DEPTH如果你要使用軟件定時器,需要將這些配置使能并設置相關參數。

其他常用配置:你還可以根據需求使能或禁用互斥量(configUSE_MUTEXES)、遞歸互斥量(configUSE_RECURSIVE_MUTEXES)、事件組(configUSE_EVENT_GROUPS)、棧溢出檢查(configCHECK_FOR_STACK_OVERFLOW)等功能。

4. 處理中斷服務程序(ISR)

FreeRTOS需要接管SVCPendSVSysTick這三個中斷246。

  • 打開你的工程中stm32fxxx_it.c文件(例如stm32f1xx_it.cstm32f4xx_it.c)。

  • 找到并注釋掉或刪除以下三個函數的具體實現:

    • SVC_Handler(void)

    • PendSV_Handler(void)

    • SysTick_Handler(void)

  • 原因:這些中斷的服務程序已經在你之前添加的移植層文件(如port.c)中實現了。如果不注釋掉,會導致函數重復定義。

注意SysTick的特殊情況:如果你的HAL庫仍然使用SysTick作為時基源(HAL_InitTick()),你可能需要修改SysTick_Handler而不是簡單地刪除它。一種常見的做法是28:

c

#include "FreeRTOS.h"
#include "task.h"void SysTick_Handler(void)
{HAL_IncTick(); // 維持HAL庫的時基if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {xPortSysTickHandler(); // 調用FreeRTOS的SysTick Handler}
}

確保在FreeRTOSConfig.h中啟用了INCLUDE_xTaskGetSchedulerState宏。

5. 修改HAL庫的時基源(強烈推薦)

STM32的HAL庫默認使用SysTick作為其時基源(用于HAL_Delay(),?HAL_GetTick()等)。而FreeRTOS也使用SysTick作為其任務調度的時鐘節拍。雖然通過一些技巧可以讓兩者共享SysTick,但更推薦的做法是將HAL庫的時基源切換到另一個硬件定時器(如TIM1, TIM6等),以避免潛在沖突9。

  • 你可以在STM32CubeMX中重新配置:在SYS選項下,將Timebase SourceSysTick改為其他的硬件定時器(如TIM1)。

  • 或者直接修改代碼:在main.cHAL_Init()調用之后,重新初始化一個定時器作為HAL庫的時基源。

🧪 編寫測試代碼

完成以上步驟后,就可以編寫簡單的FreeRTOS任務來測試移植是否成功了。

  1. 包含頭文件:在main.c中包含FreeRTOS頭文件。

    #include "FreeRTOS.h"
    #include "task.h"
    #include "queue.h" // 如果需要使用隊列等功能
  2. 創建任務函數:定義至少一個簡單的任務函數。

    void vTaskLED(void *pvParameters) {for (;;) {HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); // 假設LED連接在PC13vTaskDelay(500); // 延遲500個時鐘節拍,即500ms (假設configTICK_RATE_HZ=1000)}
    }
  3. 創建任務并啟動調度器:在main()函數的初始化代碼之后(while (1)之前)創建任務并啟動FreeRTOS調度器。

    int main(void) {HAL_Init();SystemClock_Config();// ... 其他外設初始化代碼// 創建任務xTaskCreate(vTaskLED, "LED_Task", 128, NULL, 2, NULL);// 啟動FreeRTOS調度器,永遠不會返回vTaskStartScheduler();for (;;) {} // 調度器啟動后,不會執行到這里
    }

🔬 編譯、下載與調試

  1. 編譯工程:解決所有編譯錯誤。常見的錯誤包括頭文件路徑不正確、函數未定義(可能是移植層文件沒添加或路徑錯誤)、重復定義(中斷服務函數沒注釋掉)等。

  2. 下載到開發板并運行。

  3. 觀察現象:如果一切正常,LED應該會以你設置的周期閃爍。

  4. 使用調試器:如果程序運行不正常,使用調試器進行單步調試,檢查系統是否能成功創建任務、是否成功啟動調度器、是否進入正確的硬件中斷等。

?? 常見問題排查

  • 編譯錯誤?undefined reference to ...: 檢查FreeRTOS的.c文件是否都已添加到工程組中,頭文件路徑是否設置正確。

  • 編譯錯誤?redefinition of ...: 檢查stm32fxxx_it.c中的SVC、PendSV、SysTick中斷處理函數是否已注釋掉。

  • 程序在啟動調度器后卡死或進入HardFault:

    • 檢查FreeRTOSConfig.h中的configCPU_CLOCK_HZ是否設置正確。

    • 檢查FreeRTOSConfig.h中的中斷優先級配置(configKERNEL_INTERRUPT_PRIORITYconfigMAX_SYSCALL_INTERRUPT_PRIORITY)是否正確。這是非常常見的錯誤來源

    • 檢查堆大小configTOTAL_HEAP_SIZE是否足夠創建初始任務。

    • 使用調試器檢查是否成功進入SVC_Handler(用于啟動第一個任務)。

  • SysTick中斷沖突: 確保HAL庫的時基源已切換至非SysTick的定時器,或者按照前述方法修改了SysTick_Handler函數。

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

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

相關文章

C5僅支持20MHZ帶寬,如果路由器5Gwifi處于40MHZ帶寬信道時,會出現配網失敗

是的,這會導致“怎么都連不上”。結論先說:如果路由器把 5 GHz 固定在 40 MHz(或以上)帶寬,而你的 C5 只支持 5 GHz 的 20 MHz 帶寬,那么 STA 連接一定會失敗。固件里不可能“把 40 MHz AP 連成 20 MHz”&a…

堅鵬請教DEEPSEEK:請問中國領先的AI智能體服務商有哪些?知行學

堅鵬請教DEEPSEEK:請問中國領先的AI智能體服務商有哪些?深圳知行學教育科技公司名列榜首根據2025年8月底多家權威機構發布的榜單和報告,比如德本咨詢(DBC)的“2025企業級AI Agent應用TOP50”榜單、IDC的《中國AI AGENT…

【開題答辯全過程】以 投票系統為例,包含答辯的問題和答案

個人簡介一名14年經驗的資深畢設內行人,語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧。感謝大家的…

C++異常處理指南:構建健壯程序的錯誤處理機制

在程序開發的世界里,“錯誤” 是繞不開的話題。你可能寫過一個簡單的計算器,卻因為用戶輸入 “50” 而崩潰;也可能在操作數據庫時,因為權限不足導致數據讀取失敗;甚至在申請內存時,因為系統資源耗盡而無法繼…

comfUI背后的技術——VAE

第一次知道VAE可能還是許嵩。當然,這里的VAE指的是變分自編碼器(Variational Autoencoder, VAE) Seq2Seq 在 Seq2Seq 框架提出之前,深度神經網絡在圖像分類等問題上取得了非常好的效果。在其擅長解決的問題中,輸入和…

【序列晉升】21 Spring Cloud Gateway 云原生網關演進之路

Spring Cloud Gateway作為Spring生態系統中的核心組件,已成為微服務架構中的首選API網關解決方案。它基于響應式編程模型,提供高性能、可擴展的路由管理和跨領域功能,解決了傳統微服務架構中的接口聚合、安全管控和流量控制等核心問題。與此同…

“HEU-AUTO”無線上網使用指南

本文針對筆記本電腦 筆者電腦型號為:2025聯想拯救者Y9000p 5060步驟1:點擊開始菜單,點擊設置,如圖步驟2:在Windows設置菜單中,點擊“網絡和Internet”選項,如下圖:步驟3:…

微信小程序中藍牙打印機中文編碼處理:使用iconv-lite庫

在微信小程序開發中,集成藍牙打印機實現中文打印是常見需求,但中文文本常因編碼不匹配(如UTF-8與GBK沖突)導致亂碼問題。本文詳細解釋如何利用iconv-lite庫高效處理中文編碼轉換,確保打印內容正確顯示。文章結構清晰,逐步引導您解決問題,代碼示例基于實際項目驗證。 1. …

GraphRAG——v0.3.6版本使用詳細教程、GraphRAG數據寫入Neo4j圖數據庫、GraphRAG與Dify集成

GraphRAG——v0.3.6版本使用詳細教程、GraphRAG數據寫入Neo4j圖數據庫、GraphRAG與Dify集成理論部分安裝知識圖譜生成測試將數據導入到Neo4j圖數據庫可視化將GraphRAG與Dify集成理論部分 https://guoqingru.blog.csdn.net/article/details/150771388?spm1011.2415.3001.5331安…

MongoDB 聚合管道(Aggregation)高級用法:數據統計與分析

MongoDB 聚合管道(Aggregation)高級用法:數據統計與分析第一章:聚合管道核心概念與架構設計1.1 聚合管道的本質與價值1.2 管道階段深度解析1.3 執行引擎與優化機制第二章:高級分組與多維統計分析2.1 復合分組與層次化分…

Twitter輿情裂變鏈:指紋云手機跨賬號協同機制提升互動率200%

——基于動態設備指紋與智能行為仿真的裂變增長體系??一、Twitter輿情運營的三大核心挑戰?賬號關聯風險?同一設備/IP操作多賬號觸發平臺風控,封號率高達65%,輿情響應鏈路斷裂固定設備參數(如GPU型號/屏幕分辨率)導致賬號權重暴…

【密集目標檢測】停車場車輛(車位)識別數據集:12k+圖像,yolo標注

停車場車輛(車位)識別數據集概述 數據集包含12415張從監控攝像頭畫面中截取的停車場圖像,涵蓋晴天、陰天和雨天場景,標注類別包含車位占用、空車位2類。 標注格式:yolo txt 標注工具:labelme/labelimg 分辨率:416*416 一、學術研究的奠基與迭代 停車場車輛(車位)…

蒼穹外賣項目筆記day02

接下來的筆記都會以難點與一些不常見的方法為主,一些重復的crud并不會出現哦 ThreadLocal類 ThreadLocal 并不是一個Thread,而是Thread的局部變量,它用于創建線程局部變量。 核心思想:每個線程都有自己獨立的變量副本。這意味著,即…

設計模式12-適配器模式

定義 Adapter Partern: 將一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。 場景 系統需要使用現有的類,而這些類的接口不符合系統的需要。 典型場景:集成第三方庫、遺留系統代…

VGG改進(6):基于PyTorch的VGG16-SE網絡實戰

1. 引言:注意力機制在計算機視覺中的重要性近年來,深度學習在計算機視覺領域取得了巨大成功,從圖像分類到目標檢測,各種復雜任務都獲得了前所未有的性能提升。然而,傳統的卷積神經網絡(CNN)在處…

[電商網站-動態渲染商品-尺寸、尺碼、顏色圖片等];庫存缺貨狀態動態對應。

目錄 描述: 數據結構 組件代碼文件 描述: 自動處理SKU數據生成規格屬性列表 支持用戶選擇不同規格組合 智能禁用無庫存選項 自動匹配當前選擇對應的SKU信息 通過視覺樣式區分可選/不可選狀態 該組件采用Vue實現,通過計算屬性和響應式數據…

論《運動戰》

運動戰的本質是以機動換主動,以時間換空間,通過高度的流動性、主動的位移和靈活的戰術選擇,在動態中創造并捕捉戰機,最終以較小的代價換取最大的勝利。它是一種非對稱的、主動的作戰哲學,其核心不在于一城一地的得失&a…

DVWA靶場通關筆記-CSRF(Impossible級別)

目錄 一、查看源碼 二、功能分析 三、CSRF防范分析 1、CSRF令牌驗證機制 (1)核心原理 (2)防范機制 2、舊密碼確認防御實現 (1)核心原理 (2)為什么舊密碼確認能有效防范CSRF…

深層語義在自然語言處理中的理論框架與技術融合研究

摘要本文章系統闡述了深層語義在自然語言處理(NLP)領域的定義、特征及其與知識圖譜和大型預訓練語言模型的融合方法。基于截至2025年8月的最新研究成果,報告深入分析了深層語義的多維度特性、技術實現路徑以及面臨的挑戰,為研究人…

深入解析HarmonyOS:UIAbility與Page的生命周期協同

深入解析HarmonyOS:UIAbility與Page的生命周期協同 在HarmonyOS應用開發中,理解UIAbility和Page的生命周期是構建高質量應用的關鍵。本文將深入探討這兩大核心概念的生命周期及其協同工作機制,幫助開發者更好地管理應用資源、優化用戶體驗。…