天天看點

uORB筆記整理

其實是對自己看過的文章中講uORB的部分進行了記錄。

uORB(Micro Object Request Broker,微對象請求代理器)是PX4/Pixhawk系統中非常重要且關鍵的一個子產品,它肩負了整個系統的資料傳輸任務,所有的傳感器資料、GPS、PPM信号等都要從晶片擷取後通過uORB進行傳輸到各個子產品進行計算處理。實際上uORB是一套跨「程序」的IPC通訊子產品。在Pixhawk中,所有的功能被獨立以程序子產品為機關進行實作并工作。而程序間的資料互動就由為重要,必須要能夠符合實時、有序的特點。

uORB對于NuttX而言,它僅僅是一個普通的檔案裝置對象,這個裝置支援Open、Close、Read、Write、Ioctl以及Poll機制。通過這些接口的實作,uORB提供了一套“點對多”的跨程序廣播通訊機制,“點”指的是通訊消息的“源”,“多”指的是一個源可以有多個使用者來接收、處理。而“源”與“使用者”的關系在于,源不需要去考慮使用者是否可以收到某條被廣播的消息或什麼時候收到這條消息。它隻需要單純的把要廣播的資料推送到uORB的消息“總線”上。對于使用者而言,源推送了多少次的消息也不重要,重要的是取回最新的這條消息。

uORB實際上是多個程序打開同一個裝置檔案,程序間通過此檔案節點進行資料互動和共享。

(Rhine的猜測:以擷取傳感器資料為例,裝置檔案本身不儲存資料,但是寫有擷取的何種傳感器資料的說明,釋出傳感器資料的程序,如“傳感器運作程序”,會把傳感器資料的說明寫入配置檔案,而擷取傳感器資料的程序,如px4_simple_app,會打開讀取這個配置檔案了解到能擷取的傳感器資料的相關資訊,并不是資料本身)

Pixhawk使用的是NuttX實時ARM系統,uORB實際上是多個程序打開同一個裝置檔案,程序間通過此檔案節點進行資料互動和共享。程序通過命名的「總線」交換的消息稱之為「主題」(topic),在Pixhawk 中,一個主題僅包含一種消息類型,通俗點就是資料類型。每個程序可以「訂閱」或者「釋出」主題,可以存在多個釋出者,或者一個程序可以訂閱多個主題,但是一條總線上始終隻有一條消息。

釋出與訂閱的過程

0、int poll(structpollfd fds[], nfds_t nfds, int timeout)

功能:監控檔案描述符(多個);

說明:timemout=0,poll()函數立即傳回而不阻塞;timeout=INFTIM(-1),poll()會一直阻塞下去,直到檢測到return> 0;

poll()函數用于監測多個等待事件,若事件未發生,程序睡眠,放棄CPU控制權。若監測的任何一個事件發生,poll函數将喚醒睡眠的程序,并判斷是什麼等待事件發生,并執行相應的操作。poll( )函數退出後,struct polldf變量的所有值被清零,需要重新設定。

Publisher:

1、orb_advert_torb_advertise(const struct orb_metadata *meta, const void *data)

功能:公告釋出者的主題;

orb_advertise 其實就是一個int,  meta是一個已定義好的源描述資訊,裡面就2個成員,分别為name以及size。儲存了通訊的名稱以及每次發送資料的長度。 建立源的過程為3個步驟, 打開uORB的裝置節點, 擷取裝置執行個體, 推送第一條消息。

公告也可以釋出初始化資料到主題,meta參數是傳遞給API的一個指針,指向由ORB_DEFINE()宏定義好的資料,通常使用ORB_ID()宏來根據主題名稱擷取該指針。請注意,雖然主題更新可以從中斷處理函數釋出,公告主題必須在正常的線程上下文中執行。

5、intorb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void*data)

功能:釋出新資料到主題;

Subscriber:

2、intorb_subscribe(const struct orb_metadata *meta)

功能:訂閱主題(topic);

4、int orb_copy(conststruct orb_metadata *meta, int handle, void *buffer)

功能:從訂閱的主題中擷取資料并将資料儲存到buffer中;

3、int orb_check(int handle,bool *updated)

功能:訂閱者可以用來檢查一個主題在釋出者上一次更新資料後,有沒有訂閱者調用過ob_copy來接收、處理過;

說明:如果主題在在被公告前就有人訂閱,那麼這個API将傳回“not-updated”直到主題被公告。可以不用poll,隻用這個函數實作資料的擷取。

注意:

1、對應uORB的話題釋出者,兩件事:公告(advertise)、釋出(publish);對于話題接收者,三件事:訂閱(subscribe)、查詢(poll阻塞式等待或check更新)、複制(copy)。

2、必須有了orb_advertise( )函數和orb_subscribe()函數(通過它們可以擷取orb_copy( )函數中的參數handle句柄)之後才可以使用orb_copy( )函數來擷取訂閱的主題資料。

3、源碼中常用的調用順序為:orb_subscribe( ) - > orb_check( ) -> orb_copy( )

繼續閱讀