0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

從接口定義和實現(xiàn)兩個方面,深入理解AWbus-lite

UtFs_Zlgmcu7890 ? 來源:互聯(lián)網(wǎng) ? 作者:佚名 ? 2018-07-23 09:08 ? 次閱讀

本文導讀

在使用AWBus-lite對設備進行管理時,無論設備處于 AWBus-lite拓撲結構中的哪個位置,只要其能夠提供某種標準服務,就可以使用相應的通用接口對其進行操作。本文將從接口的定義和實現(xiàn)兩個方面,深入理解AWbus-lite工作的原理。

本文為《面向AWorks框架和接口的編程(上)》第三部分軟件篇——第13章——第1~2小節(jié):通用接口的定義和接口的實現(xiàn)。

本章導讀

在基于AWBus-lite總線拓撲結構的設備管理框架中,無論一個設備處于AWBus-lite總線拓撲結構中的哪個位置,只要其能夠提供某種標準服務,就可以使用相應的通用接口對其進行訪問。那么,這究竟是怎樣實現(xiàn)的呢?本章將繼續(xù)深入探討AWBus-lite,為您揭開AWBus-lite的神秘面紗,使您對AWBus-lite有更加深入的了解,在具有這些足夠的了解后,你將有能力獨立開發(fā)一些設備的驅動,當后續(xù)遇到一些AWorks暫不支持的設備時,可以自行開發(fā)設備相應的驅動。

13.1 通用接口的定義

合理的接口應該是簡潔的、易閱讀的、職責明確的,為了便于維護,通用接口由廣州致遠電子有限公司進行統(tǒng)一的定義,用戶通常不需要自行定義通用接口。目前,常用的功能都已經(jīng)被標準化,定義了相應的通用接口。

作為一種了解,下面以LED為例,從接口的命名、參數(shù)和返回值三個方面闡述在AWorks中定義接口的一般方法。

13.1.1 接口命名

在AWorks中,所有通用接口均以“aw_”開頭,緊接著是操作對象的名字,對于LED控制接口來說,所有接口都應該以“aw_led_”作為前綴。

在接口的前綴定義好之后,應該考慮需要定義哪些功能性接口,然后根據(jù)功能完善接口名。對于LED來說,核心的操作是控制LED的狀態(tài),點亮或熄滅LED,為此,可以定義一個設置(set)LED狀態(tài)的函數(shù),比如:“aw_led_set”。

使用該接口可以設置LED的狀態(tài),顯然,為了區(qū)分是點亮還是熄滅LED,需要通過一個額外的參數(shù)來指定具體的操作。

每次開燈或關燈都需要傳遞額外的參數(shù)給aw_led_set()接口,顯得比較繁瑣。為了簡化操作,可以為常用的開燈和關燈操作定義專用的接口,這樣就不需要額外的參數(shù)來對開燈和關燈操作進行具體的區(qū)分了。比如,使用on和off分別表示開燈和關燈,則可以定義開燈的接口名為:“aw_led_on”,關燈的接口名為“aw_led_off”。

在一些特殊的應用場合中,比如,LED閃爍,用戶可能并不關心具體的操作是開燈還是關燈,它僅僅需要LED的狀態(tài)發(fā)生翻轉。此時,可以定義一個用于翻轉(toggle)LED狀態(tài)的專用接口,比如:“aw_led_toggle”

13.1.2 接口參數(shù)

在AWorks中,通用接口的第一個參數(shù)往往用于表示要操作的具體對象。顯然,在一個系統(tǒng)中,可能存在多個LED,為了區(qū)分各個LED,可以為每個LED分配一個唯一編號,即ID號。ID號是一個從0開始的整數(shù),例如,系統(tǒng)中有兩個LED,則編號分別為0、1?;诖?,為了指定要操作的具體LED,通用接口的第一個參數(shù)可以設定為int類型的id。

對于aw_led_set接口,其除了使用id確定需要控制的LED外,還需要使用一個參數(shù)來區(qū)分是點亮LED還是熄滅LED,這是一個二選一的操作,對應參數(shù)的類型可以使用布爾類型: aw_bool_t。當值為真(AW_TRUE)時,則點亮LED;當值為假(AW_FALSE)時,則熄滅LED。基于此,可以定義aw_led_set()接口的原型為(還未定義返回值):

