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...