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

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

設(shè)備驅(qū)動(dòng)在AWbus-lite中驅(qū)動(dòng)設(shè)備正常工作

AGk5_ZLG_zhiyua ? 來(lái)源:互聯(lián)網(wǎng) ? 作者:佚名 ? 2018-06-12 09:06 ? 次閱讀

本文導(dǎo)讀

一個(gè)硬件設(shè)備正常工作的前提是系統(tǒng)中存在對(duì)應(yīng)的驅(qū)動(dòng)。AWorks提供了大量常用硬件設(shè)備的驅(qū)動(dòng),用戶通常不需要開(kāi)發(fā)驅(qū)動(dòng)。為了使讀者對(duì)設(shè)備驅(qū)動(dòng)有一定的理解,本文介紹了設(shè)備驅(qū)動(dòng)相關(guān)的基礎(chǔ)概念,展示了設(shè)備驅(qū)動(dòng)在AWbus-lite中驅(qū)動(dòng)設(shè)備正常工作的原理。

本文為《面向AWorks框架和接口編程(上)》第三部分軟件篇——第13章——第3小節(jié):設(shè)備驅(qū)動(dòng)。

13.3 設(shè)備驅(qū)動(dòng)

上面討論了如何通過(guò)Method機(jī)制獲得具體設(shè)備提供的LED服務(wù),系統(tǒng)能夠從某一設(shè)備獲得LED服務(wù)的前提是,該硬件具有提供LED服務(wù)的能力。一個(gè)硬件設(shè)備相關(guān)的功能,需要通過(guò)設(shè)備驅(qū)動(dòng)才能體現(xiàn)出來(lái),進(jìn)而為系統(tǒng)服務(wù)。為此,在LED設(shè)備驅(qū)動(dòng)中,需要實(shí)現(xiàn)一個(gè)LED服務(wù),以供上層獲取。

13.3.1 基礎(chǔ)驅(qū)動(dòng)信息

AWBus-lite對(duì)設(shè)備驅(qū)動(dòng)進(jìn)行了高度的抽象,定義了驅(qū)動(dòng)的基本結(jié)構(gòu),一個(gè)設(shè)備驅(qū)動(dòng)相關(guān)的信息統(tǒng)一使用一個(gè)結(jié)構(gòu)體常量進(jìn)行描述。其中包含了諸多信息,比如:驅(qū)動(dòng)名、驅(qū)動(dòng)初始化入口、驅(qū)動(dòng)提供的Method對(duì)象等。開(kāi)發(fā)驅(qū)動(dòng)的核心即完成一個(gè)結(jié)構(gòu)體常量的定義。

不同總線下的設(shè)備驅(qū)動(dòng)需要提供的驅(qū)動(dòng)信息可能不同,對(duì)應(yīng)的驅(qū)動(dòng)信息類(lèi)型也就不同。但無(wú)論什么總線下的設(shè)備驅(qū)動(dòng),其驅(qū)動(dòng)信息類(lèi)型均是從基礎(chǔ)驅(qū)動(dòng)信息類(lèi)型派生而來(lái)的,也就是說(shuō),無(wú)論什么設(shè)備驅(qū)動(dòng),都需要提供AWBus-lite定義的基礎(chǔ)驅(qū)動(dòng)信息,即使需要擴(kuò)展其它驅(qū)動(dòng)信息,也只能在基礎(chǔ)驅(qū)動(dòng)信息的基礎(chǔ)上進(jìn)行擴(kuò)展。

由于所有設(shè)備驅(qū)動(dòng)均會(huì)提供基礎(chǔ)驅(qū)動(dòng)信息,因此,AWBus-lite可以方便的對(duì)所有驅(qū)動(dòng)進(jìn)行統(tǒng)一的管理?;A(chǔ)驅(qū)動(dòng)信息的類(lèi)型為struct awbl_drvinfo,具體定義詳見(jiàn)程序清單13.19。

程序清單13.19 struct awbl_drvinfo類(lèi)型定義(awbl_lite.h)

要實(shí)現(xiàn)一個(gè)驅(qū)動(dòng),需要定義一個(gè)該類(lèi)型結(jié)構(gòu)體,并完成各個(gè)成員的賦值。下面,首先對(duì)各個(gè)成員的含義作簡(jiǎn)要介紹。

1. AWBus-lite版本號(hào)

awb_ver表示該驅(qū)動(dòng)支持的AWBus-lite版本號(hào),當(dāng)前AWBus-lite的版本號(hào)為:AWBL_VER_1,其在awbus_lite.h文件中定義如下:

在新開(kāi)發(fā)驅(qū)動(dòng)時(shí),將awb_ver設(shè)置為AWBL_VER_1即可。

2. 總線ID

bus_id表示總線ID,該值由總線類(lèi)型和設(shè)備類(lèi)型兩部分組成。總線類(lèi)型與設(shè)備描述中的總線類(lèi)型概念一致,其表示了該驅(qū)動(dòng)所驅(qū)動(dòng)的設(shè)備掛在何種總線上,常見(jiàn)總線類(lèi)型詳見(jiàn)表12.1。實(shí)際中,在進(jìn)行驅(qū)動(dòng)和設(shè)備的匹配操作時(shí),只有當(dāng)驅(qū)動(dòng)信息中的總線類(lèi)型與設(shè)備描述中的總線類(lèi)型一致時(shí),才會(huì)繼續(xù)判定設(shè)備名和驅(qū)動(dòng)名是否一致,只有當(dāng)兩者完全相同時(shí),驅(qū)動(dòng)和設(shè)備才會(huì)判定為匹配。設(shè)備類(lèi)型表明該驅(qū)動(dòng)對(duì)應(yīng)的設(shè)備是普通設(shè)備還是特殊設(shè)備(總線控制器),若是總線控制器,則其驅(qū)動(dòng)的設(shè)備又會(huì)擴(kuò)展出另外一條總線。設(shè)備類(lèi)型可能的取值詳見(jiàn)表13.4。

表13.4 設(shè)備類(lèi)型宏定義

bus_id的值為總線類(lèi)型和設(shè)備類(lèi)型的或值(C語(yǔ)言的“|”運(yùn)算符)。特別地,若一個(gè)設(shè)備是普通設(shè)備,則設(shè)備類(lèi)型可以省略,即

AWBL_DEVID_DEVICE宏可以被省略。

例如,對(duì)于使用GPIO直接控制的LED設(shè)備驅(qū)動(dòng),GPIO是一種片內(nèi)外設(shè),當(dāng)前并沒(méi)有將GPIO視為一種總線,在AWBus-lite中,由GPIO直接驅(qū)動(dòng)的設(shè)備也視為掛在PLB上的一種設(shè)備。因而總線類(lèi)型為:AWBL_BUSID_PLB,同時(shí),LED設(shè)備只是一個(gè)普通設(shè)備,并非總線控制器,因而設(shè)備類(lèi)型為AWBL_DEVID_DEVICE。bus_id的值即為:

AWBL_BUSID_PLB | AWBL_DEVID_DEVICE

(或省略AWBL_DEVID_DEVICE,直接設(shè)定為

AWBL_BUSID_PLB)。

對(duì)于i.MX28x的I2C驅(qū)動(dòng),其驅(qū)動(dòng)的設(shè)備是片內(nèi)外設(shè),掛在PLB總線上,因而總線類(lèi)型為:AWBL_BUSID_PLB。同時(shí),i.MX28x 中的I2C設(shè)備又是一種總線控制器,可以擴(kuò)展出一條I2C總線,因而設(shè)備類(lèi)型為:

AWBL_DEVID_BUSCTRL。bus_id的值即為:

AWBL_BUSID_PLB | AWBL_DEVID_BUSCTRL。

對(duì)于PCF85063設(shè)備驅(qū)動(dòng),其驅(qū)動(dòng)的設(shè)備掛在I2C總線上,因而總線類(lèi)型為:AWBL_BUSID_I2C。同時(shí),PCF85063是一個(gè)普通設(shè)備,并非總線控制器,因而設(shè)備類(lèi)型為AWBL_DEVID_DEVICE。bus_id的值即為:

AWBL_BUSID_I2C | AWBL_DEVID_DEVICE

(或省略AWBL_DEVID_DEVICE,直接設(shè)定為

AWBL_BUSID_I2C)。

3. 驅(qū)動(dòng)名

p_drvname表示該驅(qū)動(dòng)的名字。在設(shè)備描述中,使用了“設(shè)備名”用來(lái)描述設(shè)備的名字,在系統(tǒng)啟動(dòng)時(shí),會(huì)為每個(gè)設(shè)備尋找合適的驅(qū)動(dòng),當(dāng)驅(qū)動(dòng)的總線類(lèi)型和設(shè)備描述中的總線類(lèi)型一致時(shí),將會(huì)把“驅(qū)動(dòng)名”與“設(shè)備名”進(jìn)行比對(duì),完全一致時(shí),將視為驅(qū)動(dòng)與設(shè)備匹配,進(jìn)而將該驅(qū)動(dòng)和對(duì)應(yīng)的設(shè)備進(jìn)行綁定。在AWBus-lite中,當(dāng)一個(gè)驅(qū)動(dòng)和設(shè)備匹配后,驅(qū)動(dòng)名和設(shè)備名勢(shì)必是完全一致的,因而在匹配后可以直接將驅(qū)動(dòng)名作為設(shè)備名。

對(duì)于使用GPIO控制的LED設(shè)備驅(qū)動(dòng),其驅(qū)動(dòng)名可以定義為:

4. 驅(qū)動(dòng)入口點(diǎn)

設(shè)備在使用前,需要完成必要的初始化操作,例如,對(duì)于使用GPIO控制的LED設(shè)備,需要在初始時(shí)將引腳配置為輸出模式。作為設(shè)備驅(qū)動(dòng),必須提供相關(guān)的初始化函數(shù)以完成設(shè)備的初始化。驅(qū)動(dòng)入口點(diǎn)p_busfuncs即用于提供初始化函數(shù)的入口,其為指向struct awbl_drvfuncs類(lèi)型結(jié)構(gòu)體常量的指針,struct awbl_drvfuncs類(lèi)型定義詳見(jiàn)程序清單13.20。

程序清單13.20 struct awbl_drvfuncs類(lèi)型定義(awbus_lite.h)

其中,包含了3個(gè)函數(shù)指針,分別對(duì)應(yīng)了AWBus-lite中三個(gè)階段的初始化動(dòng)作。由此可見(jiàn),為了完成一個(gè)設(shè)備的初始化,驅(qū)動(dòng)需要提供三個(gè)初始化函數(shù),分別用于完成設(shè)備不同階段的初始化,各階段對(duì)應(yīng)的初始化函數(shù)將在系統(tǒng)啟動(dòng)過(guò)程中被依次調(diào)用。各階段初始化函數(shù)的類(lèi)型是完全一樣的,均只有一個(gè)指向設(shè)備實(shí)例的指針作為形參,且均無(wú)返回值。即:

例如,對(duì)于使用GPIO控制的LED設(shè)備驅(qū)動(dòng),為了完成設(shè)備的初始化,需要提供3個(gè)初始化函數(shù),結(jié)構(gòu)性范例程序詳見(jiàn)程序清單13.21。

程序清單13.21 驅(qū)動(dòng)初始化函數(shù)結(jié)構(gòu)性范例程序

其中,__g_awbl_drvfuncs_led_gpio的地址即可作為驅(qū)動(dòng)入口點(diǎn)p_busfuncs的值。各初始化函數(shù)的實(shí)現(xiàn)將在后文進(jìn)行詳細(xì)介紹。

在系統(tǒng)啟動(dòng)時(shí),將根據(jù)驅(qū)動(dòng)信息中提供的驅(qū)動(dòng)入口點(diǎn)信息,依次調(diào)用各階段對(duì)應(yīng)的初始化函數(shù),進(jìn)而完成一個(gè)設(shè)備的初始化。在調(diào)用各初始化函數(shù)時(shí),傳入形參p_dev的值為設(shè)備描述中p_dev的值,其本質(zhì)上指向了靜態(tài)定義的設(shè)備實(shí)例。

在AWBus-lite中,將設(shè)備的初始化分為了三個(gè)階段:第一階段、第二階段、第三階段。這樣的劃分有著極其重要的意義,各階段對(duì)應(yīng)的初始化函數(shù)被系統(tǒng)調(diào)用的時(shí)機(jī)并不相同。

  • 第一階段

第一階段為設(shè)備初始化過(guò)程中最先進(jìn)入的階段,在該階段中,系統(tǒng)總中斷被關(guān)閉,OS內(nèi)核服務(wù)(如多任務(wù)管理)尚未提供,調(diào)試串口也尚未準(zhǔn)備就緒。作為設(shè)備驅(qū)動(dòng),只能處理一些設(shè)備相關(guān)的最基本、最簡(jiǎn)單的操作,不可在本階段中使用常見(jiàn)的其它服務(wù),比如:執(zhí)行連接中斷、申請(qǐng)信號(hào)量、打印調(diào)試信息等操作。對(duì)于絕大部分普通設(shè)備驅(qū)動(dòng),該階段對(duì)應(yīng)的函數(shù)設(shè)置為空,不執(zhí)行任何操作。

  • 第二階段

第二階段為設(shè)備初始化的主要階段,設(shè)備相關(guān)的絕大部分初始化操作均在該階段中完成,在第二階段中,系統(tǒng)相關(guān)的服務(wù)均已準(zhǔn)備就緒,比如:中斷、調(diào)試串口、信號(hào)量、多任務(wù)等。可以在第二階段中使用這些服務(wù)。

  • 第三階段

第三階段作為第二階段后的一個(gè)階段,系統(tǒng)相關(guān)的服務(wù)同樣已準(zhǔn)備就緒,比如:中斷、調(diào)試串口、信號(hào)量、多任務(wù)等。第三階段主要用于完成比較耗時(shí)的初始化操作,第三階段相關(guān)的操作將在一個(gè)單獨(dú)的任務(wù)中執(zhí)行,不會(huì)影響系統(tǒng)的整體啟動(dòng)過(guò)程。

例如,在某一設(shè)備的初始化過(guò)程中,有一個(gè)特殊的操作需要一分鐘才能完成,為了不影響系統(tǒng)的啟動(dòng)效率,可以將該耗時(shí)較長(zhǎng)的操作放在第三階段中完成,如此一來(lái),系統(tǒng)同樣可以快速啟動(dòng),進(jìn)而運(yùn)行至應(yīng)用程序入口,即aw_main()。否則,若將該操作放在第二階段中,則系統(tǒng)必須在第二階段初始化完成后才能啟動(dòng)完成,接著才能運(yùn)行至應(yīng)用程序入口處,導(dǎo)致系統(tǒng)的整個(gè)啟動(dòng)過(guò)程變慢。

系統(tǒng)啟動(dòng)速度的快慢將直接影響用戶體驗(yàn),以數(shù)字示波器為例,傳統(tǒng)示波器的開(kāi)機(jī)時(shí)間幾乎都在30秒甚至1分鐘以上,對(duì)于現(xiàn)場(chǎng)測(cè)試工程師來(lái)說(shuō),有可能會(huì)遺漏稍縱即逝的異常信號(hào),幾乎所有的示波器廠商都對(duì)這個(gè)需求熟視無(wú)睹,而廣州致遠(yuǎn)電子有限公司的設(shè)計(jì)理念卻與眾不同,使用AWorks助力ZDS系列示波器,使用戶從按下電源到開(kāi)始使用,整個(gè)過(guò)程僅需要十余秒,其開(kāi)機(jī)時(shí)間擊敗了所有其他品牌的示波器。讓用戶從按下電源的那一刻起,就能感受到極致的體驗(yàn)。