對于aw_led_on、aw_led_off和aw_led_toggle接口來說,它們的職責單一,僅僅需要指定控制的LED,即可完成點亮、熄滅或翻轉操作,無需其它額外的參數(shù)。對于這類接口,參數(shù)僅僅需要id,這些接口的原型可以定義如下(還未定義返回值):

13.1.3 返回值

對于用戶來說,調用通用接口后,應該可以獲取到本次執(zhí)行的結果,是執(zhí)行成功還是執(zhí)行失敗,或是一些其它的有用信息。比如,在調用接口時,如果指定的id超過了有效范圍,由于沒有與無效id對應的LED設備,操作必定會失敗,此時必須返回通過返回值告知用戶操作失敗,且操作失敗的原因是id不在有效范圍內,無與之對應的LED設備。

在AWorks中,接口通常返回一個aw_err_t類型的返回值來表示接口執(zhí)行的結果,返回值的含義已被標準化:若返回值為AW_OK,則表示操作成功;若返回值為負數(shù),則表示操作失敗,此時,用戶可根據(jù)具體的返回值,查找aw_errno.h文件中定義的宏,根據(jù)宏的含義確定失敗的原因;若返回值為正數(shù),其含義與具體接口相關,由具體接口定義,無特殊說明則表示不會返回正數(shù)。AW_OK是在aw_common.h文件中定義的宏,其定義如下:

錯誤號在aw_errno.h文件中定義,幾個常見錯誤號的定義詳見表6.2。比如,在調用LED通用接口時,若id不在有效范圍內,則該id沒有對應的LED設備,此時接口應該返回-AW_ENODEV。注意:AW_ENODEV的前面有一個負號,以表示負值。

基于此,將所有LED通用接口的返回值類型定義為aw_err_t,LED控制接口的完整定義詳見表13.1,其對應的類圖詳見圖13.1。

表13.1 LED通用接口(aw_led.h)

圖13.1 LED接口類圖

這些接口都已經(jīng)在aw_led.h文件中完成了定義,無需用戶再自行定義。上述從接口命名、參數(shù)和返回值三個方面詳細闡述了一套接口定義的方法,旨在讓用戶了解接口的由來,加深對接口的理解。實際中,定義接口并不是一件容易的事情,需要盡可能考慮到所有的情況,接口作為與用戶交互的途徑,一旦定義完成,如非必要,都應該避免再對接口進行修改。否則,所有依賴于該接口的應用程序都將受到影響。因此,當前并不建議用戶自定義通用接口,通用接口的定義應由廣州致遠電子有限公司統(tǒng)一規(guī)劃、定義、維護和管理。

13.2 接口的實現(xiàn)

作為一種范例,下面以實現(xiàn)LED接口為例,詳細介紹AWorks中實現(xiàn)接口的一般方法。

13.2.1 實現(xiàn)接口初探

在AWorks中,硬件設備和驅動統(tǒng)一由AWBus-lite進行管理,因此,對于LED這一類硬件設備,其實現(xiàn)是屬于AWBus-lite的一部分。LED有4個通用接口函數(shù),其中的aw_led_on()和aw_led_off()接口可以直接基于aw_led_set()接口實現(xiàn),詳見程序清單13.1。

程序清單13.1 aw_led_on()和aw_led_off()接口的實現(xiàn)

實現(xiàn)接口的核心是實現(xiàn)aw_led_set()和aw_led_toggle()這兩個接口。對于不同的底層硬件設備,LED實際控制方式是不同的,比如,最常見的,通過GPIO直接控制一個LED,簡單范例詳見程序清單13.2。

程序清單13.2 aw_led_set()的實現(xiàn)(GPIO控制LED)

也有可能是通過串口控制一個LED設備。例如,通過發(fā)送字符串命令控制LED的狀態(tài),命令格式為:set ,其中,id為LED編號,on為設置LED的狀態(tài),要點亮LED0,則發(fā)送字符串:"set 0 1"。這種情況下,aw_led_set()的實現(xiàn)范例詳見程序清單13.3。

程序清單13.3 aw_led_set()的實現(xiàn)(UART控制LED)

總之,底層硬件設備是多種多樣的,不同類型的LED設備對應的控制方式也會不同。

定義通用接口的目的在于屏蔽底層硬件的差異性,即無論底層硬件如何變化,用戶都可以使用通用接口控制LED。顯然,如果直接類似程序清單13.2和程序清單13.3這樣實現(xiàn)一個通用接口,那么隨著LED設備種類的增加,同一個接口的實現(xiàn)代碼將有越來越多不同的版本。

