天天看點

AliOS Things異步事件架構Yloop

每個Yloop執行個體(aos_loop_t)與特定的任務上下文綁定,AliOS Things的程式入口application_start所在的上下文與系統的主Yloop執行個體綁定,該上下文也稱為主任務。主任務以外的任務也可以建立自己的Yloop執行個體。

Yloop實作了對IO,timer,callback,event的統一排程管理:

IO:最常見的是Socket,也可以是AliOS Things的vfs管理的裝置

timer:即常見的定時器

callback:特定的執行函數

event:包括系統事件,使用者自定義事件

當調用aos_loop_run後,目前任務将會等待上述的各類事件發生。

Yloop利用協定棧的select接口實作了對IO及timer的排程。AliOS Things自帶的協定棧又暴露一個特殊的eventfd接口,Yloop利用此接口把VFS的裝置檔案,和eventfd關聯起來,實作了對整個系統的事件的統一排程。

<a href="https://github.com/alibaba/AliOS-Things/blob/master/example/helloworld/helloworld.c">hello world example</a>

裡面有這樣一段代碼:

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連接配接後,調用aos_poll_read_fd()把mqtt的socket加入到Yloop的監聽對象裡。當服務端有資料過來時,cb_recv回調将被調用,進行資料的處理。這樣,mqtt就不需要一個單獨的任務來處理socket,進而節省記憶體使用。同時,由于所有處理都是在主任務進行,不需要複雜的互斥操作。

AliOS Things定義了一系列系統事件,程式可以通過aos_register_event_filter()注冊事件監聽函數,進行相應的處理,比如WiFi事件。

<code>#define EV_USER 0x1000</code>

EV_USER以後的事件ID可以用于使用者自定義的事件。

Yloop回調用于跨任務的處理。以下面僞代碼為例:

假設uart_recv_data_cb是IO裝置收到資料時的回調,收到資料後通過aos_schedule_call把實際處理do_uart_io_in_main_task放到主任務上下文去執行。這樣,資料的邏輯處理do_uart_io_in_main_task就不需要考慮并發,而去做複雜的互斥操作。

aos_schedule_call

aos_loop_schedule_call

aos_loop_schedule_work

aos_cancel_work

aos_post_event

Yloop作為AliOS Things的事件架構,和VFS,協定棧深度結合,在取得較好的footprint的同時,能較好地适應于對footprint要求較高隻有一個主任務的系統,也可以适用于對處理的并發性要求較高的系統。

繼續閱讀