本文通過分析contiki的原始碼,梳理contiki的process-event模型中的event機制。
通過前文的闡述我們知道,contiki是基於事件驅動的,有process-event模型和5大定時器機制。本文開始梳理process-event模型中的event處理機制。下篇文章繼續梳理process-event模型中的event產生機制。
contiki的核心執行函式是process_run()。我們由此開始contiki的剖析之旅。
開啟process_run函式的定義
int
process_run
(void
)/* process one event from the queue */
do_event()
;return nevents + poll_requested;
}
poll_requested是poll1請求標誌,當它置位時,系統執行一次poll。每次poll會把有poll請求的process拿出來,執行process對應的函式。而event的執行是無條件的,它會取出乙個事件,並執行事件繫結的process。nevents是剩餘的event計數。poll_requested標誌是否有poll請求,故本函式返回非0值代表系統尚有任務需處理。返回0則代表系統空閒,可以進入低功耗模式或者空閒模式。
我們深入一步,剖析do_poll和do_event。
static
void
do_poll
(void)}
}
可以發現do_poll真的只是輪詢了整個process鍊錶,設定了process的狀態和引數,然後呼叫了有poll請求的process。
static
void
do_event
(void
)call_process
(p, ev, dataa);}
}else
/* make sure that the process actually is running. */
call_process
(receiver, ev, dataa);}
}}
可以看到do_event做的事情就是取了乙個process執行需要的引數:事件繫結的process–>receiver,發生的具體事件ev ,事件要給process傳遞的資料dataa 。然後對事件型別特殊判斷。分為廣播事件和初始化事件。如果是廣播事件,則把取到的引數傳遞給所有註冊在process鍊錶的process。如果是初始化事件,則要設定該process的狀態為process_state_running(執行態,其具體機制之後再說)。注意contiki實現的事件機制實際上是用乙個事件陣列儲存的,用環形佇列的邏輯結構實現的,所以會有佇列空滿的判定,陣列預設大小是32。
可以看到無論是do_event還是do_poll,最終都會呼叫call_process,而它正是真正去執行乙個process的函式,我們繼續剖析call_process。
static
void
call_process
(struct process *p, process_event_t ev, process_data_t dataa)
else
}}
通過上面函式的**和我新增的註冊,基本上可以看出call_process做的工作了。可以看到在執行process繫結的函式時,先做了鎖機制,即把即將要執行的process的state設定為process_state_called狀態。該狀態代表了process正在執行,不可重複執行。在process執行結束,修改state為process_state_running狀態,即釋放了鎖。相當於標明process處於就緒狀態。其中p->thread(&p->pt, ev, dataa)就是我們process繫結的函式,即我們自己實現業務**的函式。
分析到這裡,我們搞清楚了產生poll和event後,contiki怎麼從process_run執行到我們自己的業務函式。但是擺在眼前的問題是,contiki是如何產生poll和event的?我們在下篇文章繼續分析。
參考poll可以籠統的視為一種特殊的事件機制
Gridview,Formview的事件驅動
最近發現一件怪事 執行formview的insert的時候,girdview自動重新整理了一次。奇怪啊。我沒有寫這個重新繫結的方法啊 name id birthday name birthday name id birthday 新增 用 10仔細分析了一下事件的執行順序。問題 為什麼以前的用gv的...
linux核心的裝置驅動模型和平台裝置驅動
為了解決這種驅動 和裝置資訊耦合的問題,linux 提出了裝置驅動模型。裝置驅動模型中包括匯流排,驅動,裝置。在裝置驅動模型中,引入匯流排的概念可以對驅動 和裝置資訊進行分離。對於i2c spi usb這類常見的物理匯流排來說,linux核心回自動建立與之對應的驅動匯流排,因此i2c裝置,spi裝置...
核心驅動上報EV LED事件失敗原因分析
之前在寫驅動時使用如下方式上報一次ev led型別事件,使用getevent命令測試卻一直接收不到事件。input event input dev,ev led,led misc,1 input sync input dev 因為趕工無法深究原因,只能先參考普通按鍵上報方式 在上報抬起 按下兩個事件...