CSR uEnergy timer使用時容易犯的一個隱蔽錯誤
在CSR uEnergy的開發過程中,難以避免地會用到timer,在使用過程中,有這麼一個情況,很容易造成程序運行的不正常,而這種不正常,常常很容易讓開發者費解。
我們來看以下例子:
A定義一個timer id
timer_id tId;
B開啟一個timer
Start_tId ()
{
If(tId!=TIMER_INVALID)
{
TimerDelete(tId);
tId=TIMER_INVALID;
}
tId = TimerCreate((1* SECOND), TRUE, timerCallBack);
}
C定義回調函數
static void timerCallBack(timer_id const id)
{
if(id == tId)
{
…….
}
}
D刪除函數
Void timerDelete()
{
If(tId!=TIMER_INVALID)
{
TimerDelete(tId);
tId=TIMER_INVALID;
}
}
一般的用法是B=>C,或者是B=>D。單獨從這個timer的使用情況來看,似乎也沒啥問題。
但是,如果有第二個timer存在的話,就不一樣了。
如我們再定義一個tId2:
timer_id tId2;
接下去開啟timer1:
Start_tId 1();
這個時候,我們假設底層把0x8001賦給了tId。
在以上代碼執行後2秒後,再開啟另一個timer:
Start_tId 2();
這個時候,由於一秒已過,tId已經溢出,所以底層0x8001的timer已經釋放,所以,給tId2的timer id依舊是0x8001。
然後0.5秒後再開啟tId:
Start_tId1();
這個時候,問題就來了,由於在timerCallBack裡面tId沒有被清零(TIMER_INVALID),故在Start tId1函數裡面,會調用delete清除之前賦予的0x8001,這樣,tId2就被意外清除了。timerCallBack2自然就不會被調用,程序就出現異常了。
如果這個timer2是系統裡面重要的timer,那麼,整個程序就崩潰了。
解決這個問題的辦法,就是在callback函數中,先將timer id清零:
tId=TIMER_INVALID;
進入callback函數就執行這一句,這樣就能有效避免此問題。這樣的錯誤在初學者中出現的比較多,而現象往往是莫名其妙的,可能是藍牙功能不正常了,也有可能整個系統就崩潰了。因為,timer在SDK中被廣泛應用,特別是在Mesh中,Mesh底層的timer許可權也沒比用戶層高,所以更容易造成莫名其妙的問題。


TAG:藍牙 |