在AWBus-lite中,巧妙的將一個(gè)設(shè)備的初始化過(guò)程分為了三個(gè)階段,可以使系統(tǒng)的啟動(dòng)速度從結(jié)構(gòu)上得到優(yōu)化,在大多數(shù)中小系統(tǒng)中,系統(tǒng)啟動(dòng)時(shí)間都小于1秒。

特別地,在一些設(shè)備的初始化過(guò)程中,可能并沒(méi)有耗時(shí)較長(zhǎng)的操作,此時(shí),可以將第三階段對(duì)應(yīng)的函數(shù)設(shè)置為空,不執(zhí)行任何操作。

5. Method對(duì)象列表

每個(gè)設(shè)備都是為系統(tǒng)提供某種服務(wù)而存在的,其提供了相應(yīng)的服務(wù),才能被系統(tǒng)、用戶所使用。如LED設(shè)備可以為系統(tǒng)提供LED服務(wù),為了使系統(tǒng)能夠獲取到設(shè)備提供的LED服務(wù),需要提供相應(yīng)的Method對(duì)象,以指定獲取LED服務(wù)對(duì)應(yīng)的入口函數(shù)。定義一個(gè)Method對(duì)象的范例詳見(jiàn)程序清單13.22。

程序清單13.22 定義Method對(duì)象范例程序

一些特殊設(shè)備,可能可以為系統(tǒng)提供多種服務(wù),這時(shí),對(duì)應(yīng)驅(qū)動(dòng)中將需要定義多個(gè)Method對(duì)象,每個(gè)Method對(duì)象用于獲取某一種服務(wù)。

為此,AWBus-lite中,將一個(gè)驅(qū)動(dòng)定義的所有Method對(duì)象存放在一個(gè)列表中,并以AWBL_METHOD_END表示列表的結(jié)束。驅(qū)動(dòng)信息p_methods即用于指向Method對(duì)象列表,范例詳見(jiàn)程序清單13.23。

程序清單13.23 定義Method對(duì)象列表范例程序

其中,__g_led_gpio_dev_methods即可作為驅(qū)動(dòng)信息中p_methods的值。Method對(duì)象的具體定義將在后文詳細(xì)介紹。

6. 驅(qū)動(dòng)探測(cè)函數(shù)

在基礎(chǔ)驅(qū)動(dòng)信息中,pfunc_drv_probe是一個(gè)函數(shù)指針,用于指向一個(gè)探測(cè)函數(shù),用于探測(cè)驅(qū)動(dòng)是否支持該設(shè)備。其類(lèi)型為:

由此可見(jiàn),其指向的函數(shù)是具有一個(gè)p_dev形參,返回值為布爾類(lèi)型的函數(shù)。

p_dev是指向設(shè)備實(shí)例的指針,用于指定探測(cè)的設(shè)備。返回值為布爾類(lèi)型,返回AW_TRUE時(shí),探測(cè)成功;否則,探測(cè)失敗。

前面提到過(guò)系統(tǒng)是如何判定設(shè)備與驅(qū)動(dòng)是否匹配的。設(shè)備與驅(qū)動(dòng)匹配的首要條件是設(shè)備描述中的總線類(lèi)型與驅(qū)動(dòng)信息中的總線類(lèi)型一致。在總線類(lèi)型一致的情況下,可以增加兩種額外的判定條件。

一種條件是針對(duì)該總線類(lèi)型的,該總線類(lèi)型下的設(shè)備和驅(qū)動(dòng),都必須滿足該條件。不同總線類(lèi)型對(duì)該條件的定義可能不同,但對(duì)于絕大部分總線來(lái)說(shuō),其判定條件都是:驅(qū)動(dòng)名和設(shè)備名是否相同。這也是前面提到系統(tǒng)中使用驅(qū)動(dòng)名和設(shè)備名進(jìn)行匹配判定的原因。需要用戶注意的是,這種條件是與具體總線類(lèi)型相關(guān)的,雖然絕大部分總線類(lèi)型的判定條件都是驅(qū)動(dòng)名和設(shè)備名是否相同,但也不排除可能出現(xiàn)某一類(lèi)型的總線,其不要求設(shè)備名和驅(qū)動(dòng)名一致,這種情況極為罕見(jiàn),如果出現(xiàn),應(yīng)該對(duì)該類(lèi)總線作出非常重要的特殊說(shuō)明。

一種條件是針對(duì)某一特定驅(qū)動(dòng)的,這種條件通過(guò)驅(qū)動(dòng)提供探測(cè)函數(shù)來(lái)實(shí)現(xiàn)。若驅(qū)動(dòng)不需要進(jìn)行額外的判斷,則將pfunc_drv_probe的值設(shè)置為NULL。若需要進(jìn)行額外的判斷,則應(yīng)提供一個(gè)有效的探測(cè)函數(shù),在探測(cè)函數(shù)的實(shí)現(xiàn)中,若判定驅(qū)動(dòng)和設(shè)備匹配,能夠支持相應(yīng)的設(shè)備,則應(yīng)返回AW_TRUE,以告知AWBus-lite系統(tǒng),驅(qū)動(dòng)和設(shè)備是匹配的,進(jìn)而將設(shè)備和驅(qū)動(dòng)進(jìn)行綁定;若判定驅(qū)動(dòng)和設(shè)備不匹配,驅(qū)動(dòng)不支持該設(shè)備,則應(yīng)該返回AW_FALSE,以告知AWBus-lite系統(tǒng),驅(qū)動(dòng)和設(shè)備不匹配。

通常情況下,對(duì)于絕大部分驅(qū)動(dòng)而言,并不需要進(jìn)行的探測(cè),此時(shí),需將pfunc_drv_probe的值設(shè)置為NULL?;诖耍ǔG闆r下,只要驅(qū)動(dòng)與設(shè)備的總線類(lèi)型和名字一致,均可視為驅(qū)動(dòng)和設(shè)備匹配。

以上僅僅對(duì)基礎(chǔ)驅(qū)動(dòng)信息中各成員的含義進(jìn)行了簡(jiǎn)要的介紹,其中的初始化函數(shù),Method對(duì)象列表等均還未實(shí)際實(shí)現(xiàn),后文將以開(kāi)發(fā)LED設(shè)備驅(qū)動(dòng)為例,進(jìn)一步介紹設(shè)備類(lèi)型的定義、設(shè)備信息類(lèi)型的定義、初始化函數(shù)的實(shí)現(xiàn),Method對(duì)象的具體實(shí)現(xiàn)等。

13.3.2 實(shí)際驅(qū)動(dòng)信息

在開(kāi)發(fā)具體的設(shè)備驅(qū)動(dòng)時(shí),需要明確該驅(qū)動(dòng)所對(duì)應(yīng)的設(shè)備掛在何種總線上,不同總線下的設(shè)備對(duì)應(yīng)驅(qū)動(dòng)可能需要提供不同的驅(qū)動(dòng)信息,此時(shí),它們對(duì)應(yīng)的驅(qū)動(dòng)信息類(lèi)型也是不同的。無(wú)論何種總線下的設(shè)備驅(qū)動(dòng),它們的驅(qū)動(dòng)信息類(lèi)型都是從基礎(chǔ)驅(qū)動(dòng)信息派生而來(lái)的,以便在基礎(chǔ)驅(qū)動(dòng)信息的基礎(chǔ)上,擴(kuò)展一些特殊的總線相關(guān)的成員。但在實(shí)際中,常見(jiàn)的大多數(shù)總線下的設(shè)備驅(qū)動(dòng)信息并沒(méi)有擴(kuò)展更多的成員,例如,PLB總線下的設(shè)備驅(qū)動(dòng),其對(duì)應(yīng)的驅(qū)動(dòng)信息類(lèi)型為awbl_plb_drvinfo_t,其定義詳見(jiàn)程序清單13.24。

