零基礎STM32單片機編程入門(五)FreeRTOS實時操作系統詳解及實戰含源碼視頻

文章目錄

    • 一.概要
    • 二.什么是實時操作系統
    • 三.FreeRTOS的特性
    • 四.FreeRTOS的任務詳解
      • 1.任務函數定義
      • 2.任務的創建
      • 3.任務的調度原理
    • 五.CubeMX配置一個FreeRTOS例程
      • 1.硬件準備
      • 2.創建工程
      • 3.調試FreeRTOS任務調度
    • 六.CubeMX工程源代碼下載
    • 七.講解視頻鏈接地址
    • 八.小結

一.概要

FreeRTOS是一個迷你的實時操作系統內核。作為一個輕量級的操作系統,功能包括:任務管理、時間管理、信號量、消息隊列、內存管理、記錄功能、軟件定時器、協程等,可基本滿足較小系統的需要。
由于RTOS需占用一定的系統資源(尤其是RAM資源),只有μC/OS-II、embOS、salvo、FreeRTOS等少數實時操作系統能在小RAM單片機上運行。相對μC/OS-II、embOS等商業操作系統,FreeRTOS操作系統是完全免費的操作系統,具有源碼公開、可移植、可裁減、調度策略靈活的特點,可以方便地移植到各種單片機上運行。

二.什么是實時操作系統

操作系統是一個控制程序,作為硬件和應用程序之間的橋梁,主要是和硬件打交道,負責協調分配計算資源和內存資源給不同的應用程序使用,并防止系統出現故障。面對來自不同應用程序的大量且互相競爭的資源請求,操作系統通過一個調度算法和內存管理算法盡可能把資源公平且有效率地分配給不同的程序。應用程序則通過調用操作系統提供的API接口獲得相應資源完成指定的任務。

實時操作系統(RTOS-Real Time Operating System)中實時(Real Time)指的是任務(Task)或者說實現一個功能的線程(Thread)必須在給定的時間(Deadline)內完成。

三.FreeRTOS的特性

具有搶占式或者合作式的實時操作系統內核
功能可裁剪,最小占用10kB左右rom空間,0.5kB ram空間
靈活的任務優先級分配
具有低功耗模式
有互斥鎖、信號量、消息隊列等功能
運行過程可追蹤
支持中斷嵌套

四.FreeRTOS的任務詳解

FreeRTOS的核心是任務調度器(Task Scheduler),它負責按照一定的調度策略將任務分配給處理器執行。每個任務都是一個獨立的函數,可以有不同的優先級和堆棧大小。任務調度器根據任務的優先級和調度策略決定哪個任務被執行。

下圖就是任務調度簡單介紹
在這里插入圖片描述

下面代碼就是個簡單的示例代碼,通過調用osThreadCreate函數創建了兩個任務LED_Thread1(驅動LED燈滅)和LED_Thread2(驅動LED燈亮)。在main函數中,通過調用osKernelStart函數啟動了實時系統,使得任務可以被調度執行,由于兩個任務都能不斷運行,所以能驅動LED燈閃爍。