在一個應用程序中,一個接口不能同時具有多種不同的實現(xiàn),因此,這樣的做法有著非常明顯的缺點:多個不同種類的LED設備不能在一個應用中共存,更換硬件設備,就必須更換通用接口的實現(xiàn),使用何種設備就加入相應設備的控制代碼進行編譯。 例如,系統(tǒng)中有幾個直接通過GPIO控制的LED,同時也存在幾個通過UART控制的LED,那么,類似程序清單13.2和程序清單13.3這樣直接實現(xiàn)通用接口的方法,就無法組織代碼了,因為不可能同時將程序清單13.2和程序清單13.3所示的代碼加入工程編譯。顯然,需要更好的辦法來解決這個問題。

13.2.2 LED抽象方法

在使用幾種控制方式不同的LED硬件設備時,雖然它們對應的aw_led_set()和aw_led_toggle()接口的具體實現(xiàn)方法并不相同,但它們要實現(xiàn)的功能卻是一樣的,這是它們的共性:均要實現(xiàn)設置LED狀態(tài)和翻轉LED狀態(tài)的功能。由于一個接口的實現(xiàn)代碼只能有一份,因此,這些功能的實現(xiàn)不能直接作為通用接口的實現(xiàn)代碼。為此,可以在通用接口和具體實現(xiàn)之間增加一個抽象層,以對共性進行抽象,將兩種功能的實現(xiàn)抽象為如下兩個方法:

相對于通用接口來說,抽象方法多了一個p_cookie參數(shù)。在面向對象的編程語言中(如C++),對象中的方法都能通過隱式指針p_this訪問對象自身,引用自身的一些私有數(shù)據(jù)。而在C語言中則需要顯式的聲明,這里的p_cookie就有類似的作用,當前設置為void *類型主要是由于具體對象的類型還并不確定。

為了節(jié)省內存空間,同時方便管理,可以將所有抽象方法放在一個結構體中,形成一張?zhí)摵瘮?shù)表,比如:

由于LED的實現(xiàn)屬于AWBus-lite的一部分,因此,命名使用"awbl_"作為前綴。這里定義了一個虛函數(shù)表,包含了兩個方法,分別用于設置LED的狀態(tài)和翻轉LED。針對不同的硬件設備,都可以根據(jù)自身特性實現(xiàn)這兩個方法。GPIO控制LED的偽代碼詳見程序清單13.4,UART控制LED的偽代碼詳見程序清單13.5。

程序清單13.4 抽象方法的實現(xiàn)(GPIO控制LED)

程序清單13.5 抽象方法的實現(xiàn)(UART控制LED)

顯然,__g_led_gpio_drv_funcs和__g_led_uart_drv_funcs分別是使用GPIO和UART控制LED的具體實現(xiàn),它們在形式上是兩個不同的結構體常量,在同一系統(tǒng)中是可以共存的。

13.2.3 抽象的LED服務

當對不同的LED硬件設備抽象了相同的pfn_led_set和pfn_led_toggle方法后,在通用接口aw_led_set()和aw_led_toggle()的實現(xiàn)中,就無需再處理與硬件相關的具體事務,只需要找到相應設備提供的相應方法,然后調用這些具體硬件設備提供的方法即可。

在調用設備提供的方法時,由于方法的第一個參數(shù)為p_cookie,p_cookie代表了具體的設備對象,調用方法時,需要傳遞一個p_cookie給下層,用于在具體實現(xiàn)時,訪問設備對象中的具體成員,起到“p_this”的作用。由于在aw_led_set()接口的實現(xiàn)中,并不需要直接操作具體設備,因此,無需知道p_cookie的具體類型,僅需起到一個傳遞的作用:在調用相應的方法時,傳遞給下層驅動使用。

既然要傳遞p_cookie,那么,必然要獲得一個p_cookie并保存下來,顯然,p_cookie代表了具體設備,只能由具體設備提供,同時,抽象方法也是由具體設備提供的,為此,可以將抽象方法和p_cookie定義在一起,形成一個新的類型,以便在具體設備提供的抽象方法的實現(xiàn)時,將p_cookie一并提供,即:

為了便于描述,將其稱之為 “LED服務”。其中包含了由驅動實現(xiàn)的抽象方法和傳遞給驅動函數(shù)的p_cookie。其中,p_servfuncs為指向驅動虛函數(shù)表的指針,比如,指向__g_led_gpio_drv_funcs或__g_led_uart_drv_funcs,p_cookie為指向具體設備的指針,即傳遞給驅動函數(shù)的第一個參數(shù)。此時,在aw_led_set()接口的實現(xiàn)中,無需再完成底層硬件相關的操作,僅需調用LED服務中包含的pfn_led_set方法即可,其范例程序詳見程序清單13.6。

程序清單13.6 aw_led_set()實現(xiàn)(1)

程序中,使用了一個全局變量__gp_led_serv指向當前一個有效的LED服務,顯然,其只有在賦值后才能使用,暫不考慮其如何賦值,僅用以展示pfn_led_set方法的調用形式。

實際中,具體的LED設備往往不止一個。比如,使用GPIO控制的LED設備和使用UART控制的LED設備,它們都可以向系統(tǒng)提供LED服務,這就需要系統(tǒng)具有管理多個LED服務的能力。由于LED設備的數(shù)目無法確定,可能動態(tài)變化,因此,選用單向鏈表進行動態(tài)管理。為此,在struct awbl_led_service中增加一個p_next成員,用于指向下一個LED服務。即:

此時,系統(tǒng)中的多個LED服務使用鏈表的形式進行管理。那么,在通用接口的實現(xiàn)中,如何確定具體該使用哪個LED服務呢?在定義通用接口時,使用了ID號區(qū)分不同的LED,ID號是唯一的,顯然,某一ID的LED必然屬于某一確定的硬件設備,若一個硬件設備在提供LED服務時,包含了該硬件設備中所有LED的ID號信息,那么,在通用接口的實現(xiàn)中,就可以根據(jù)ID找到對應的LED服務,然后使用驅動中提供的方法完成LED的操作。為此,可以在LED服務中再增加一個ID信息,以表示對應硬件設備中所有LED的ID號。

在一個LED硬件設備中,可能包含多個LED,例如,MiniPort-LED擴展板,包含了8個LED,但一般來講,一個LED硬件設備中所有LED的編號是連續(xù)分配的,基于此,僅需知道一個硬件設備中LED的起始編號和結束編號,就可以獲得該硬件設備中所有LED對應的編號,例如,一個硬件設備中LED的起始編號為2、結束編號為9,則表示在該硬件設備中,各個LED的編號分別為:2、3、4、5、6、7、8、9,共計8個LED。為此,可以定義一個LED服務信息結構體類型,專門用于提供LED服務相關的信息,例如:

由此可見,在LED服務信息中,當前僅包含起始編號和結束編號兩個信息。LED服務信息是與具體設備相關的,因此,可以在LED服務中新增一個指向LED服務信息的指針,以便在具體設備在提供p_cookie和抽象方法的實現(xiàn)時,將設備支持的LED編號信息一并提供,LED服務的完整定義詳見程序清單13.7。

程序清單13.7 完整的LED服務類型定義(awbl_led.h)

由于在LED服務中新增了LED編號信息,那么,在通用接口的實現(xiàn)中,就可以根據(jù)設備提供的LED編號信息,找到id對應的LED服務?;诖?,aw_led_set()函數(shù)的實現(xiàn)詳見程序清單13.8。

程序清單13.8 aw_led_set()實現(xiàn)(2)

程序中,調用了__led_id_to_serv()函數(shù)以獲取ID號對應的LED服務。__led_id_to_serv()函數(shù)通過遍歷LED服務鏈表,將id與各個LED服務中的ID信息進行對比,直到找到id對應的LED服務(即id處于該LED服務的起始編號和結束編號之間),具體實現(xiàn)范例詳見程序清單13.9。

程序清單13.9 獲取ID號對應的LED服務

其中,__gp_led_serv_head是一個模塊內部使用的全局變量,初始值為NULL,表示初始時系統(tǒng)中無任何有效的LED服務。同理,可實現(xiàn)aw_led_toggle()接口,詳見程序清單13.10。

程序清單13.10 aw_led_toggle()實現(xiàn)

至此,實現(xiàn)了所有通用接口。顯然,由于當前并不存在任何有效的LED服務,因此,__gp_led_serv_head的值為NULL,致使__led_id_to_serv()的返回值為NULL,最終導致通用接口的返回值始終為-AM_ENODEV。

13.2.4 Method機制

為了使通用接口能夠操作到具體有效的LED,必須通過某種方法,將當前系統(tǒng)中所有LED設備提供的LED服務加入到以__gp_led_serv_head為頭的LED服務鏈表中。