程序清單13.24 awbl_plb_drvinfo_t類(lèi)型定義(awbl_plb.h

對(duì)于I2C總線下的設(shè)備驅(qū)動(dòng),其對(duì)應(yīng)的驅(qū)動(dòng)信息類(lèi)型為awbl_i2c_drvinfo_t,其定義詳見(jiàn)程序清單13.25。

程序清單13.25 awbl_i2c_drvinfo_t類(lèi)型定義(awbl_i2cbus.h)

由此可見(jiàn),這些總線下的設(shè)備驅(qū)動(dòng),并沒(méi)有擴(kuò)展額外的成員,均是對(duì)基礎(chǔ)驅(qū)動(dòng)信息的簡(jiǎn)單繼承。即使如此,出于結(jié)構(gòu)性考慮,為了便于后續(xù)擴(kuò)展,每種總線都單獨(dú)定義了相應(yīng)的驅(qū)動(dòng)信息類(lèi)型。用戶僅需了解到,開(kāi)發(fā)不同總線下的設(shè)備驅(qū)動(dòng)時(shí),它們對(duì)應(yīng)的驅(qū)動(dòng)信息類(lèi)型可能是不同的,需要查看總線對(duì)應(yīng)的實(shí)際驅(qū)動(dòng)信息類(lèi)型,以判斷在開(kāi)發(fā)驅(qū)動(dòng)時(shí),除了提供基礎(chǔ)驅(qū)動(dòng)信息外,是否還需要提供其它額外的信息。

13.3.3 定義設(shè)備類(lèi)型

通過(guò)前面對(duì)硬件設(shè)備列表的介紹可知,在硬件設(shè)備的描述中,需要使用驅(qū)動(dòng)定義的具體設(shè)備類(lèi)型定義一個(gè)設(shè)備實(shí)例,用于為設(shè)備分配必要的內(nèi)存空間,設(shè)備相關(guān)的狀態(tài)、變量、屬性等相關(guān)數(shù)據(jù)都可以存放在該設(shè)備實(shí)例中。

在AWBus-lite中,所有具體設(shè)備類(lèi)型均是從基礎(chǔ)設(shè)備類(lèi)型struct awbl_dev派生而來(lái)的,在定義設(shè)備類(lèi)型時(shí),基礎(chǔ)設(shè)備類(lèi)型的成員應(yīng)該作為設(shè)備類(lèi)型的第一個(gè)成員,基于此,可以定義LED設(shè)備類(lèi)型為:

顯然,要完成LED設(shè)備類(lèi)型的定義,重點(diǎn)是考慮需要定義哪些其它成員。LED設(shè)備的核心功能是為系統(tǒng)提供LED服務(wù),回顧LED服務(wù)的具體類(lèi)型定義,詳見(jiàn)程序清單13.26。

程序清單13.26 LED服務(wù)類(lèi)型定義(awbl_led.h)

LED服務(wù)類(lèi)型作為一個(gè)結(jié)構(gòu)體類(lèi)型,顯然,需要占用一定的內(nèi)存空間,由于每個(gè)LED設(shè)備均能提供LED服務(wù),因此,可以將LED服務(wù)作為L(zhǎng)ED設(shè)備類(lèi)型的一個(gè)成員。當(dāng)需要為系統(tǒng)上層提供LED服務(wù)時(shí),只需要將LED服務(wù)中的各個(gè)成員正確賦值,提交給上層即可。基于此,可以更新LED設(shè)備類(lèi)型的定義,詳見(jiàn)程序清單13.27。

程序清單13.27 LED設(shè)備類(lèi)型的定義

當(dāng)前僅僅從LED的主要功能出發(fā),完成了LED設(shè)備類(lèi)型的定義,若在開(kāi)發(fā)過(guò)程中,發(fā)現(xiàn)需要在設(shè)備類(lèi)型中增加新的成員,可以隨時(shí)動(dòng)態(tài)添加。在設(shè)備描述中,如需定義一個(gè)設(shè)備實(shí)例,直接使用該類(lèi)型定義一個(gè)設(shè)備實(shí)例即可,例如:

13.3.4 定義設(shè)備信息類(lèi)型

通過(guò)前面對(duì)硬件設(shè)備列表的介紹可知,在硬件設(shè)備的描述中,需要提供硬件設(shè)備信息。硬件設(shè)備信息的具體類(lèi)型同樣由相應(yīng)的驅(qū)動(dòng)定義。

在使用LED設(shè)備時(shí),往往需要用戶提供一些必要的信息,例如,在使用GPIO控制LED時(shí),需要知道各個(gè)LED對(duì)應(yīng)的引腳信息,即使用哪些GPIO引腳控制相應(yīng)的LED。同時(shí),對(duì)于不同的硬件電路,點(diǎn)亮LED對(duì)應(yīng)的GPIO輸出電平可能是不同的,可能是輸出低電平點(diǎn)亮LED,也可能是輸出高電平點(diǎn)亮LED,此外,不同硬件設(shè)備中,LED的數(shù)目也可能存在差異,這些都是與具體硬件相關(guān)的。

為了便于對(duì)這些信息進(jìn)行修改、配置,可以定義一個(gè)信息結(jié)構(gòu)體類(lèi)型,以包含所有需要由用戶提供的信息,即:

特別的,在部分平臺(tái)中,使用GPIO前,可能需要一些特殊的平臺(tái)相關(guān)的操作,比如:使能時(shí)鐘、申請(qǐng)GPIO的使用權(quán)、配置GPIO的特殊模式等。由于具體平臺(tái)相關(guān)的操作當(dāng)前并不能確定,為此,可以由用戶提供一個(gè)平臺(tái)初始化函數(shù),以在必要時(shí),通過(guò)該函數(shù)完成平臺(tái)相關(guān)的初始化操作。基于此,在設(shè)備信息類(lèi)型中新增一個(gè)函數(shù)指針成員,用以指向用戶提供的平臺(tái)初始化函數(shù),即:

新增的pfn_plfm_init是一個(gè)函數(shù)指針,指向的函數(shù)是無(wú)參數(shù)、無(wú)返回值的函數(shù),用于完成在使用LED前需要完成的平臺(tái)相關(guān)的初始化操作。在一些情況下,可能不需要執(zhí)行任何平臺(tái)相關(guān)的初始化操作,則可以將其值設(shè)置為NULL。

上面主要基于硬件層面定義了設(shè)備信息中的各個(gè)成員,此外,LED主要的功能是提供LED服務(wù),在LED服務(wù)中,需要提供的一個(gè)重要信息是LED服務(wù)信息,其主要包含了LED設(shè)備中各個(gè)LED的編號(hào)信息,LED服務(wù)信息的定義詳見(jiàn)程序清單13.28。

程序清單13.28 LED服務(wù)信息類(lèi)型定義

由此可見(jiàn),LED服務(wù)信息中包含了起始編號(hào)和結(jié)束編號(hào),用戶通過(guò)設(shè)定起始編號(hào)和結(jié)束編號(hào),就可以為設(shè)備中的每個(gè)LED分配一個(gè)唯一ID。為了存放用戶分配的ID信息,可以在設(shè)備信息類(lèi)型中新增一個(gè)LED服務(wù)信息成員,設(shè)備信息完整的定義詳見(jiàn)程序清單13.29。

程序清單13.29 LED設(shè)備信息類(lèi)型完整定義

在EPC-AW280開(kāi)發(fā)套件中,板載了兩個(gè)LED,標(biāo)識(shí)分別為RUN、Error,對(duì)應(yīng)的引腳分別為PIO2_6、PIO2_5,等效原理圖詳見(jiàn)圖13.2,由此可見(jiàn),當(dāng)GPIO輸出低電平時(shí),對(duì)應(yīng)的LED點(diǎn)亮,GPIO輸出高電平時(shí),對(duì)應(yīng)的LED熄滅。若為兩個(gè)LED分配的ID號(hào)分別為0、1,則在設(shè)備描述中,LED設(shè)備信息的定義范例詳見(jiàn)程序清單13.30。

圖13.2 板載LED電路

程序清單13.30 LED設(shè)備信息定義范例

13.3.5 實(shí)現(xiàn)三個(gè)階段的初始化函數(shù)

在一個(gè)設(shè)備使用前,需要完成設(shè)備相關(guān)的初始化操作,例如,對(duì)于LED驅(qū)動(dòng),可能需要將GPIO設(shè)置為輸出模式等。在基礎(chǔ)驅(qū)動(dòng)信息中,使用了驅(qū)動(dòng)入口點(diǎn)指定驅(qū)動(dòng)提供的初始化函數(shù),其結(jié)構(gòu)性代碼詳見(jiàn)程序清單13.21,共需實(shí)現(xiàn)3個(gè)初始化函數(shù),分別對(duì)應(yīng)3個(gè)階段。

需要特別注意的是,雖然各階段初始化函數(shù)的形參類(lèi)型均為awbl_dev_t *,但實(shí)際上,在系統(tǒng)調(diào)用各初始化函數(shù)時(shí),傳入形參p_dev的值為設(shè)備描述中p_dev的值,其本質(zhì)上指向了靜態(tài)定義的設(shè)備實(shí)例。對(duì)于GPIO控制型LED設(shè)備,其設(shè)備實(shí)例的實(shí)際類(lèi)型為struct awbl_led_gpio_dev(具體定義詳見(jiàn)程序清單13.27),在使用p_dev時(shí),可以將其強(qiáng)制轉(zhuǎn)換為指向?qū)嶋H設(shè)備實(shí)例的指針,以訪問(wèn)設(shè)備實(shí)例中的各個(gè)成員。范例程序詳見(jiàn)程序清單13.31。

