關于內存,要講的東西有點多,還是分篇聊吧,這一篇筆記說是講事件,其實是想借著事件來講一下內存管理,正好事件這塊也用到了內存管理,所以就一塊講了吧,水平有限,講到哪里算哪里吧,講不到的地方就靠你們了。站在應用的角度上來講,開發一款軟件,當你的構架定型的時候,狀態機也就基本定型了,能控制事件的數量和大小,那就取決于你對狀態機的應用能力了。但是有一點無論你的事件控制的多小,他總歸會占很大一部分比重,因為整個應用所有的交互全靠事件來驅動。
假如你用傳統的方式定義了所有的事件,所謂傳統的方式就是靜態的定義,你要問啥是靜態的定義,那么這么講,你這么問就證明你現在用的方式都是靜態的,那么后面的內容都不用講了,直接下課了,因為靜態定義的變量(單片機中常這么稱呼),從出生開始就不會凋零,也就是不會GAMEOVER,那你還談什么生命周期,內存回收。內存管理?沒有內存管理了(那還聊什么,友誼的小船說翻就翻,掀桌子...)。
傳統的靜態的定義事件,也并不是一無是處,例如,穩定,不會產生系統潛在的風險,申請不到,提前回收等等問題,說白了,就是用起來簡單,不用想那么多復雜的場景,但是有個最大的缺點就是消耗內存,當然這個問題嵌入式領域,完全可以通過升級內存來解決,這也意味著成本的上升,那全部定義成動態事件?也會存在很多問題,首先他無形的提高了對編程者的水平要求,各種漏洞總是五花八門,合理的分配靜態和動態事件所占的比例,用有限的資源實現整個應用,才是我們真正的追求。那什么樣子的事件適合被定義為靜態事件.
這里總結了一下,給大家兩個建議:
1. 這個事件從定義開始,就不會發生任何變化,也就是事件的參數不會發生改變。
2. 這個事件總是被頻繁的使用,貫穿整個應用,例如由QF_tick產生的周期事件。
為了增加應用的靈活性,掌握動態事件的使用時關鍵,下面聊得都是以動態事件為基礎的內存方案。
接下來我們來聊聊,關于事件是如何在QF中傳遞的,我們知道事件要被發送到相應的事件隊列,那么真正傳遞到事件隊列的是什么?其實是有兩種方案,第一種是值傳遞,這種情況,你要傳遞一個事件,你就需要把整個事件復制出一個復制品,并放進事件隊列中,實際情況比這還要復雜,這只是將事件傳遞到事件隊列,還有事件循環要從事件隊列取出事件,給到狀態機,這中間是否有牽扯一次的事件復制,在很多RTOS中都是采用這種值傳遞,他的好處是用內存開銷來換取確定性,其存取模型如圖:
還有一種事件的派發機制,叫做零事件派發機制,實際就是應用指針傳遞,這種方式不太適合傳統的RTOS這里記住就好了,展開講就太細節了,但是這種方式非常適合QF框架,因為他是明顯的控制倒置的類型,框架對于維護事件的指針還是合適的,因為框架可以從頭到尾的跟蹤整個事件指針的來龍去脈,不會再RTC中過多的停留。其存取模型如圖:
從圖中可以看到動態事件全部被指向事件池,也就是在傳遞過程中傳遞的是指針。還有一個點需要關注一下,就是一個動態事件的生命周期中所有權的問題,直接看圖吧,大概理解一下圖:
關于內存管理再講篇幅就有點長了,還是分開聊,看下篇吧 。