AWbus-lite提供了一種特殊的“Method機制”,其是一種系統(tǒng)上層和硬件底層相互“交流”的一種方式,可用于系統(tǒng)發(fā)現(xiàn)各個硬件設備提供的服務。AWBus-lite提供了Method相關的宏,詳見表13.2。

表13.2 Method相關的宏(awbus_lite.h)

1. 定義一個Method類型

AWBL_METHOD_DEF()用于定義一個Method類型,其原型為:

其中,method為定義的Method類型名,string為一個描述字符串,描述字符串僅在定義時對method類型進行描述,可以是任意字符串,其它地方不會被使用到。

Method類型具有唯一性,不可定義兩個相同的Method類型。Method類型可以看作一個“唯一標識”,用于標記某一類操作,在底層驅動的實現(xiàn)中,凡是能夠完成該類操作的設備,都可以使用該“唯一標識”標記一個入口函數(shù),該入口函數(shù)即用于完成相應的操作,這樣一來,系統(tǒng)就可以通過該“唯一標識”查找所有被標記的入口函數(shù),并依次調用它們,完成某種特定功能。例如,對于LED,為了獲取當前系統(tǒng)中所有設備提供的LED服務,可以定義一個獲取LED服務的Method類型,范例程序詳見程序清單13.11。

程序清單13.11 定義Method類型范例程序

如此一來,即定義了一個名為awbl_ledserv_get的Method類型,該Method類型即表示了一類操作:獲取LED服務。后續(xù)在底層設備驅動的實現(xiàn)中,只要一個設備能夠提供LED服務,則表示系統(tǒng)可以從中獲取到一個LED服務,此時,該驅動就可以提供一個入口函數(shù),用于獲取LED服務,并使用該Method類型對入口函數(shù)進行標記。這樣,在系統(tǒng)啟動時,就可以通過查找系統(tǒng)中所有被該Method類型標記的入口函數(shù),然后一一調用它們,以此獲得所有設備提供的LED服務。

2. 定義一個具體的Method對象

定義Method對象的本質就是使用Method類型標記一個入口函數(shù),使系統(tǒng)知道該入口函數(shù)可以完成某種特定的功能,以便系統(tǒng)在合適的時機調用。為便于描述,在AWBus-lite中,將使用Method類型標記的入口函數(shù)稱之為一個Method對象。AWBus-lite提供了定義Method對象的輔助宏,其原型為:

其中,name為使用AWBL_METHOD_DEF()定義的Method類型名,handler為用于完成某種特定功能的入口函數(shù)。例如,定義awbl_ledserv_get類型的目的是獲取LED服務,因此,該類型的Method對象對應的handler應該能夠獲取到一個LED服務。handler的類型為awbl_method_handler_t,其定義如下(awbus_lite.h):

由此可見,awbl_method_handler_t是一個函數(shù)指針類型,其指向的函數(shù)有兩個形參:p_dev和p_arg,返回值為標準的錯誤號。p_dev指向設備自身,同樣起到一個p_this的作用,該handler運行在哪個設備上,傳入p_dev的值就應該為指向該設備的指針;p_arg為void *類型的參數(shù),其具體類型與該入口函數(shù)需要完成的功能相關,如果功能為獲取一個LED服務,p_arg的實際類型就為struct awbl_led_service **,即一個指向LED服務的指針的地址,以便在函數(shù)內部改變指向LED服務的指針的值,使其指向設備提供的LED服務,從而完成LED服務的獲取。例如,在GPIO控制LED的設備中,其能夠提供LED服務,則應在對應的驅動中,定義一個具體的Method對象,便于系統(tǒng)得到LED服務。范例詳見程序清單13.12。

程序清單13.12 定義Method對象范例程序

其中,__g_led_gpio_dev_methods為該設備能夠提供的Method對象列表,一個設備提供的Method對象統(tǒng)一存放在一個列表中。該列表的具體使用以及入口函數(shù)的具體實現(xiàn),將在LED驅動的實現(xiàn)中進一步介紹。這里僅用于展示系統(tǒng)上層獲取LED服務的原理。

3. Method對象列表結束標記

在程序清單13.12中,將Method對象定義在了一個列表中,AWBL_METHOD_END用于定義一個特殊的標志,表示Method對象列表的結束。其原型為:

該宏無需傳入任何參數(shù),其僅用于標識一個Method對象列表的結束。例如,GPIO控制的LED設備只能提供一個Method對象,用于系統(tǒng)上層獲取LED服務,那么,在該對象之后,應該使用AWBL_METHOD_END表示列表結束。范例程序詳見程序清單13.13。

程序清單13.13 AWBL_METHOD_END使用范例程序

4. 導入(聲明)一個在外部定義的Method類型

當需要使用一個已定義的Method類型時,若Method類型是在其它文件中定義的,此時就需要在使用前對該Method類型進行聲明,類似于C語言中的extern。其原型為:

其中,name為使用AWBL_METHOD_DEF()定義的Method類型名。例如,在程序清單13.13中,定義了Method對象列表,其中使用到了Method類型:awbl_ledserv_get。在使用前,需要對該Method類型進行聲明,范例程序詳見程序清單13.14。

程序清單13.14 AWBL_METHOD_IMPORT()使用范例程序

5. 得到一個已定義的Method類型的ID

Method類型相當于一個“唯一標識”,有時候,需要判斷某一Method對象是否為指定的Method類型。為了便于比較判斷,或將“Method類型”作為參數(shù)傳遞給其它接口函數(shù),可以通過該宏獲得一個Method類型對應的ID,ID作為一個常量,可以用于比較或參數(shù)傳遞。獲取Method類型的ID對應的宏原型為:

其中,method為使用AWBL_METHOD_DEF()定義的Method類型名,返回值為該Method類型的ID,其類型為:awbl_method_id_t,該類型的具體定義用戶無需關心,ID可以用作比較,只要兩個Method類型的ID相同,就表示兩個Method類型是相同的,ID也可以作為參數(shù)傳遞給其它接口,以指定一種Method類型。

例如,在AWbus-lite中,提供了一個工具函數(shù),用于查找設備中是否存在指定類型的Method對象,其函數(shù)原型為(awbus_lite.h):

其中,p_dev指定了要查找的設備,即在該設備中查找是否存在指定類型的Method對象,method用于指定Method類型的ID。若查找到該ID對應的method對象,則返回該method對象的入口函數(shù),否則,返回NULL。

例如,有一個p_dev指向的設備,要查找其是否能夠提供LED服務,則可以通過該接口實現(xiàn),范例程序詳見程序清單13.15。

程序清單13.15 AWBL_METHOD_ CALL()使用范例程序

程序中,使用AWBL_METHOD_ CALL()得到Method類型awbl_ledserv_get的ID,然后傳遞給awbl_dev_method_get()函數(shù)以查找設備中是否存在相應的Method對象,若存在,則得到了一個有效的入口函數(shù),最后使用該入口函數(shù)即可得到一個LED服務。

13.2.5 LED服務鏈表的初始化

通過程序清單13.15所示的一個流程,若一個設備能夠提供LED服務,則可以從中獲取到相應的LED服務。若對每個設備都執(zhí)行一遍上述流程,并在獲得一個設備提供的LED服務后,就將其添加到以__gp_led_serv_head為頭的LED服務鏈表中,則可以收集到系統(tǒng)中所有的LED服務,完成LED服務鏈表的初始構建。為了便于對所有設備執(zhí)行某一操作,AWBus-lite提供了一個用于遍歷所有設備的接口,其函數(shù)原型為:

其中,pfunc_action表示要在每個設備上執(zhí)行的操作,p_arg為傳遞給pfunc_action的附加參數(shù),flags為遍歷設備的標志,返回值為標準錯誤號。

pfunc_action的類型為awbl_iterate_func_t,該類型的具體定義如下(awbus_lite.h):

由此可見,awbl_iterate_func_t是一個函數(shù)指針類型,其指向的函數(shù)有兩個形參:p_dev和p_arg,返回值為標準的錯誤號。p_dev指向當前遍歷到的設備,同樣起到一個p_this的作用,當前遍歷到哪個設備,在哪個設備上運行pfunc_action函數(shù),傳入的p_dev就為指向該設備的指針;p_arg為遍歷時提供的附加參數(shù),其值與調用awbl_dev_iterate()函數(shù)時傳入的p_arg參數(shù)相同。

flags為遍歷設備的標志,其決定了需要遍歷哪些設備,以及pfunc_action函數(shù)的返回值是否能夠終止遍歷過程??捎脴酥驹斠姳?3.3。

表13.3 遍歷設備標志宏(awbus_lite.h)