程序清單13.31 將p_dev轉(zhuǎn)換為指向?qū)嶋H設(shè)備實(shí)例的指針

在初始化時(shí),往往還需要獲得用戶為設(shè)備提供的相關(guān)信息,AWBus-lite提供了通過(guò)p_dev獲取硬件設(shè)備描述的宏:AWBL_DEVHCF_GET(),其返回值即為const struct awbl_devhcf *類(lèi)型的指向硬件設(shè)備描述的指針,struct awbl_devhcf類(lèi)型的定義詳見(jiàn)程序清單12.2,其中包含了設(shè)備名、設(shè)備單元號(hào)、所處總線、設(shè)備信息等常見(jiàn)的信息,使用范例詳見(jiàn)程序清單13.32。

程序清單13.32 AWBL_DEVHCF_GET()宏的使用范例程序

程序中,只要獲得了設(shè)備描述,即可通過(guò)指針獲得設(shè)備描述中的其它成員信息,但通常情況下,可能只需要獲得設(shè)備描述中某一個(gè)成員的信息,此時(shí),為了簡(jiǎn)化獲取步驟,AWBus-lite提供了直接獲取設(shè)備描述中某一成員的輔助宏,詳見(jiàn)表13.5。

表13.5 獲取設(shè)備相關(guān)信息的輔助宏(awbus_lite.h)

特別地,在設(shè)備描述中,設(shè)備實(shí)例信息的類(lèi)型為const void *,而實(shí)際上,p_devinfo指向的是具體設(shè)備信息,對(duì)于GPIO控制型LED設(shè)備,其設(shè)備信息的實(shí)際類(lèi)型為

struct awbl_led_gpio_param(具體定義詳見(jiàn)程序清單13.29),因此,在使用設(shè)備實(shí)例信息時(shí),可以將其強(qiáng)制轉(zhuǎn)換為指向?qū)嶋H設(shè)備信息的指針,以便訪問(wèn)實(shí)際設(shè)備信息中的成員。例如:

1. 第一階段初始化函數(shù)實(shí)現(xiàn)

第一階段通常無(wú)需作任何操作,該階段對(duì)應(yīng)的始化函數(shù)往往為空,詳見(jiàn)程序清單13.33。

程序清單13.33 第一階段初始化函數(shù)實(shí)現(xiàn)范例

2. 第二階段初始化函數(shù)實(shí)現(xiàn)

第二階段為初始化設(shè)備的主要階段,可以在該階段中完成GPIO模式設(shè)置、初始電平設(shè)置等初始化相關(guān)操作,范例程序詳見(jiàn)程序清單13.34。

程序清單13.34 第二階段初始化函數(shù)實(shí)現(xiàn)范例

程序中,將所有LED對(duì)應(yīng)的引腳設(shè)置為了輸出模式,并將初始電平設(shè)置為了設(shè)備信息中active_low的值,以使LED初始處于熄滅狀態(tài)。例如,active_low的值為1,則表示引腳輸出低電平時(shí)點(diǎn)亮LED,而初始時(shí),將輸出電平設(shè)置為了

active_low的值,即高電平,從而熄滅了LED。為了更清楚的理解這個(gè)關(guān)系,可以列舉出active_low的值和GPIO輸出電平對(duì)LED狀態(tài)的影響,詳見(jiàn)表13.6。由此可見(jiàn),當(dāng)active_low的值和GPIO輸出電平相同時(shí),LED熄滅,否則,LED點(diǎn)亮。因此,初始時(shí),將GPIO輸出電平設(shè)置為active_low的值,確保了LED初始處于熄滅狀態(tài)。

表13.6 LED狀態(tài)的影響因素

3. 第三階段初始化函數(shù)實(shí)現(xiàn)

第三階段通常用于耗時(shí)較長(zhǎng)的初始化操作,由于LED設(shè)備初始化中,并沒(méi)有任何比較復(fù)雜、耗時(shí)的操作,因此,第三階段無(wú)需作任務(wù)處理,設(shè)定為空即可,詳見(jiàn)程序清單13.35。

程序清單13.35 第三階段初始化函數(shù)實(shí)現(xiàn)范例

實(shí)現(xiàn)了各階段初始化函數(shù)后,可以定義一個(gè)struct awbl_drvfuncs類(lèi)型的常量,以將所有初始化函數(shù)整合在一起,作為基礎(chǔ)驅(qū)動(dòng)信息中驅(qū)動(dòng)入口點(diǎn)的值。詳見(jiàn)程序清單13.36。

程序清單13.36 定義struct awbl_drvfuncs類(lèi)型的常量

其中,__g_awbl_drvfuncs_led_gpio即可作為驅(qū)動(dòng)入口點(diǎn)p_busfuncs的值。

為了簡(jiǎn)化程序,可以在定義

struct awbl_drvfuncs類(lèi)型的常量時(shí),將空函數(shù)對(duì)應(yīng)的指針直接設(shè)定為NULL。例如,在程序清單13.36中,由于第一階段和第三階段對(duì)應(yīng)的初始化函數(shù)是空函數(shù),沒(méi)有作任何操作,因此,可以將pfunc_dev_init1和pfunc_dev_connect的值設(shè)置為NULL,更新后的struct awbl_drvfuncs類(lèi)型常量定義詳見(jiàn)程序清單13.37。

程序清單13.37 更新struct awbl_drvfuncs類(lèi)型的常量定義

13.3.6 實(shí)現(xiàn)LED服務(wù)

LED設(shè)備的主要功能是為系統(tǒng)提供LED服務(wù),在向系統(tǒng)提供LED服務(wù)前,需要實(shí)現(xiàn)一個(gè)LED服務(wù),回顧LED服務(wù)類(lèi)型的定義,詳見(jiàn)程序清單13.38。

程序清單13.38 LED服務(wù)類(lèi)型定義(awbl_led.h)

在LED設(shè)備實(shí)例中,具有一個(gè)

struct awbl_led_service 類(lèi)型的led_serv成員(詳見(jiàn)程序清單13.27)。實(shí)現(xiàn)LED服務(wù)的核心工作就是完成led_serv中各成員的賦值。

1. p_next成員賦值

在LED服務(wù)中,p_next用于系統(tǒng)組織多個(gè)LED服務(wù),使它們以鏈表的形式串接起來(lái),便于統(tǒng)一管理。對(duì)于單個(gè)LED設(shè)備來(lái)講,其僅能提供一個(gè)LED服務(wù),p_next的值設(shè)置應(yīng)設(shè)置為NULL。設(shè)置范例詳見(jiàn)程序清單13.39。

