esp32基于Arduino框架的freertos使用——定時器xTimerCreate
開發(fā)平臺:vscode+platformIO? ? 框架:arduino? ? 開發(fā)板:esp32-wroom-32
API參考文檔:https://www.freertos.org/a00106.html
定時器:xTimerCreate()??創(chuàng)建一個新的軟件計時器實例并返回一個可以引用計時器的句柄
開啟定時器:xTimerStart()? 創(chuàng)建實例之后需要啟用。
????如果立刻激活,則不用阻塞10個tick,直接返回pdPASS,如果任務(wù)隊列已滿,沒有立刻激活,則在此處阻塞10個tick等待激活。10個tick后如果任務(wù)激活,則返回pdPASS,若沒有激活,則返回pdFAIL。(當然這個只是我自己通俗的理解)
真實詳細可以去韋東山老師的網(wǎng)站:http://rtos.100ask.net/freeRTOS%E6%95%99%E7%A8%8B/index.html
這里需要注意定時回調(diào)函數(shù)傳參需要指定為void *Parameter,否則會報錯。回調(diào)函數(shù)可以使用簡單的IO操作,可以進行運算。不應(yīng)該使用阻塞函數(shù)。
下面這么寫就會報錯,這兩個函數(shù)只是同名的函數(shù)。
在其他地方可以使用xTimerIsTimerActive()方法去判斷某個定時器是否啟用
自己的心得:
????使用定時器的初衷是可以實現(xiàn)一些復(fù)雜的定時任務(wù),但是實際上使用xTimerStart得到的實例只能處理一些簡單的任務(wù),IO,數(shù)據(jù)的運算,當我嘗試在定時器中刷新IIC屏幕時,干脆整個回調(diào)函數(shù)直接就不執(zhí)行了。而使用Ticker庫的方法同樣可以使用定時器,但是限制上沒有這么多。
????定時任務(wù)的規(guī)則其實是按照絕對時間來啟用任務(wù)的,但是如果回調(diào)函數(shù)運行時長超時,也會一直運行到正常結(jié)束。這樣子程序是穩(wěn)定了,但是會不會按照意愿進行就不能保證了。
????舉個例子:如下圖所示:定時任務(wù)50ms執(zhí)行一次,但是任務(wù)執(zhí)行20ms。這是非常復(fù)合預(yù)期的結(jié)果。事實上就是每50ms運行一次。如果任務(wù)執(zhí)行時間為80ms。則在50ms時任務(wù)就會變?yōu)榫途w狀態(tài)。80ms任務(wù)執(zhí)行完成,則會直接再次執(zhí)行任務(wù)。

????這么看來,其實多任務(wù)時,單純的使用定時器,很有可能造成一些不可估量的后果。如果存在兩個任務(wù)都定時為50ms,但是運行時間都是30ms。則會出現(xiàn)兩個任務(wù)每30ms交替運行一次。一次循環(huán)就是60ms。和預(yù)期的50ms出現(xiàn)了不符。如果再極端一點,任務(wù)執(zhí)行時間為100ms,則一次循環(huán)就是200ms,若任務(wù)優(yōu)先級不一樣,則時間一直會被高優(yōu)先級的任務(wù)獨占,低優(yōu)先級的無法運行。
????定時任務(wù)不會被另一個定時任務(wù)打斷,運行時間過長可能會導(dǎo)致運行不按照預(yù)期進行。一些簡單的任務(wù)直接使用Ticker庫其實蠻不錯的。起碼比xTimerCrate來說容量更大。