基於STM32的FreeRTOS任務管理

2021-10-24 16:15:40 字數 4278 閱讀 4381

freertos是一款實時作業系統,可以設定任務的優先順序。

freertos用於mcu,占用irom約4~9kbyte,freertos支援裁剪功能(可裁剪性強)。

freertos 與 ucos-ii區別:

在商用條件下,freertos免費開源,而ucos-ii需要收費(非商用免費)。

任務設計上更容易。在ucos-ii中,每個任務的優先順序互不相同;而在freertos中,任務的優先順序的可以相同(對於相同優先順序任務,採用時間片輪詢方式排程)。

ucos中表示任務優先順序時,數字小的級別高;在freertos中表示任務優先順序時,數字大的級別高。

freertos是st欽定的第三方程式。

比如stm32cubemx軟體可以直接生成含freertos的工程。

在freertos中,可以設定任務的優先順序(一般是在建立任務的時候設定優先順序)

任務優先順序的範圍 受限於工程中freertosconfig.h的configmax_priorities 的值,低優先順序號表示任務的優先順序低,優先順序號 0 表示最低優先順序。有效的優先順序號範圍從 0 (configmax_priorites – 1)。

可以多個任務共用同乙個優先順序,那麼當他們被排程執行時,排程器會讓他們輪流執行(採用時間片機制)。

任務排程由排程器控制,一般優先順序排程當前可執行的任務中級別最高的任務。

而查詢是否需要切換任務排程需要特定操作,一般,mcu會在每個時鐘節拍產生後,檢測是否需要切換任務排程。

時鐘節拍發生的頻率

心跳中斷頻率由freertosconfig.h 中的編譯時配置常量 configtick_rate_hz 進行配置。

比如,若當前工程中configtick_rate_hz 為100,則當前系統每隔10ms產生一次時鐘節拍,檢測是否需要切換任務。

時鐘節拍的**

由stm32的systick(滴答定時器)提供。具體操作如下

(1)之後設計systick_init() 需要考慮,溢位時間為1.0/ configtick_rate_hz 秒,使用systick的溢位中斷

(2)重新設計systick的中斷服務函式(包含檢測是否需要切換任務)

執行狀態

當前正在執行的任務處於執行狀態,同一時間只有乙個任務處於執行狀態。

就緒狀態

如果任務處於非執行狀態,但既沒有阻塞也沒有掛起,則這個任務處於就緒(ready,準備或就緒)狀態

掛起狀態

(執行vtasksuspend()、vtaskresume())「掛起(suspended)」也是非執行狀態的子狀態。處於掛起狀態的任務對排程器而言是不可見的。

阻塞狀態

如果乙個任務正在等待某個事件,則稱這個任務處於」阻塞態(blocked)」。阻塞態是非執行態的乙個子狀態。

比如:void vtaskdelay( const ticktype_t xtickstodelay ); 使當前任務阻塞xtickstodelay個節拍

上圖反映了freertos下任務在就緒態、執行態、掛起態和阻塞態切換。結論:

只有處於就緒態的任務才能直接進入到執行態。

處於執行態的任務a,若執行期間存在優先順序更高的其他任務b(任務b必須是處於就緒態或執行態),則在最近時鐘節拍後,任務b取代任務a進入到執行態,原先任務a回到就緒態。

處於執行態的任務a,若執行期間呼叫vtasksuspend(),則進入到掛起態。處於掛起態的任務,需要其他任務對它呼叫vtaskresume(),才能進入到就緒態。

處於執行態的任務a,若執行期間呼叫含有阻塞功能函式(比如延時阻塞),則進入到阻塞態。處於阻塞態的任務需要滿足一定的條件才能進入到就緒態。

以stm32乙個已移植freertos的工程為例:

任務函式是用於實現任務功能的。

任務函式要求:

必須返回 void,而且帶有乙個 void *指標引數。其函式原型如下

void ataskfunction( void *pvparameters );

作為系統中主要執行的任務函式,函式體中要求包含while(1); 即使任務不會因為執行到函式結束而結束。任務函式設計如下:

void

ataskfunction

(void

*pvparameters )

刪除任務

eg:建立led1連續閃爍任務。設計led1的任務函式

void

led1taskfunction

(void

*pvparameters )

//刪除任務

}

補充:void vtaskdelay( const ticktype_t xtickstodelay );

使乙個任務進入阻塞狀態,等待規定時鐘節拍次數達到後,回到就緒態

考慮給任務分配棧區深度

需要結合任務函式進行分析,最終分配棧區大小必須要大於在該任務函式中分配/申請/使用到的空間之和。

比如:當前任務函式中由於未定義變數,不需要分配特別多的空間,分配100字大小即可。

呼叫建立任務的函式

taskhandle_t  led1_taskhandle;

//建立任務控制代碼(作為任務的id)

basetype_t xtaskcreate

( led1taskfunction,

「led1task」,

100,

null,1

,//優先順序

& led1_taskhandle )

;

void vtaskdelete( taskhandle_t xtasktodelete )

引數:任務的結構體(id)

void vtasksuspend( taskhandle_t xtasktosuspend )

掛起任務(引數填儲存任務id的變數/ 任務的控制代碼)

讓指定任務進入掛起態。

void vtaskresume( taskhandle_t xtasktoresume )

讓任務解除掛起繼續執行(引數填儲存任務id的變數/ 任務的控制代碼)

讓指定任務從掛起態到就緒態。

void vtaskstartscheduler( void )

使任務開始排程

void vtaskendscheduler( void )

停止排程

led1:0.3秒狀態反轉

led2:0.7秒狀態反轉

led3:1.1秒狀態反轉

uart:從『a』開始每隔1秒傳送字母

#include

"main.h"

void

led1_taskfunction

(void

*pvparameters)

;void

led2_taskfunction

(void

*pvparameters)

;void

led3_taskfunction

(void

*pvparameters)

;void

uart1_taskfunction

(void

*pvparameters)

;taskhandle_t led1taskhandle;

taskhandle_t led2taskhandle;

taskhandle_t led3taskhandle;

taskhandle_t uart1taskhandle;

intmain

(void

)//先設計led1任務

void

led1_taskfunction

(void

*pvparameters)

}//先設計led2任務

void

led2_taskfunction

(void

*pvparameters)

}//先設計led3任務

void

led3_taskfunction

(void

*pvparameters)

}//先設計uart1任務

void

uart1_taskfunction

(void

*pvparameters)

}

基於STM32的串列埠通訊

序列通訊一般是以幀格式傳輸資料,即一幀一幀的傳輸,每一幀都含有起始訊號,資料資訊以及停止資訊等。資料各個位同時傳輸,速度快,但是占用引腳資源多。eg led1602 資料按位順序傳輸,占用引腳資源少,但是速度相對較慢。一位一位傳輸 bit iic spi 串列埠通訊 單工,半雙工,全雙工 同步通訊 ...

基於STM32的恆流源設計

本設計以stm32f103rct6為主控晶元,利用mos管的恆流區特點,設計恆流源。設計電流範圍為1 300ma。基本原理圖 q2為n溝道mos管,在正常工作情況下,運放與mos管之間構成深度負反饋,使得輸入控制電壓與vr虛短,近似相等。這可以得到負載電流 3.1.電源 電路圖如圖所示 電源由 12...

linux spi驅動分析 基於STM32

linux kernel 版本2.6.30,spi驅動基於platform device,platform driver驅動模型來編寫.spi分為主從裝置,乙個主裝置下可心掛接多個從裝置,linux驅動中使用struct spi master結構來表示乙個主裝置,使用struct spi devic...