程序清單13.39 LED服務(wù)中p_next成員賦值范例

2. p_servinfo成員賦值

在LED服務(wù)中,p_servinfo用于指向LED服務(wù)信息,通過(guò)LED設(shè)備信息類(lèi)型的定義可知,LED服務(wù)信息由用戶提供,因此,只需將p_servinfo指向設(shè)備信息中的LED服務(wù)信息,設(shè)置范例詳見(jiàn)程序清單13.40。

程序清單13.40 LED服務(wù)中p_servinfo成員賦值范例

3. p_servfuncs成員賦值

為了屏蔽底層硬件的差異性,系統(tǒng)為L(zhǎng)ED設(shè)備定義了兩個(gè)抽象方法,回顧

struct awbl_led_servfuncs類(lèi)型的定義,詳見(jiàn)程序清單13.41。

程序清單13.41 struct awbl_led_servfuncs類(lèi)型的定義(awbl_led.h)

在LED服務(wù)中,p_servfuncs即為指向各抽象方法的具體實(shí)現(xiàn)列表。為了完成p_servfuncs成員的賦值,首先需要實(shí)現(xiàn)操作LED設(shè)備的的兩個(gè)抽象方法,然后將它們整合到一個(gè)

struct awbl_led_servfuncs類(lèi)型的結(jié)構(gòu)體常量中,抽象方法的實(shí)現(xiàn)詳見(jiàn)程序清單13.42。

程序清單13.42 LED抽象方法的實(shí)現(xiàn)

在各個(gè)抽象方法的實(shí)現(xiàn)中,都將參數(shù)p_cookie直接視為了指向設(shè)備的指針,為了便于使用,將p_cookie的類(lèi)型從void *強(qiáng)制轉(zhuǎn)換為了struct awbl_led_gpio_dev *。實(shí)際中,p_cookie的值是由驅(qū)動(dòng)自身決定的,在下一小節(jié)p_cookie成員的賦值中將作進(jìn)一步介紹。

各函數(shù)完成的主要功能是根據(jù)需要控制LED對(duì)應(yīng)引腳的輸出電平,主要分為兩個(gè)步驟:根據(jù)LED的ID得到引腳索引;通過(guò)引腳索引,控制相應(yīng)引腳的輸出電平。

LED對(duì)應(yīng)的引腳在設(shè)備信息的引腳數(shù)組中,數(shù)組的起始索引為0,但LED的ID是從LED服務(wù)信息中指定的起始編號(hào)開(kāi)始的,為了通過(guò)LED的ID獲得其對(duì)應(yīng)引腳在數(shù)組中的索引,應(yīng)使用ID號(hào)減去起始編號(hào),即:

在__led_gpio_set()函數(shù)的實(shí)現(xiàn)中,其需要根據(jù)參數(shù)on的值決定是否點(diǎn)亮LED,點(diǎn)亮LED的電平與設(shè)備信息中的active_low有關(guān), 為了更清楚的理解這個(gè)關(guān)系,可以列舉出參數(shù)on和active_low的值對(duì)GPIO輸出電平的影響,詳見(jiàn)表13.7。例如,當(dāng)active_low為0時(shí),表示GPIO輸出高電平時(shí)點(diǎn)亮LED,此時(shí),若on為1,表示需要點(diǎn)亮LED,則GPIO應(yīng)輸出高電平;若on為0,表示需要熄滅LED,則GPIO應(yīng)輸出低電平。

表13.7 GPIO輸出與active_low和on值的關(guān)系

由此可見(jiàn),當(dāng)active_low和on相同時(shí),GPIO應(yīng)該輸出“0”,而當(dāng)active_low和on值不同時(shí),GPIO應(yīng)輸出“1”。即:“相同為0,相異為1”,這恰好是一種異或關(guān)系,因此,在設(shè)置GPIO輸出電平時(shí),直接將active_low和on的異或值作為GPIO的輸出電平,即:

在__led_gpio_toggle()函數(shù)的實(shí)現(xiàn)中,僅需翻轉(zhuǎn)GPIO輸出電平接口,與設(shè)備信息中active_low的值無(wú)關(guān),即:

至此,實(shí)現(xiàn)了LED服務(wù)中的兩個(gè)抽象方法,并存放在了__g_led_servfuncs常量中,該常量的地址即可直接作為L(zhǎng)ED服務(wù)中p_servfuncs的值,詳見(jiàn)程序清單13.43。

程序清單13.43 p_servfuncs成員的賦值

4. p_cookie成員賦值

在LED服務(wù)中,p_cookie用于系統(tǒng)在調(diào)用設(shè)備實(shí)現(xiàn)的抽象方法時(shí),“原封不動(dòng)”的傳遞給各個(gè)抽象方法的p_cookie參數(shù)。這樣一來(lái),傳入抽象方法中的p_cookie與LED服務(wù)中的p_cookie是完全相同的,換句話說(shuō),驅(qū)動(dòng)為L(zhǎng)ED服務(wù)中的p_cookie設(shè)置了什么值,那么,在系統(tǒng)通過(guò)LED服務(wù)調(diào)用驅(qū)動(dòng)實(shí)現(xiàn)的抽象方法時(shí),傳入p_cookie參數(shù)的值也為該值。

通常情況下,p_cookie都起到一個(gè)p_this的作用,用于指向設(shè)備自身,為此,直接將LED服務(wù)中p_cookie的設(shè)置為p_this,詳見(jiàn)程序清單13.44。

程序清單13.44 p_cookie成員的賦值

也正因?yàn)槿绱耍诔绦蚯鍐?3.42所示的LED抽象方法的實(shí)現(xiàn)中,可以直接將p_cookie強(qiáng)制轉(zhuǎn)換為指向設(shè)備自身的指針。

至此,清楚了LED服務(wù)中各成員應(yīng)該設(shè)置的具體值,可以選擇在初始化函數(shù)中完成各成員的賦值,比如將相關(guān)的賦值語(yǔ)句添加到第二階段初始化函數(shù)中。也可以選擇在系統(tǒng)獲取LED服務(wù)時(shí),再進(jìn)行相關(guān)成員的賦值。顯然,在系統(tǒng)獲取LED服務(wù)時(shí)再進(jìn)行相關(guān)成員的賦值,這種方式更優(yōu),因?yàn)槿粝到y(tǒng)不獲取LED服務(wù),那么就不會(huì)進(jìn)行相關(guān)成員的賦值,避免了不必要的操作,下面將對(duì)這種方法作進(jìn)一步介紹。

13.3.7 定義Method對(duì)象

通過(guò)前面對(duì)Method機(jī)制的介紹可知,為了使LED設(shè)備可以向系統(tǒng)提供LED服務(wù),需要定義Method對(duì)象,一個(gè)Method對(duì)象由Method類(lèi)型標(biāo)識(shí)和一個(gè)入口函數(shù)構(gòu)成。已知獲取LED服務(wù)的Method類(lèi)型為:awbl_ledserv_get。因此,定義Method對(duì)象的關(guān)鍵在于實(shí)現(xiàn)一個(gè)用于系統(tǒng)獲取LED服務(wù)的入口函數(shù),范例程序詳見(jiàn)程序清單13.45。

程序清單13.45 獲取LED服務(wù)的入口函數(shù)實(shí)現(xiàn)范例

基于此,可以完成一個(gè)Method對(duì)象的定義,即:

為了便于管理,一個(gè)驅(qū)動(dòng)提供的所有Method對(duì)象應(yīng)該存放在一個(gè)列表中,由于LED設(shè)備僅能提供LED服務(wù),因此,Method對(duì)象列表中僅包含一個(gè)用于獲取LED服務(wù)的Method對(duì)象,詳見(jiàn)程序清單13.46。

