標籤:include 回調 .com 使用者 eve iba 實現原理 start api
本文為轉載,原文地址:78852247
Yloop概要
Yloop是AliOS Things的非同步事件架構。Yloop借鑒了,libuv及嵌入式業界常見的event loop,綜合考慮使用複雜性,效能,及footprint,實現了一個適合於MCU的事件調度機制。
Yloop上下文
每個Yloop執行個體(aos_loop_t)與特定的任務上下文綁定,AliOS Things的程式入口application_start所在的上下文與系統的主Yloop執行個體綁定,該上下文也稱為主任務。主任務以外的任務也可以建立自己的Yloop執行個體。
Yloop調度
Yloop實現了對IO,timer,callback,event的統一調度管理:
- IO:最常見的是Socket,也可以是AliOS Things的vfs管理的裝置
- timer:即常見的定時器
- callback:特定的執行函數
- event:包括系統事件,使用者自訂事件
當調用aos_loop_run後,當前任務將會等待上述的各類事件發生。
Yloop實現原理
Yloop利用協議棧的select介面實現了對IO及timer的調度。AliOS Things內建的協議棧又暴露一個特殊的eventfd介面,Yloop利用此介面把VFS的裝置檔案,和eventfd關聯起來,實現了對整個系統的事件的統一調度。
Yloop的使用從hello world開始
hello world example
裡面有這樣一段代碼:
application_start裡面做了兩件事情:
- 調用aos_post_delayed_action建立了一個1秒的定時器(Yloop裡面只有oneshot timer)
- 調用aos_loop_run進入事件迴圈
1秒後,定時器觸發,app_delayed_action被調用,而app_delayed_action裡面
- 調用LOG列印
- 再次建立一個5秒的定時器,重而實現定期執行app_delayed_action
這裡注意到,程式並不需要aos_loop_init()去建立Yloop執行個體,因為系統會預設自動建立主Yloop執行個體。
和Socket的結合
以mqtt的framework/connectivity/mqtt/mqtt_client.c作為例子:
在和服務端建立好socket串連後,調用aos_poll_read_fd()把mqtt的socket加入到Yloop的監聽對象裡。當服務端有資料過來時,cb_recv回調將被調用,進行資料的處理。這樣,mqtt就不需要一個單獨的任務來處理socket,從而節省記憶體使用量。同時,由於所有處理都是在主任務進行,不需要複雜的互斥操作。
系統事件的處理
AliOS Things定義了一系列系統事件,程式可以通過aos_register_event_filter()註冊事件監聽函數,進行相應的處理,比如WiFi事件。
#define EV_USER 0x1000
EV_USER以後的事件ID可以用於使用者自訂的事件。
Yloop回調
Yloop回調用於跨任務的處理。以下面虛擬碼為例:
假設uart_recv_data_cb是IO裝置收到資料時的回調,收到資料後通過aos_schedule_call把實際處理do_uart_io_in_main_task放到主任務上下文去執行。這樣,資料的邏輯處理do_uart_io_in_main_task就不需要考慮並發,而去做複雜的互斥操作。
注意事項
Yloop的API(include/aos/yloop.h)除了下述API,都必須在Yloop執行個體所綁定的任務的上下文執行:
- aos_schedule_call
- aos_loop_schedule_call
- aos_loop_schedule_work
- aos_cancel_work
- aos_post_event
小結
Yloop作為AliOS Things的事件架構,和VFS,協議棧深度結合,在取得較好的footprint的同時,能較好地適應於對footprint要求較高只有一個主任務的系統,也可以適用於對處理的並發性要求較高的系統。
AliOS Things 非同步事件架構Yloop