//定義任務函數1
void LED_Thread1(void const * argument)
{(void) argument;for (;;){HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);//PC13輸出高,LED滅osDelay(100);//等待100ms}
}
//定義任務函數2
void LED_Thread2(void const * argument)
{(void) argument;for (;;){HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);//PC13輸出低,LED亮osDelay(250);//等待250ms}
}int main(void)
{HAL_Init();SystemClock_Config();//外部8M晶振,系統72M主頻MX_GPIO_Init();//PC13配置成推挽輸出MX_FREERTOS_Init();//實時系統初始化/* Start scheduler */osThreadDef(THREAD1, LED_Thread1, osPriorityNormal, 0, 128);THREAD1Handle = osThreadCreate(osThread(THREAD1), NULL);//建立任務1/* definition and creation of THREAD2 */osThreadDef(THREAD2, LED_Thread2, osPriorityNormal, 0, 128);THREAD2Handle = osThreadCreate(osThread(THREAD2), NULL);//建立任務2osKernelStart();//實時系統啟動while (1){}}

1.任務函數定義

無論采用何種方法創建任務,均需要用到任務函數。FreeRTOS 規定任務函數的返回值必須為void,而且帶有一個void型指針參數。

void LED_Thread1(void const * argument)
{(void) argument;for (;;){HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);//PC13輸出高,LED滅osDelay(100);//等待100ms}
}

STM32F103C8T6單片機只有一個內核,那怎么讓多個人同時干活呢?其實每個子任務雖然都是死循環,但并不是每個子任務一直都在執行,每個子任務在執行期間,可能需要延時,這邊就通過 osDelay(100),等待100ms,單片機就可以停止此任務,然后切換到其它任務執行,這樣看起來就是多個人在同時干活了。

2.任務的創建

osThreadDef(THREAD1, LED_Thread1, osPriorityNormal, 0, 128);//定義一個任務,任務名,任務函數,優先級,堆棧大小
THREAD1Handle = osThreadCreate(osThread(THREAD1), NULL);  //根據上面定義的任務,創建一個任務

osThreadDef函數中的128是任務棧大小定義:

任務棧大小指定了任務可以使用多少RAM來存儲局部變量和其他臨時數據。這個大小應該足夠大,能夠容納任務在執行期間可能出現的最大需求。

osThreadDef函數中的LED_Thread1是任務函數:

任務函數是任務執行的代碼,它應該是一個無返回值的函數,其參數是一個可選的指針,可以用來傳遞任何需要的數據,我們代碼中的任務就是控制GPIO輸出高或者低電平。

osThreadDef函數中的osPriorityNormal任務優先級:

任務優先級決定了任務在操作系統調度下的執行順序。數值越大,優先級越高。

osThreadCreate函數的返回值THREAD1Handle是任務句柄:

任務句柄是一個指針,可以用來引用已經創建的任務,以便可以在任務創建后對其進行操作,例如刪除、掛起、恢復等。

3.任務的調度原理

FreeRTOS默認使用搶占式調度策略,對同等優先級的任務使用時間片輪詢調度,時間片輪詢就是可輪流享有相同的單片機時間(可設置),一個時間片等于SysTick中斷周期。
搶占式調度是指調度器始終運行優先級最高且處于可運行狀態的任務,無論任務何時可以運行。如在中斷服務函數中更改了優先級最高且可運行的任務,調度器會停止當前執行的低優先級任務,并啟動高優先級任務。
剛才程序中的osDelay 是通過將當前任務加入到延時列表中,并設置一個定時器來在指定的延時時間,延時時間過去之后將任務從延時列表中移除并將其設置為就緒狀態。這樣當定時器觸發時,任務重新被加入到就緒列表中,等待被調度器再次調度執行。

上面代碼中的LED_Thread1(驅動LED燈滅)和LED_Thread2(驅動LED燈亮)兩個任務的調度順序以及時間,如下圖所示,橫坐標是時間,箭頭代表運行順序
在這里插入圖片描述

下面代碼截圖就是操作系統底層尋找就緒任務的最高優先級,獲取優先級最高的就緒任務的 TCB(任務控制塊),然后更新到 pxCurrentTCB ,當前運行的任務只可能有一個,因此pxCurrentTCB只是單個TCB_t指針,它始終指向當前運行的任務。通過xPortPendSVHandler(PendSV_Handler)函數實現調度
在這里插入圖片描述
PendSV_Handler 是 ARM Cortex-M 處理器中的一個特殊的中斷處理函數,用于處理掛起 PendSV(Pending Supervisor Call)中斷。PendSV 中斷是 Cortex-M 架構中的一種特殊的軟件中斷,它可以用來實現任務切換或者其他與系統調度相關的操作。
PendSV_Handler 在中斷向量表的位置
在這里插入圖片描述

__asm void xPortPendSVHandler( void ){extern uxCriticalNesting;extern pxCurrentTCB;extern vTaskSwitchContext;PRESERVE8mrs r0, psp //(1)        讀取進程棧指針,保存在寄存器 R0 里面。isbldr r3, =pxCurrentTCB//(2)   獲取當前任務的任務控制塊,并將任務控制塊的地址保存在寄存器 R2 里面。ldr r2, [r3] //(3)tst r14, #0x10 //(4)        判斷任務是否使用了 FPUit eq //(5)vstmdbeq r0!, {s16-s31}// (6)stmdb r0!, {r4-r11, r14} //(7)str r0, [r2] //(8)stmdb sp!, {r3} //(9)mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY //(10)       msr basepri, r0 //(11)           關閉中斷,進入臨界區dsbisbbl vTaskSwitchContext //(12)    調用函數 vTaskSwitchContext(),此函數用來獲取下一個要運行的任務,并將pxCurrentTCB 更新為這個要運行的任務。mov r0, #0 //(13)msr basepri, r0 //(14)        打開中斷,退出臨界區。ldmia sp!, {r3} //(15)ldr r1, [r3] //(16)ldr r0, [r1] //(17)ldmia r0!, {r4-r11, r14} //(18)tst r14, #0x10 //(19)it eq //(20)vldmiaeq r0!, {s16-s31} //(21)msr psp, r0 //(22)           更新進程棧指針 PSP 的值isbbx r14 //(23)     執行此行代碼以后硬件自動恢復寄存器 R0~R3、 R12、 LR、 PC 和 xPSR 的值,確定異常返回以后應該進入處理器模式還是進程模式,使用主棧指針(MSP)還是進程棧指針(PSP)。很明顯這里會進入進程模式,并且使用進程棧指針(PSP),寄存器 PC 值會被恢復為即將運行的任務的任務函數,新的任務開始運行!至此,任務切換成功。}

五.CubeMX配置一個FreeRTOS例程

1.硬件準備

STLINK接STM32F103C8T6小系統板,STLINK接電腦USB口。

在這里插入圖片描述

2.創建工程

打開STM32CubeMX軟件,新建工程
在這里插入圖片描述
Part Number處輸入STM32F103C8,再雙擊就創建新的工程
在這里插入圖片描述
配置下載口引腳
在這里插入圖片描述
配置外部晶振引腳
在這里插入圖片描述

可以查看STM32F103C8T6小系統板原理圖,PC13連接LED燈,所以配置PC13為GPIO輸出

在這里插入圖片描述
配置FreeRTOS
在這里插入圖片描述
配置系統主頻
在這里插入圖片描述
配置工程文件名,保存路徑,KEIL5工程輸出方式
在這里插入圖片描述
生成工程
在這里插入圖片描述
用Keil5打開工程
在這里插入圖片描述
添加代碼
在這里插入圖片描述
在這里插入圖片描述

3.調試FreeRTOS任務調度

調試代碼,能更好理解任務調度。
下載調試,在LED_Thread1打斷點,程序能運行到斷點處停止
在這里插入圖片描述
在LED_Thread2打斷點,程序也能運行到斷點處停止
在這里插入圖片描述

在xPortPendSVHandler調度函數中打斷點,可以看到操作系統將要跳轉到任務1運行
在這里插入圖片描述
單步執行,運行指針就跳轉到任務1開始運行
在這里插入圖片描述

xPortPendSVHandler調度函數中打斷點,可以看到操作系統將要跳轉到任務2運行
在這里插入圖片描述
單步執行,運行指針就跳轉到任務2開始運行
在這里插入圖片描述

六.CubeMX工程源代碼下載

鏈接:https://pan.baidu.com/s/1f50X8w2UXnDtbM6U6zwYqw
提取碼:0sys
如果鏈接失效,可以聯系博主給最新鏈接

程序下載下來之后解壓就行

七.講解視頻鏈接地址

FreeRTOS實驗

八.小結

FreeRTOS實時操作系統能使在STM32軟件開發中,程序結構清晰,單片機執行效率提升許多,在多個任務模塊的代碼中,可以考慮使用FreeRTOS。

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

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

相關文章

[SwiftUI 開發] 嵌套的ObservedObject中的更改不會更新UI

1. 發生問題的demo 業務邏輯代碼 class Address: ObservableObject {Published var street "123 Apple Street"Published var city "Cupertino" }class User: ObservableObject {Published var name "Tim Cook"Published var address Addr…

解決 Win11 微軟拼音輸入法下 JetBrains IDE Shift+F6 失效的問題

一、使用舊版微軟拼音輸入法 1.在任務欄中輸入法圖標上右鍵,點擊“設置”,或者在系統設置中進入“時間和語言 -> 語言和區域 -> 微軟拼音輸入法”設置項。 2.點擊進入“常規”類別,滾動到頁面底部,找到“兼容性 -> 使用…

nacos漏洞小結

Alibaba Nacos是阿里巴巴推出來的一個新開源項目,是一個更易于構建云原生應用的動態服務發現、配置管理和服務管理平臺。致力于幫助發現、配置和管理微服務。Nacos提供了一組簡單易用的特性集,可以快速實現動態服務發現、服務配置、服務元數據及流量管理…

我的創作紀念日 第四年 我在人間遭罪,也在人間享樂

回顧 一晃四年過去了,從畢業到現在依舊沒有后悔自己當初的選擇是工作而不是繼續讀研。 讀研雖然可以給我更高的起點,但破碎的底層建筑和生活壓力讓我沒的選擇,畢竟只是一介凡人,而且還是底層出身,環境差,觀…

64、哥倫比亞大學:CU-Net-目前腦腫瘤分割的最先進模型

本文已被接受發表在2024年IEEE MLISE會議上(c)2024 IEEE。準確地將腦腫瘤從MRI掃描中分割出來對于制定有效的治療方案和改善患者預后至關重要。本研究引入了一種新的哥倫比亞大學網絡(CU-Net)架構實現,用于使用BraTS 2…

收銀系統源碼-千呼新零售2.0【移動管理端】

千呼新零售2.0系統是零售行業連鎖店一體化收銀系統,包括線下收銀線上商城連鎖店管理ERP管理商品管理供應商管理會員營銷等功能為一體,線上線下數據全部打通。 適用于商超、便利店、水果、生鮮、母嬰、服裝、零食、百貨、寵物等連鎖店使用。 詳細介紹請…

如何循環遍歷循環中的剩余元素

1、問題背景 給定一段文本,文本中包含多條錯誤信息,每條錯誤信息包含行號、錯誤路徑和錯誤信息。需要從文本中提取出這些錯誤信息,并以特定的格式輸出。 line, Error 12, This is the Error line, Error 34, Another Error line, Error …

【Linux】線程周邊002之線程安全

👀樊梓慕:個人主頁 🎥個人專欄:《C語言》《數據結構》《藍橋杯試題》《LeetCode刷題筆記》《實訓項目》《C》《Linux》《算法》 🌝每一個不曾起舞的日子,都是對生命的辜負 目錄 前言 1.Linux線程互斥 1…

每日一題——Python實現PAT乙級1050 螺旋矩陣(舉一反三+思想解讀+逐步優化)6千字好文

一個認為一切根源都是“自己不夠強”的INTJ 個人主頁:用哲學編程-CSDN博客專欄:每日一題——舉一反三Python編程學習Python內置函數 Python-3.12.0文檔解讀 目錄 我的寫法 時間復雜度分析 空間復雜度分析 總結 我要更強 代碼解釋 時間復雜度 …

小區服務前臺小程序的設計

管理員賬戶功能包括:系統首頁,個人中心,住戶管理,管理員管理,員工管理,安保管理,安保分配管理,客服聊天管理 微信端賬號功能包括:系統首頁,公告,…

Mongodb集群中的分布式讀寫

學習mongodb,體會mongodb的每一個使用細節,歡迎閱讀威贊的文章。這是威贊發布的第81篇mongodb技術文章,歡迎瀏覽本專欄威贊發布的其他文章。如果您認為我的文章對您有幫助或者解決您的問題,歡迎在文章下面點個贊,或者關…

互聯網摸魚日報(2024-07-01)

互聯網摸魚日報(2024-07-01) 36氪新聞 最前線 | 孚能科技廣州基地投產,年產能30GWh,主推SPS大軟包產品 本周雙碳大事:800億元“風光火儲”大項目來了;光伏巨頭SolarEdge股價驟跌20%;韓國電池廠大火,鋰電安…

目標檢測算法的優缺點

目標檢測算法在計算機視覺領域具有廣泛的應用,其優缺點因算法類型和具體實現而有所不同。以下是對一些主流目標檢測算法優缺點的概述: 1. 傳統目標檢測算法 優點: 模型簡單:傳統目標檢測算法通常基于手工設計的特征和分類器&am…

Java進階學習|Day3.Java集合類(容器),Stream的使用,哈希初接觸

java集合類(容器) Java中的集合類主要由Collection和Map這兩個接口派生而出,其中Collection接口又派生出三個子接口,分別是Set、List、Queue。所有的Java集合類,都是Set、List、Queue、Map這四個接口的實現類&#xf…

Powershell 簡易爬蟲,提取種子網站的磁力鏈接

目錄 一. 需求二. 分析2.1 思路分析2.2 技術點 三. 代碼四. 效果 一. 需求 ?有網站如下所示,先要求從按照關鍵詞搜索到的網頁中,提取出所有的磁力鏈接。 二. 分析 2.1 思路分析 打開網頁之后,從網頁中先提取出所有的標題相關的url然后再打…

linux驅動部分內容整理

文章目錄 Linux驅動概念應用程序調用驅動程序流程驅動模塊的加載linux設備號加載和卸載注冊新字符設備注冊設備節點自動創建設備節點編譯編譯驅動程序編譯應用程序 地址映射ioctrl命令碼的解析 并發與競爭原子操作自旋鎖信號量互斥體 linux中斷DMA映射其它printkmemcpyvolatile…

如何在ubuntu上安裝ros-noetic?

如何在ubuntu上安裝ros-noetic? 1. 源由2. 快速安裝3. ROS學習 1. 源由 圍繞ros-noetic這個系統,前面已經有不少談及: Linux 35.5 JetPack v5.1.3ros-noetic安裝Linux 35.5 JetPack v5.1.3Fast-Planner編譯安裝Linux 35.5 JetPack v5.1.…

RocketMQ常用基本操作

文章中的rabbitmq使用的是rocketmq-all-5.1.3-bin-release版本,需要安裝包的可自行下載 RockerMQ啟動停止命令 啟動命令 nohup sh bin/mqnamesrv & nohup sh bin/mqbroker -n localhost:9876 --enable-proxy & 查看日志 tail -f ~/logs/rocketmqlogs/…

多線程編程的挑戰與解決方案

多線程編程的挑戰與解決方案 大家好,我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編,也是冬天不穿秋褲,天冷也要風度的程序猿! 1. 多線程編程的挑戰 在現代軟件開發中,多線程編程成為處理并發任務…

PatchTST創新點

這篇論文的創新點主要集中在PatchTST模型的設計和應用中。以下是對其創新點的詳細說明: 創新點 頻道獨立補丁設計:PatchTST模型通過將多變量時間序列分割成不同的頻道,每個頻道作為單變量時間序列處理。每個頻道獨立地通過實例歸一化操作和補…