程序清單13.46 LED設(shè)備驅(qū)動(dòng)Method對(duì)象列表定義

其中,__g_led_gpio_dev_methods即可作為基礎(chǔ)驅(qū)動(dòng)信息中p_methods的值。

13.3.8 注冊(cè)驅(qū)動(dòng)

通過(guò)前面的介紹,LED設(shè)備驅(qū)動(dòng)相關(guān)的函數(shù)均已實(shí)現(xiàn),驅(qū)動(dòng)已經(jīng)基本開(kāi)發(fā)完成,基于此,可以按照AWbus-lite的定義,使用相應(yīng)驅(qū)動(dòng)信息結(jié)構(gòu)體類(lèi)型完成一個(gè)驅(qū)動(dòng)信息的定義,用于完整的描述LED驅(qū)動(dòng)。

由GPIO直接控制的LED設(shè)備掛在PLB總線上,PLB總線上的所有設(shè)備驅(qū)動(dòng)對(duì)應(yīng)的信息結(jié)構(gòu)體類(lèi)型為awbl_plb_drvinfo_t,其是直接從基礎(chǔ)驅(qū)動(dòng)信息類(lèi)型派生而來(lái)的,其定義詳見(jiàn)程序清單13.47。

程序清單13.47 awbl_plb_drvinfo_t類(lèi)型定義(awbl_plb.h)

由此可見(jiàn),其并未擴(kuò)展任何其它新的成員,和基礎(chǔ)驅(qū)動(dòng)信息是完全一樣的,可以定義用于描述LED驅(qū)動(dòng)的信息常量,詳見(jiàn)程序清單13.48。

程序清單13.48 定義描述LED驅(qū)動(dòng)的信息常量

完成描述驅(qū)動(dòng)的信息常量定義后,還需要將驅(qū)動(dòng)注冊(cè)到系統(tǒng)中,以便被系統(tǒng)中相應(yīng)的設(shè)備所使用,AWBus-lite提供了驅(qū)動(dòng)注冊(cè)函數(shù),用于向系統(tǒng)中注冊(cè)一個(gè)驅(qū)動(dòng),其函數(shù)原型為:

其中,p_drvinfo指向待注冊(cè)的驅(qū)動(dòng)信息,返回值為標(biāo)準(zhǔn)的錯(cuò)誤號(hào),若返回AW_OK,則表示驅(qū)動(dòng)注冊(cè)成功;若返回-AW_ENOSPC,則表示內(nèi)存空間不足,驅(qū)動(dòng)注冊(cè)失?。蝗舴祷?AW_ENOTSUP,則表示AWbus-lite不支持該驅(qū)動(dòng)的版本,往往是由于驅(qū)動(dòng)信息中的awb_ver版本號(hào)設(shè)置有誤引起的。例如,注冊(cè)LED驅(qū)動(dòng)的范例程序詳見(jiàn)程序清單13.49。

程序清單13.49 注冊(cè)LED驅(qū)動(dòng)范例程序

由于__g_drvinfo_led_gpio的類(lèi)型是從基礎(chǔ)驅(qū)動(dòng)信息類(lèi)型派生而來(lái)的,兩者類(lèi)型并不完全相同,為了避免警告,可以將__g_drvinfo_led_gpio的地址轉(zhuǎn)換為struct awbl_drvinfo *類(lèi)型。

顯然,是否注冊(cè)驅(qū)動(dòng)應(yīng)該是由用戶決定的,只有當(dāng)需要使用某一設(shè)備時(shí),才應(yīng)將相應(yīng)的驅(qū)動(dòng)注冊(cè)到系統(tǒng)中。為了使用戶可以在需要使用LED驅(qū)動(dòng)時(shí)再注冊(cè)驅(qū)動(dòng),比較容易想到的方法可能是將__g_drvinfo_led_gpio作為一個(gè)對(duì)外開(kāi)放的全局變量,引出到驅(qū)動(dòng)文件外部,當(dāng)用戶需要使用LED驅(qū)動(dòng)時(shí),再使用程序清單13.49所示的程序進(jìn)行注冊(cè)。但是,__g_drvinfo_led_gpio作為一個(gè)結(jié)構(gòu)體常量,可以看作驅(qū)動(dòng)的一個(gè)數(shù)據(jù),在面向?qū)ο蟮木幊讨校鳛橐环N良好的編程習(xí)慣,應(yīng)該盡可能避免將數(shù)據(jù)直接引出到對(duì)象外部供其它模塊使用,對(duì)數(shù)據(jù)的操作都應(yīng)該通過(guò)相關(guān)的接口實(shí)現(xiàn)。將過(guò)多的數(shù)據(jù)作為全局變量引出到文件外部,將嚴(yán)重破壞系統(tǒng)的可維護(hù)性。同時(shí),對(duì)于用戶來(lái)說(shuō),其并不需要訪問(wèn)驅(qū)動(dòng)信息中的相關(guān)成員,將整個(gè)驅(qū)動(dòng)信息開(kāi)放給用戶也是不必要的。

由于驅(qū)動(dòng)信息僅用于在注冊(cè)驅(qū)動(dòng)時(shí)使用,為此,可以提供一個(gè)用于注冊(cè)LED驅(qū)動(dòng)的專(zhuān)用函數(shù),其實(shí)現(xiàn)詳見(jiàn)程序清單13.50。

程序清單13.50 注冊(cè)LED驅(qū)動(dòng)的專(zhuān)用函數(shù)

如此一來(lái),驅(qū)動(dòng)信息僅在內(nèi)部被訪問(wèn),做到了很好的“封裝”。當(dāng)用戶需要使用LED驅(qū)動(dòng)時(shí),直接調(diào)用awbl_led_gpio_drv_register()函數(shù)即可。

通常情況下,并不需要由用戶手動(dòng)調(diào)用該函數(shù),而是將該函數(shù)的調(diào)用放在模板工程下的

aw_prj_config.c文件中,具體位于

awbl_group_init()函數(shù)中,該函數(shù)在系統(tǒng)啟動(dòng)時(shí)會(huì)被自動(dòng)調(diào)用,從而使系統(tǒng)在啟動(dòng)時(shí)自動(dòng)調(diào)用awbl_led_gpio_drv_register()函數(shù)完成驅(qū)動(dòng)的注冊(cè),詳見(jiàn)程序清單13.51。

程序清單13.51 系統(tǒng)啟動(dòng)時(shí)自動(dòng)注冊(cè)驅(qū)動(dòng)的原理

由此可見(jiàn),用戶可以通過(guò)是否定義

AW_DRV_AWBL_GPIO_LED宏來(lái)確定是否注冊(cè)LED驅(qū)動(dòng),在aw_prj_params.h工程配置文件中,只要使能了LED設(shè)備,即定義了AW_DEV_GPIO_LED宏,則表示要使用GPIO驅(qū)動(dòng)型LED,此時(shí),將自動(dòng)完成

AW_DRV_AWBL_GPIO_LED的定義,以此確保當(dāng)使用LED時(shí),相應(yīng)驅(qū)動(dòng)會(huì)在系統(tǒng)啟動(dòng)過(guò)程中被自動(dòng)注冊(cè)。核心的原理性程序詳見(jiàn)程序清單13.52。

程序清單13.52 自動(dòng)定義AW_DRV_AWBL_GPIO_LED宏的原理(aw_prj_params.h)

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 設(shè)備驅(qū)動(dòng)

    關(guān)注

    0

    文章

    67

    瀏覽量

    10869
  • 致遠(yuǎn)電子
    +關(guān)注

    關(guān)注

    13

    文章

    403

    瀏覽量

    31246
  • AWorks
    +關(guān)注

    關(guān)注

    1

    文章

    16

    瀏覽量

    5673

原文標(biāo)題:AWorks軟件篇 — 深入理解 AWbus-lite(設(shè)備驅(qū)動(dòng)基礎(chǔ)概念)

