app_timer是大家經(jīng)常用到的一個(gè)庫,app_timer的功能就是定時(shí),也就是說,你在某一時(shí)刻啟動(dòng)一個(gè)app timer并設(shè)定超時(shí)時(shí)間,超時(shí)時(shí)間一到,app_timer就會(huì)回調(diào)timeout handler,然后執(zhí)行你需要的工作。使用app_timer時(shí)有如下幾點(diǎn)需要注意:
app_timer底層使用的是RTC1,而不是timer1/2/3/4,所以app_timer的功耗非常低:0.1uA左右。
app_timer計(jì)時(shí)精度為1ms,也就是說,app_timer只能計(jì)時(shí)毫秒的倍數(shù),如果你的計(jì)時(shí)精度小于1ms,請使用傳統(tǒng)timer1/2/3/4來做。
app_timer計(jì)時(shí)不是很準(zhǔn)確。app_timer庫可以創(chuàng)建幾十甚至上百個(gè)app timer,每次start或者stop這些timer,都會(huì)對其他timer計(jì)時(shí)精度產(chǎn)生一些影響。而且app_timer的中斷優(yōu)先級(jí)也不高,所以timeout handler經(jīng)常會(huì)被推遲執(zhí)行。
啟動(dòng)或者停止app_timer都是異步的,也就是說,當(dāng)調(diào)用app_timer_start或者app_timer_stop時(shí),系統(tǒng)只是把start或者stop操作入隊(duì),然后觸發(fā)一個(gè)軟中斷,如果此時(shí)上下文環(huán)境的中斷優(yōu)先級(jí)高于軟中斷,那么只有等退出了當(dāng)前上下文環(huán)境后才會(huì)真正去執(zhí)行軟中斷handler然后啟動(dòng)或者停止timer,這也是為什么app_timer模塊需要一個(gè)operation queue,并通過APP_TIMER_CONFIG_OP_QUEUE_SIZE來配置其大?。蝗绻藭r(shí)上下文環(huán)境的優(yōu)先級(jí)低于軟中斷,那么立即觸發(fā)軟中斷handler并啟動(dòng)或者停止timer。
用法說明
一般按照如下步驟使用app_timer:
修改app_timer默認(rèn)配置參數(shù),如下:

創(chuàng)建app_timer。創(chuàng)建app timer時(shí),先定義一個(gè)timer ID,用來表示這個(gè)timer,然后選擇app timer模式:single shot或者repeated。Single shot模式app timer只運(yùn)行一次,timeout后執(zhí)行timeout handler然后自動(dòng)停止app timer。Repeated模式app timer自動(dòng)循環(huán)執(zhí)行,每次timeout后執(zhí)行timeout handler,然后繼續(xù)計(jì)時(shí),直到下一個(gè)timeout然后再次執(zhí)行timeout handler,如此循環(huán)往復(fù)。創(chuàng)建app timer的時(shí)候,還需要定義timeout handler。
APP_TIMER_DEF(my_timer_id); //定義timer ID err_code = app_timer_create(&my_timer_id, APP_TIMER_MODE_REPEATED, my_timeout_handler) static void my_timeout_handler (void * p_context) { //add your code here }
啟動(dòng)app_timer或者停止app_timer。前面也提及過,啟動(dòng)或者停止timer是異步的,所以我們有一個(gè)operation queue來存放start或者stop操作。真正的start或者stop操作是通過軟中斷0來實(shí)現(xiàn)的。
err_code = app_timer_start(my_timer_id, APP_TIMER_TICKS(10), NULL); //啟動(dòng)timer并定時(shí)10ms err_code = app_timer_stop(my_timer_id);
常見使用問題
目前看到的常見使用問題有:
沒有按照使用說明來使用app_timer,比如定義app timer ID的時(shí)候不使用宏APP_TIMER_DEF,超時(shí)時(shí)間不使用宏APP_TIMER_TICKS來計(jì)算。
多次重復(fù)調(diào)用同一個(gè)app_timer_create。app_timer_create用于創(chuàng)建一個(gè)timer,多次調(diào)用同一個(gè)app_timer_create,會(huì)讓系統(tǒng)產(chǎn)生多個(gè)相同ID的app timer,以致于系統(tǒng)出現(xiàn)不可知的行為。
Stop沒有start的timer。當(dāng)一個(gè)timer沒有通過app_timer_start啟動(dòng)時(shí),使用app_timer_stop停止它時(shí),或者使用app_timer_stop停止一個(gè)不存在的timer時(shí),會(huì)打亂app timer的正常行為,產(chǎn)生不可預(yù)測的結(jié)果。
Operation queue溢出。這個(gè)需要具體問題具體分析,有時(shí)候operation queue溢出不一定是因?yàn)閝ueue size設(shè)置太小導(dǎo)致的,而是系統(tǒng)某個(gè)地方,確切說某個(gè)中斷例程,執(zhí)行時(shí)間太久,導(dǎo)致start和stop操作積累太多,從而產(chǎn)生queue溢出,這個(gè)時(shí)候就必須找出這個(gè)中斷例程執(zhí)行時(shí)間太久的原因,才能從根本上解決這個(gè)問題。
沒有初始化app_scheduler,而直接使用app_timer的schedule模式。app_scheduler原理及使用說明見:https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.3.0%2Flib_scheduler.html&cp=5_1_3_38,概括來說,app_scheduler的作用就是把長長的中斷代碼從中斷函數(shù)轉(zhuǎn)到main線程中來執(zhí)行。
審核編輯 黃宇
-
SDK
+關(guān)注
關(guān)注
3文章
1093瀏覽量
51146 -
Nordic
+關(guān)注
關(guān)注
9文章
238瀏覽量
48732
發(fā)布評論請先 登錄
深度技術(shù)解析nRF Connect SDK裸機(jī)選項(xiàng)方案
使用nRF52840芯片的USB Host 功能參考例程
深度技術(shù)解析低功耗藍(lán)牙廠商nordic的nRF Connect SDK裸機(jī)選項(xiàng)方案
nRF Connect SDK Basic
Nordic nRF5 SDK和softdevice介紹
如何調(diào)試nRF5 SDK
nRF5 SDK軟件架構(gòu)及softdevice工作原理
Nordic nRF51/nRF52開發(fā)流程說明
Flash訪問模塊FDS用法及常見問題—nRF5 SDK模塊系列一
nRF Connect SDK(NCS)/Zephyr固件升級(jí)詳解 – 重點(diǎn)講述MCUboot和藍(lán)牙空中升級(jí)
如何調(diào)試nRF5 SDK
deepin 25系統(tǒng)安裝常見問題
STM32定時(shí)器基本原理及常見問題之培訓(xùn)資料
關(guān)于功率模塊冷卻的六個(gè)常見問題

定時(shí)模塊app_timer用法及常見問題—nRF5 SDK模塊系列二
評論