其中,AWBL_ITERATE_INSTANCES和AWBL_ITERATE_ORPHANS標志用于指定需要遍歷的設備,即在哪些設備上執(zhí)行pfunc_action函數(shù)。在硬件設備列表中,定義了當前系統(tǒng)中所有的硬件設備,當設備具有與之匹配的驅動時,才能夠變成一個實例,被系統(tǒng)正常使用,而如果一個設備沒有與之匹配的驅動,該設備將變成一個孤兒設備,由于沒有與之匹配的驅動,因此系統(tǒng)暫時無法使用孤兒設備。AWBL_ITERATE_INSTANCES表示表示需要遍歷所有實例,即具有相應驅動的設備。AWBL_ITERATE_ORPHANS表示需要遍歷所有的孤兒設備。若要遍歷所有的實例和孤兒設備,可以使用或運算同時設定這兩個標志。

AWBL_ITERATE_INTRABLE標志用于指定pfunc_action 的返回值是否可以終止遍歷,若設定了該標志,則在某一設備上運行pfunc_action函數(shù)的返回值將可以決定是否終止整個遍歷過程:返回值為AW_OK時,不終止遍歷,繼續(xù)遍歷其它設備;否則,遍歷過程被終止,不會再繼續(xù)遍歷其它設備。若未設定該標志,則遍歷過程不受返回值影響,直到遍歷完所有需要遍歷的設備后結束。

為了獲得所有設備提供的LED服務,需要遍歷所有實例,并在pfunc_action中執(zhí)行如程序清單13.15所示的流程,并將各個設備提供的LED服務添加到以__gp_led_serv_head為頭的LED服務鏈表中。完整的范例程序詳見程序清單13.16。

程序清單13.16 獲取所有設備提供的LED服務

程序中,由于孤兒設備沒有對應的驅動,無法正常使用,顯然無法提供LED服務,因此僅需遍歷所有實例,遍歷標志設定為了:AWBL_ITERATE_INSTANCES。該程序的目的是完成LED服務鏈表的初始構建,是一種初始化操作,因此,將其入口函數(shù)命名為了awbl_led_init(),若需使用LED,則應確保在系統(tǒng)啟動時,該函數(shù)被自動調用。通常情況下,并不需要由用戶手動調用該函數(shù),而是將該函數(shù)的調用放在模板工程下的aw_prj_config.c文件中,具體位于aw_prj_early_init()函數(shù)中,該函數(shù)在系統(tǒng)啟動時會被自動調用,從而使系統(tǒng)在啟動時自動調用awbl_led_init()函數(shù),詳見詳見程序清單13.17。

程序清單13.17 awbl_led_init()在系統(tǒng)啟動時被自動調用的原理

在aw_prj_params.h工程配置文件中,只要使能了某一LED設備,比如,AW_DEV_GPIO_LED,則表示要使用LED,此時,將自動完成AW_COM_AWBL_LED的定義,以此確保當使用LED時,awbl_led_init()會在系統(tǒng)啟動過程中被自動調用。核心的原理性程序詳見程序清單13.18。

程序清單13.18 自動定義AW_COM_AWBL_LED宏的原理(aw_prj_params.h)

至此,完成了LED服務鏈表的初始化,若系統(tǒng)中存在LED服務,則鏈表將不為空,在LED通用接口的實現(xiàn)中,只要傳入的id正確,__led_id_to_serv()的返回值就不為NULL,進而返回一個有效的LED服務,接著,通過LED服務中實現(xiàn)的抽象方法,即可完成LED相關的操作,例如,設置LED狀態(tài)、翻轉LED狀態(tài)等。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 接口
    +關注

    關注

    33

    文章

    8360

    瀏覽量

    150522
  • 總線
    +關注

    關注

    10

    文章

    2849

    瀏覽量

    87840
  • 周立功
    +關注

    關注

    38

    文章

    130

    瀏覽量

    37523

原文標題:AWorks軟件篇 — 深入理解 AWbus-lite(接口的定義和實現(xiàn))