文章出處:【微信號(hào):ZLG_zhiyuan,微信公眾號(hào):ZLG致遠(yuǎn)電子】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    AWBus-lite的拓?fù)浣Y(jié)構(gòu)及應(yīng)用設(shè)計(jì)

    為了管理系統(tǒng)各式各樣的硬件設(shè)備(或虛擬硬件設(shè)備),AWorks推出了領(lǐng)先的輕量級(jí)總線管理框架:AWBus-lite,實(shí)現(xiàn)了硬件設(shè)備
    的頭像 發(fā)表于 06-21 09:10 ?5828次閱讀
    <b class='flag-5'>AWBus-lite</b>的拓?fù)浣Y(jié)構(gòu)及應(yīng)用設(shè)計(jì)

    AWorks如何編寫(xiě)開(kāi)發(fā)設(shè)備驅(qū)動(dòng)程序

    本文詳細(xì)介紹了AWorks開(kāi)發(fā)設(shè)備驅(qū)動(dòng)的一般方法?;谶@些通用的方法,用戶可以嘗試獨(dú)立開(kāi)發(fā)一些設(shè)備驅(qū)動(dòng),以進(jìn)一步加深對(duì)
    的頭像 發(fā)表于 06-20 09:58 ?8610次閱讀
    AWorks如何編寫(xiě)開(kāi)發(fā)<b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動(dòng)</b>程序

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

    使用AWBus-lite對(duì)設(shè)備進(jìn)行管理時(shí),無(wú)論設(shè)備處于 AWBus-lite拓?fù)浣Y(jié)構(gòu)的哪個(gè)位
    的頭像 發(fā)表于 07-23 09:08 ?8271次閱讀
    從接口定義和實(shí)現(xiàn)兩個(gè)方面,深入理解<b class='flag-5'>AWbus-lite</b>

    Linux平臺(tái)設(shè)備框架驅(qū)動(dòng)

    ? 平臺(tái)設(shè)備框架(platform)是將一個(gè)驅(qū)動(dòng)分為設(shè)備層和驅(qū)動(dòng)層兩個(gè)部分,通過(guò)總線模型將設(shè)備驅(qū)動(dòng)
    的頭像 發(fā)表于 09-25 08:59 ?1696次閱讀
    Linux平臺(tái)<b class='flag-5'>設(shè)備</b>框架<b class='flag-5'>驅(qū)動(dòng)</b>

    AWorks開(kāi)發(fā)設(shè)備驅(qū)動(dòng)一般方法

    本文詳細(xì)介紹了AWorks開(kāi)發(fā)設(shè)備驅(qū)動(dòng)的一般方法?;谶@些通用的方法,用戶可以嘗試獨(dú)立開(kāi)發(fā)一些設(shè)備驅(qū)動(dòng),以進(jìn)一步加深對(duì)
    的頭像 發(fā)表于 06-11 08:59 ?4516次閱讀
    AWorks<b class='flag-5'>中</b>開(kāi)發(fā)<b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動(dòng)</b>一般方法

    Linux設(shè)備驅(qū)動(dòng)程序開(kāi)發(fā) - Linux設(shè)備驅(qū)動(dòng)類(lèi)型

    驅(qū)動(dòng)程序Linux的內(nèi)核源代碼占有很大的比例,源代碼的長(zhǎng)度日益增加,主要是驅(qū)動(dòng)程序的增加。Linux內(nèi)核的不斷升級(jí)過(guò)程
    發(fā)表于 04-16 14:31

    字符設(shè)備驅(qū)動(dòng) —— 字符設(shè)備驅(qū)動(dòng)框架

    設(shè)備驅(qū)動(dòng),這些函數(shù)集中file_operations結(jié)構(gòu)體。當(dāng)應(yīng)用程序使用系統(tǒng)調(diào)用read、write等函數(shù)訪問(wèn)設(shè)備時(shí),最終會(huì)調(diào)用到fi
    發(fā)表于 10-19 17:08

    Linux設(shè)備驅(qū)動(dòng)開(kāi)發(fā)之設(shè)備驅(qū)動(dòng)簡(jiǎn)述

    是操作系統(tǒng)最基本的功能,并且提供統(tǒng)一的操作方式。設(shè)備驅(qū)動(dòng)程序是內(nèi)核的一部分,硬件驅(qū)動(dòng)程序是操作系統(tǒng)最基本的組成部分,Linux內(nèi)核源程序
    發(fā)表于 10-18 16:44 ?0次下載

    《Linux設(shè)備驅(qū)動(dòng)開(kāi)發(fā)詳解》第9章、Linux設(shè)備驅(qū)動(dòng)的異步通知與異步IO

    《Linux設(shè)備驅(qū)動(dòng)開(kāi)發(fā)詳解》第9章、Linux設(shè)備驅(qū)動(dòng)的異步通知與異步IO
    發(fā)表于 10-27 11:33 ?0次下載
    《Linux<b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動(dòng)</b>開(kāi)發(fā)詳解》第9章、Linux<b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>中</b>的異步通知與異步IO

    《Linux設(shè)備驅(qū)動(dòng)開(kāi)發(fā)詳解》第8章、Linux設(shè)備驅(qū)動(dòng)的阻塞與非阻塞IO

    《Linux設(shè)備驅(qū)動(dòng)開(kāi)發(fā)詳解》第8章、Linux設(shè)備驅(qū)動(dòng)的阻塞與非阻塞IO
    發(fā)表于 10-27 11:35 ?9次下載
    《Linux<b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動(dòng)</b>開(kāi)發(fā)詳解》第8章、Linux<b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>中</b>的阻塞與非阻塞IO

    《Linux設(shè)備驅(qū)動(dòng)開(kāi)發(fā)詳解》第7章、Linux設(shè)備驅(qū)動(dòng)的并發(fā)控制

    《Linux設(shè)備驅(qū)動(dòng)開(kāi)發(fā)詳解》第7章、Linux設(shè)備驅(qū)動(dòng)的并發(fā)控制
    發(fā)表于 10-27 11:37 ?10次下載
    《Linux<b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動(dòng)</b>開(kāi)發(fā)詳解》第7章、Linux<b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>中</b>的并發(fā)控制

    Linux總線、設(shè)備、驅(qū)動(dòng)是如何關(guān)聯(lián)的?

    對(duì)于 Linux 驅(qū)動(dòng)開(kāi)發(fā)來(lái)說(shuō),設(shè)備模型的理解是根本,顧名思義設(shè)備模型是關(guān)于設(shè)備的模型,設(shè)備的概念就是總線和與其相連的各種
    發(fā)表于 11-27 01:21 ?3229次閱讀

    基于AWBus-lite總線拓?fù)浣Y(jié)構(gòu)的設(shè)備管理框架

    使用AWBus-lite對(duì)設(shè)備進(jìn)行管理時(shí),無(wú)論設(shè)備處于 AWBus-lite拓?fù)浣Y(jié)構(gòu)的哪個(gè)位
    的頭像 發(fā)表于 07-02 09:20 ?5264次閱讀
    基于<b class='flag-5'>AWBus-lite</b>總線拓?fù)浣Y(jié)構(gòu)的<b class='flag-5'>設(shè)備</b>管理框架

    labview怎么添加設(shè)備驅(qū)動(dòng)

    添加設(shè)備驅(qū)動(dòng)是使用LabVIEW進(jìn)行設(shè)備控制和數(shù)據(jù)采集的關(guān)鍵步驟之一。本文將向您介紹如何在LabVIEW添加設(shè)備
    的頭像 發(fā)表于 01-02 16:10 ?1990次閱讀

    總線上的音頻設(shè)備驅(qū)動(dòng)怎么安裝

    安裝總線上的音頻設(shè)備驅(qū)動(dòng)是確保計(jì)算機(jī)聲音正常工作的關(guān)鍵步驟。本文將從安裝的必要性和步驟、常見(jiàn)問(wèn)題和解決方法以及一些技巧方面詳細(xì)介紹總線上音頻設(shè)備
    的頭像 發(fā)表于 01-24 13:44 ?865次閱讀