pixhawk自学笔记之uorb学习总结
注:這是看過(guò)好多文章總結(jié)出來(lái)的,轉(zhuǎn)載了較多人的博客,希望有知道原出處的人把地址留下,我貼上來(lái)。在此謝謝各位前輩的總結(jié)。(我會(huì)在后續(xù)筆記中貼出在我自己的程序中對(duì)于uorb的使用)
進(jìn)程與應(yīng)用程序(傳感器應(yīng)用程序發(fā)送傳感器數(shù)據(jù)到姿態(tài)過(guò)濾應(yīng)用程序)之間的通訊是pixhawk軟件架構(gòu)的重要組成部分,進(jìn)程(即所謂的節(jié)點(diǎn))通過(guò)命名的總線交換消息稱之為“主題”,在pixhawk中,一個(gè)主題僅包含一種消息類型,例如:vehicle_attitude主題傳輸包含姿態(tài)結(jié)構(gòu)(翻滾,俯仰和偏航估算)。節(jié)點(diǎn)可以在總線,主題上發(fā)布一跳消息或者訂閱總線,主題。通訊雙方之間并不知道在與誰(shuí)通訊,可以存在多個(gè)發(fā)布或一條消息有多個(gè)訂閱者。這種設(shè)計(jì)模式可以防止鎖定的問(wèn)題。
pixhawk的發(fā)布訂閱機(jī)制是通過(guò)“微對(duì)象請(qǐng)求代理”(uORB)來(lái)實(shí)現(xiàn)的。
快速入門:
在深入細(xì)節(jié)之前,以下是一對(duì)簡(jiǎn)單,完整的發(fā)布/訂閱模型。發(fā)布者發(fā)布一條名為“random——integer”的主題并用隨機(jī)整數(shù)更新該主題。訂閱者檢查并打印這些更新。
發(fā)布:
? ? 發(fā)布分為三個(gè)獨(dú)立但又相關(guān)的行為;確定主題,公告主題和發(fā)布主題更新。
?
確定主題:
? ? pixhawk系統(tǒng)為提供部件之前的通用接口定義了許多標(biāo)準(zhǔn)主題,如果發(fā)布者想使用標(biāo)準(zhǔn)主題和相關(guān)的數(shù)據(jù)結(jié)構(gòu)不需要做額外的工作。
?
自定義主題
? ? 要定義一個(gè)自定義主題,發(fā)布者需要提供給訂閱者一個(gè)頭文件(參考上面的topic.h),在這個(gè)頭文件中必須有:
? ??? ? 1.用主題的名稱做作為參數(shù)調(diào)用ORB_DECLARE()宏來(lái)定義一個(gè)實(shí)例
? ??? ? 2.定義一個(gè)結(jié)構(gòu)體,用來(lái)描述將要用來(lái)發(fā)布的數(shù)據(jù)結(jié)構(gòu)
主題的名稱應(yīng)該要具有描述性,pixhawk的管理使用下劃線來(lái)分割主題名稱為獨(dú)立的部分并且首選更通用的術(shù)語(yǔ)表示元件的名稱。
? ? 例如:raw sensor data發(fā)布在sensors_raw主題
?
除了頭文件,發(fā)布者必須要具有使用ORB_DEFINE()宏在源碼中定義一個(gè)實(shí)例,當(dāng)固件被構(gòu)建時(shí),他將被編譯并且鏈接到固件。
可選主題:
? ??? ? 如果一個(gè)主題通過(guò)一個(gè)軟件組件來(lái)發(fā)布,那么它屬于可選主題,并且可能不會(huì)存在于發(fā)布后的固件,這種情況下,頭文件也可以改用ORB_DECLARE_OPTIONAL()宏來(lái)替代,以這種方式聲明主題,發(fā)布者不需要專門來(lái)處理什么。但在下面討論的也有額外要處理的情況,當(dāng)處理可選主題時(shí)訂閱者必須要注意。
?
公告主題:
? ??? ? 在數(shù)據(jù)被發(fā)布到一個(gè)主題前,它必須被公告,發(fā)布者可以使用下面的API來(lái)公告一個(gè)新的主題。
[cpp] view plain copy print?? ? 公告也可以發(fā)布初始化數(shù)據(jù)到主題,meta參數(shù)是傳遞給API的一個(gè)指針,指向由ORB_DEFINE()宏定義好的數(shù)據(jù),通常使用ORB_ID()宏來(lái)根據(jù)主題名稱獲取該指針。請(qǐng)注意,雖然主題更新可以從中斷處理函數(shù)發(fā)布,公告主題必須在常規(guī)的線程上下文中執(zhí)行。
多個(gè)發(fā)布:
? ??? ? 只有一個(gè)發(fā)布者可以具有發(fā)布一次一個(gè)主題,但是該主題手柄可以被關(guān)閉,因?yàn)槭俏募枋龇?#xff0c;可以通過(guò)close()函數(shù)關(guān)閉。?
發(fā)布更新:
? ??? ? 一旦公告了一個(gè)主題,公告主題后返回的句柄可使用下面的API來(lái)發(fā)布主題更新。
[cpp] view plain copy print?
訂閱者:
? ??? ? 訂閱主題的要求如下:
? ??? ??? ??? ? 1.調(diào)用ORB_DEFINE()或ORB_DEFINE_OPTIONAL()宏(在訂閱者的頭文件中包含他們)
? ??? ??? ??? ? 2.發(fā)布到主題的數(shù)據(jù)結(jié)構(gòu)定義(通常與發(fā)布者使用同一頭文件)
? ??? ? 如果滿足上面的條件后,訂閱者可以使用下面的api來(lái)訂閱一個(gè)主題:
[cpp] view plain copy print?
?如果可選主題不存在于固件之中,訂閱到可選的主題將會(huì)失敗,但其他主題即便發(fā)布者沒(méi)有進(jìn)行公告也會(huì)訂閱成功,這樣可大大降低系統(tǒng)對(duì)啟動(dòng)順序的安排。
? ??? ? 這里沒(méi)有專門來(lái)限制一個(gè)任務(wù)的最大訂閱數(shù)。
? ??? ? 要取消訂閱一個(gè)主題,可以用下面的API:
[cpp] view plain copy print?
拷貝數(shù)據(jù)到主題:
? ??? ? 訂閱者不能引用ORB中存儲(chǔ)的數(shù)據(jù)或其他訂閱共享的數(shù)據(jù),而是在訂閱者請(qǐng)求時(shí)從ORB拷貝數(shù)據(jù)到訂閱者的臨時(shí)緩沖區(qū)。副本拷貝的方式可以避免鎖定ORB的問(wèn)題,并保持兩者之間(發(fā)布者,訂閱者)的API接口簡(jiǎn)單。它也允許訂閱者在必要的時(shí)候直接修改拷貝副本的數(shù)據(jù)供自己使用。
? ??? ? 當(dāng)訂閱者想要把主題中的最新數(shù)據(jù)拷貝一份全新的副本,可以使用:
[cpp] view plain copy print?
?拷貝是以原子操作進(jìn)行的,所以可以保證獲取到發(fā)布者最新的數(shù)據(jù)。
檢查更新:
? ??? ? 訂閱者可以使用下面的API來(lái)檢查一個(gè)主題在發(fā)布者最后更新后,有沒(méi)有人調(diào)用過(guò)orb_copy來(lái)接收,處理:
[cpp] view plain copy print?
? ?如果主題在被公告前就有人訂閱,那么這個(gè)API將返回“not-updated”直到主題被公告。
發(fā)布時(shí)間戳:
? ??? ? 訂閱者可以使用下面的API來(lái)檢查一個(gè)主題最后發(fā)布的時(shí)間。
[cpp] view plain copy print?需要注意的是,要小心的使用這個(gè)調(diào)用,因?yàn)椴荒鼙WC再調(diào)用返回后不久主題就不會(huì)被發(fā)布(調(diào)用返回后不久,主題可能馬上又被發(fā)布,導(dǎo)致最后更新時(shí)間錯(cuò)誤)
uORB的管理羅輯是通過(guò)創(chuàng)建線程后臺(tái)運(yùn)行方式實(shí)現(xiàn)。
uORB深入探索
? ??? ? uORB是pixhawk系統(tǒng)中非常重要的一個(gè)模塊,它肩負(fù)了整個(gè)系統(tǒng)的數(shù)據(jù)傳輸任務(wù),所有的傳感器數(shù)據(jù),GPS,ppm信號(hào)等都要從芯片獲取后通過(guò)uORB進(jìn)行傳輸?shù)礁鱾€(gè)模塊進(jìn)行計(jì)算處理。
? ??? ? 1.uORB的架構(gòu)簡(jiǎn)述:
? ??? ???uORB是一套跨進(jìn)程的IPC通訊模塊。在pixhawk中,所有的功能被獨(dú)立以進(jìn)程模塊為單位進(jìn)行實(shí)現(xiàn)并工作。而進(jìn)城間的數(shù)據(jù)交互尤為重要,必須要能夠符號(hào)實(shí)時(shí),有序的特點(diǎn)。
? ??? ? pixhawk使用nuttx實(shí)時(shí)ARM系統(tǒng),而uORB對(duì)于nuttx而言,它僅僅是一個(gè)普通的文件設(shè)備對(duì)象,這個(gè)設(shè)備支持open,close,read,write,ioctl以及poll機(jī)制。通過(guò)這些接口的實(shí)現(xiàn),uORB提供了一套“點(diǎn)對(duì)多”的跨進(jìn)程廣播通訊機(jī)制。“點(diǎn)”指的是通訊消息的“源”,“多”指的是一個(gè)源可以有多個(gè)用戶來(lái)接受,處理。而源和用戶的關(guān)系在于,源不需要去考慮用戶是否課余i收到某條被廣播的消息或什么時(shí)候收到這條消息。它只是需要單純的把要廣播的數(shù)據(jù)推送到uORB的消息總線上,對(duì)于用戶而言,源推送了多少次的小心也不重要,重要的是取回最新的這條消息。
?
? ??? ? 2.uORB的實(shí)現(xiàn)位于固件源碼的src/modules/uORB/uORB.cpp文件,它通過(guò)重載CDev基類來(lái)組織一個(gè)uORB的設(shè)備實(shí)例。并且完成Read/Write等功能的重載。uORB的入口點(diǎn)是uorb_main函數(shù),在這里它檢查uORB的啟動(dòng)參數(shù)來(lái)完成對(duì)應(yīng)的功能,uORB支持start/test/status這3條啟動(dòng)參數(shù),在pixhawk的rcS啟動(dòng)腳本中,使用start參數(shù)來(lái)進(jìn)行初始化,其他2個(gè)參數(shù)分別用來(lái)進(jìn)行uORB功能的自檢和列出uORB的當(dāng)前狀態(tài)。
? ??? ? 在rcS中使用start參數(shù)啟動(dòng)后,uORB會(huì)創(chuàng)建并初始化它的設(shè)備實(shí)例,其中的實(shí)現(xiàn)大部分都在CDev基類完成。這個(gè)過(guò)程類似于Linux設(shè)備驅(qū)動(dòng)中的Probe函數(shù),通過(guò)init調(diào)用完成設(shè)備的創(chuàng)建,節(jié)點(diǎn)注冊(cè)以及派遣例程的設(shè)置等。
?
? ??? ? 源碼解讀:(最新版本的uORB)
? ??? ? uORB文件夾說(shuō)明
? ??? ? 1.uORB文件夾結(jié)構(gòu)
2.文件/目錄說(shuō)明
? ??? ??? ? objects_common.cpp:通用接口標(biāo)準(zhǔn)主題定義集合,如添加新主題就在這里定義。
? ??? ??? ? uORBMap.hpp:對(duì)象請(qǐng)求節(jié)點(diǎn)鏈表管理(驅(qū)動(dòng)節(jié)點(diǎn))
? ??? ??? ? uORBSet.hpp:對(duì)象請(qǐng)求節(jié)點(diǎn)鏈表管理(非驅(qū)動(dòng)節(jié)點(diǎn))
? ??? ??? ?Publication.cpp/?Publication.hpp:在不同的發(fā)布中遍歷使用
? ??? ??? ?Subscription.cpp/?Subscription.hpp:在不同的發(fā)布中遍歷使用
? ??? ??? ? uORB.cpp:uORB的實(shí)現(xiàn)
? ??? ??? ? uORB.h:uORB的頭文件
? ??? ??? ? uORBCommon.hpp:uORB公共部分變量定義實(shí)現(xiàn)
? ??? ??? ? uORBCommunicator.hpp:遠(yuǎn)程訂閱的接口實(shí)現(xiàn),實(shí)現(xiàn)了對(duì)不同的通信通道管理,如添加、移除訂閱者,可以基于TCP/IP或者fastRPC;傳遞給通信鏈路的實(shí)現(xiàn),以提供在信道上接收信息的回調(diào)。
? ??? ??? ? uORBDevices_nuttx.cpp:節(jié)點(diǎn)操作,close,open,read,write等
? ??? ??? ? uORbMain.cpp:uORB入口
? ??? ??? ? uORBManager.hpp:uORB功能函數(shù)實(shí)現(xiàn)的頭文件
? ??? ??????uORBManager_nuttx.cpp:uORB功能函數(shù)的實(shí)現(xiàn)(Nuttx)
? ??? ??? ?uORBManager_posix.cpp:uORB功能函數(shù)的實(shí)現(xiàn)(Posix)
? ??? ??? ?uORBTest_UnitTest.cpp:uORB測(cè)試
? ??? ??? ??uORBTest_UnitTest.hpp:uORB測(cè)試頭文件,包括主題定義和聲明等
總結(jié)
以上是生活随笔為你收集整理的pixhawk自学笔记之uorb学习总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: MAX232和PL2303、CH340的
- 下一篇: poll()函数详解