文章出處:【微信號:Zlgmcu7890,微信公眾號:周立功單片機】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    設備驅動在AWbus-lite中驅動設備正常工作

    硬件設備正常工作的前提是系統(tǒng)中存在對應的驅動。AWorks提供了大量常用硬件設備的驅動,用戶通常不需要開發(fā)驅動。本文介紹了設備驅動相關的基礎概念,展示了設備驅動在AWbus-lite中驅動設備正常工作的原理。
    的頭像 發(fā)表于 06-12 09:06 ?4057次閱讀
    設備驅動在<b class='flag-5'>AWbus-lite</b>中驅動設備正常工作

    AWBus-lite的拓撲結構及應用設計

    為了管理系統(tǒng)中各式各樣的硬件設備(或虛擬硬件設備),AWorks推出了領先的輕量級總線管理框架:AWBus-lite,實現(xiàn)了硬件設備和驅動的徹底分離,使設備驅動可以最大限度的得到復用。本文介紹了AWBus-lite的基礎概念……
    的頭像 發(fā)表于 06-21 09:10 ?5828次閱讀
    <b class='flag-5'>AWBus-lite</b>的拓撲結構及應用設計

    深入理解Android

    深入理解Android
    發(fā)表于 08-20 15:30

    深入理解實現(xiàn)RTOS_連載

    和trcohili的帖子。深入理解實現(xiàn)RTOS_連載1_RTOS的前生今世今天發(fā)布的是第一篇,"RTOS的前生今世"。通過軟件系統(tǒng)結構的比對簡要的介紹rtos為何而生。如果讀者對RTOS
    發(fā)表于 05-29 11:20

    深入理解實現(xiàn)RTOS_連載

    和trcohili的帖子。trochili rtos完全是作者興趣所在,且行且堅持,比沒有duo。深入理解實現(xiàn)RTOS_連載1_RTOS的前生今世今天發(fā)布的是第一篇,"RTOS的前生今世"
    發(fā)表于 05-30 01:02

    深入理解lte-a

    深入理解LTE-A
    發(fā)表于 02-26 10:21

    深入理解STM32

    時鐘系統(tǒng)是處理器的核心,所以在學習STM32所有外設之前,認真學習時鐘系統(tǒng)是必要的,有助于深入理解STM32。下面是網(wǎng)上找的一STM32時鐘框圖,比《STM32中文參考手冊》里面的是中途看起來清晰一些:重要的時鐘:PLLCL
    發(fā)表于 08-12 07:46

    對棧的深入理解

    為什么要深入理解棧?做C語言開發(fā)如果棧設置不合理或者使用不對,棧就會溢出,溢出就會遇到無法預測亂飛現(xiàn)象。所以對棧的深入理解是非常重要的。注:動畫如果看不清楚可以電腦看更清晰啥是棧先來看一段動畫:沒有
    發(fā)表于 02-15 07:01

    為什么要深入理解

    [導讀] 從這篇文章開始,將會不定期更新關于嵌入式C語言編程相關的個人認為比較重要的知識點,或者踩過的坑。為什么要深入理解棧?做C語言開發(fā)如果棧設置不合理或者使用不對,棧就會溢出,溢出就會遇到無法
    發(fā)表于 02-15 06:09

    深入理解Android》文前

    深入理解Android》文前
    發(fā)表于 03-19 11:23 ?0次下載

    深入理解Android:卷I》

    深入理解Android:卷I》
    發(fā)表于 03-19 11:23 ?0次下載

    深入理解Android網(wǎng)絡編程

    深入理解Android網(wǎng)絡編程
    發(fā)表于 03-19 11:26 ?1次下載

    基于AWBus-lite總線拓撲結構的設備管理框架

    在使用AWBus-lite對設備進行管理時,無論設備處于 AWBus-lite拓撲結構中的哪個位置,只要其能夠提供某種標準服務,就可以使用相應的通用接口對其進行操作。本文將從接口
    的頭像 發(fā)表于 07-02 09:20 ?5264次閱讀
    基于<b class='flag-5'>AWBus-lite</b>總線拓撲結構的設備管理框架

    辨別PCB線路板好壞可以兩個方面入手

    面對市面上五花八門的PCB線路板,辨別PCB線路板好壞可以兩個方面入手;第一種方法就是外觀來分判斷,另一方面就是PCB板本身質量規(guī)范要
    的頭像 發(fā)表于 08-28 15:12 ?3481次閱讀

    兩個方面講解電子連接器知識

    兩個方面講解電子連接器知識”由德索連接器為您整理,采購連接器,上德索。功能上定義理解,電子連接器是在一電子系統(tǒng)中的
    的頭像 發(fā)表于 01-12 18:13 ?825次閱讀
    <b class='flag-5'>兩個方面</b>講解電子連接器知識