本文導(dǎo)讀
為了管理系統(tǒng)中各式各樣的硬件設(shè)備(或虛擬硬件設(shè)備),AWorks推出了領(lǐng)先的輕量級(jí)總線管理框架:AWBus-lite,實(shí)現(xiàn)了硬件設(shè)備和驅(qū)動(dòng)的徹底分離,使設(shè)備驅(qū)動(dòng)可以最大限度的得到復(fù)用。本文介紹了AWBus-lite的基礎(chǔ)概念,以及如何使用和配置AWbus-lite。
本文為《面向AWorks框架和接口的編程》第三部分軟件篇——第12章AWBus-lite總線框架——第1~4小節(jié):AWBus-lite簡(jiǎn)介、AWBus-lite拓?fù)浣Y(jié)構(gòu)、系統(tǒng)硬件資源和訪問設(shè)備。本章導(dǎo)讀
在嵌入式系統(tǒng)中,硬件外設(shè)的種類非常繁多,例如,GPIO、ADC、UART、按鍵、數(shù)碼管、RTC、LM75、EEPROM、SD卡、U盤等。正確使用各個(gè)外設(shè)的基礎(chǔ)是平臺(tái)中具有相應(yīng)的驅(qū)動(dòng),隨著外設(shè)種類的不斷增加,驅(qū)動(dòng)也隨之越來越多,為了高效的管理眾多的外設(shè)和驅(qū)動(dòng),AWorks推出了領(lǐng)先的輕量級(jí)總線管理框架:AWBus-lite。AWBus-lite作為AWorks中最重要的組件之一,負(fù)責(zé)管理系統(tǒng)中所有的硬件設(shè)備(或虛擬硬件設(shè)備),實(shí)現(xiàn)硬件外設(shè)和驅(qū)動(dòng)的分離,使驅(qū)動(dòng)可以最大限度的得到復(fù)用。
本章作為AWBus-lite的入門,主要介紹了AWBus-lite的拓?fù)浣Y(jié)構(gòu),以及基本的設(shè)備、總線、驅(qū)動(dòng)相關(guān)的概念,重點(diǎn)從用戶角度出發(fā),講述如何使用、配置AWBus-lite。
12.1 AWBus-lite簡(jiǎn)介
隨著MCU的快速發(fā)展,越來越多的硬件外設(shè)集成到了MCU內(nèi)部(片內(nèi)外設(shè)),這部分外設(shè)可以直接通過CPU操作相應(yīng)的寄存器使用,例如,i.MX28x中的GPIO、ADC、UART等。一些外設(shè)在MCU外部(片外外設(shè)),必須通過某種總線進(jìn)行訪問,比如PCF85063,需要通過I2C總線訪問;SD卡,需要通過SDIO總線訪問。
為了使用統(tǒng)一的拓?fù)浣Y(jié)構(gòu)描述所有的片外和片內(nèi)外設(shè),在AWBus-lite中,把CPU直接控制的總線統(tǒng)稱為PLB(Processor Local Bus,CPU本地總線),集成在MCU內(nèi)部的外設(shè)就掛在該總線上。例如:在一個(gè)系統(tǒng)中,硬件設(shè)備連接示意圖詳見圖12.1(a),其對(duì)應(yīng)的AWBus-lite軟件拓?fù)浣Y(jié)構(gòu)詳見圖12.1(b)。
圖12.1 AWBus-lite抽象
AWBus-lite提供了一種機(jī)制,使得我們可以在軟件環(huán)境里建立、還原系統(tǒng)的硬件總線拓?fù)浣Y(jié)構(gòu)。如圖12.1所示,圖12.1(a)為一個(gè)可能的系統(tǒng)總線的物理拓?fù)浣Y(jié)構(gòu)(僅作示例之用),圖12.1(b)為在AWBus-lite中抽象出來的系統(tǒng)總線模型。由此可見,在軟件中抽象出來的對(duì)象同真實(shí)世界的對(duì)象一一對(duì)應(yīng)!
圖12.1(a)僅作為一種示例,與實(shí)際硬件可能存在差異。整個(gè)硬件被分為了核心板(i.MX28xPack board)和用戶板(User Board)兩部分。核心板又分為MCU(i.MX28x)和外圍器件(ICs)兩個(gè)部分,MCU又分為內(nèi)核(ARM)和片內(nèi)外設(shè)兩個(gè)部分。
內(nèi)核的核心是CPU,其可以直接控制片上外設(shè),這里虛擬了一個(gè)PLB控制器,其產(chǎn)生了一條PLB總線,由CPU直接控制,片內(nèi)外設(shè)均直接掛在PLB總線上。
片內(nèi)外設(shè)集成在芯片內(nèi)部,例如,GPIO、I2C、UART等,它們掛在PLB總線上。其中部分片內(nèi)外設(shè)又是總線控制器(比如I2C),它們又可以擴(kuò)展出一條總線到片外,例如,I2C0擴(kuò)展出一條總線I2C bus 0,I2C1擴(kuò)展出一條總線II2C bus 1。擴(kuò)展的總線可以連接一些外圍器件。
這些器件可能處于核心板中,比如
SC18IS602B(一款I2C轉(zhuǎn)SPI芯片,僅用作拓?fù)浣Y(jié)構(gòu)展示,無(wú)需深入了解)、
CAT24C02(EEPROM)、PCF85063(RTC芯片),也可能處于用戶板上,比如CAT9555(一款I2C轉(zhuǎn)GPIO芯片,僅用作拓?fù)浣Y(jié)構(gòu)展示,無(wú)需深入了解)。
一些外圍器件可能又是總線控制器,則其又可以擴(kuò)展出一條總線,比如SC18IS602B,其為I2C轉(zhuǎn)SPI芯片,可以擴(kuò)展出SPI總線,在SPI總線上,又可以掛在其它SPI接口的器件,比如:SC16IS752(一款SPI轉(zhuǎn)UART芯片,僅用作拓?fù)浣Y(jié)構(gòu)展示,用戶無(wú)需了解具體細(xì)節(jié))。特別地,若連接的芯片又是一個(gè)總線控制器,則可以繼續(xù)擴(kuò)展總線,從理論上講,通過添加總線控制器,可以將系統(tǒng)的總線層次無(wú)限地增加,即系統(tǒng)的功能外設(shè)可無(wú)限擴(kuò)展。
圖12.1(b)為對(duì)應(yīng)的軟件拓?fù)浣Y(jié)構(gòu)圖,在軟件環(huán)境中,外設(shè)對(duì)象與真實(shí)硬件設(shè)備呈一一對(duì)應(yīng)關(guān)系。不過,軟件環(huán)境中并不區(qū)分設(shè)備的物理位置,只考慮設(shè)備的父總線,比如CAT9555(用戶板上)和PCF85063(核心板上)都是掛在I2C bus 1上的,則它們處于同一個(gè)層級(jí)。
12.2 AWBus-lite拓?fù)浣Y(jié)構(gòu)
在圖12.1中,以一個(gè)具體的示例說明了AWbus-lite的基本結(jié)構(gòu),展示了AWBus-Lite對(duì)現(xiàn)實(shí)世界的一種抽象。從具體到一般,一個(gè)更加抽象的總線拓?fù)浣Y(jié)構(gòu)詳見圖12.2。
圖12.2 AWBus-lite總線拓?fù)浣Y(jié)構(gòu)圖
其中,Bus Controller 0是由CPU直接控制的總線控制器,通常情況下,其為PLBController,以擴(kuò)展出一條PLB總線。在總線拓?fù)浣Y(jié)構(gòu)圖中,抽象了3個(gè)重要的概念:設(shè)備、總線控制器、總線。
-
設(shè)備
設(shè)備是指掛在某條總線上的硬件外設(shè)(或虛擬外設(shè))。例如,圖12.1中的GPIO、CAT24C02、CAT9555等。
-
總線控制器
總線控制器是一種特殊的設(shè)備,它可以擴(kuò)展出一條下游總線,這條總線上又能掛其它設(shè)備(包括總線控制器)。例如,圖12.1中的I2C0、SC18IS602B等。
-
總線
任何設(shè)備或總線控制器都必須掛在一條總線上。AWBus-lite不區(qū)分CPU的具體類型,把CPU直接控制的總線統(tǒng)稱為 PLB,PLB為根總線。其它總線由總線控制器產(chǎn)生,例如,圖12.1中的I2C Bus 0、I2C Bus 1、SPI Bus等。
“設(shè)備”是最為核心的概念,其它概念都可以基于“設(shè)備”進(jìn)行描述:“設(shè)備”掛在“總線”上,特殊“設(shè)備”(總線控制器設(shè)備)擴(kuò)展出一條下游總線。能夠正常使用一個(gè)設(shè)備的前提是系統(tǒng)中具有設(shè)備相應(yīng)的驅(qū)動(dòng),例如,要使用i.MX28x的GPIO去控制一個(gè)LED,就必須具有相應(yīng)的GPIO驅(qū)動(dòng),以設(shè)置GPIO的模式、輸出電平等,最終達(dá)到控制LED的目的。也就是說,要使系統(tǒng)具有訪問和控制設(shè)備的能力,就必須具有相應(yīng)的驅(qū)動(dòng)。這就需要掌握另外一個(gè)非常重要的概念:設(shè)備驅(qū)動(dòng)。
設(shè)備驅(qū)動(dòng)提供了訪問和控制設(shè)備(包括特殊的設(shè)備:總線控制器)的能力,在AWBus-lite中,將設(shè)備和驅(qū)動(dòng)進(jìn)行了很好的分離,使驅(qū)動(dòng)可以最大限度的得到復(fù)用。通常情況下,系統(tǒng)中可能存在多個(gè)相同類型的設(shè)備。例如,在i.MX28x中,存在I2C0和I2C1共計(jì)兩個(gè)I2C總線控制器,它們的操作方法是完全相同的,這種情況下,I2C0和I2C1設(shè)備即可復(fù)用一份驅(qū)動(dòng)。示意圖詳見圖12.3。
圖12.3I2C0和I2C1復(fù)用同一份驅(qū)動(dòng)
其它片上外設(shè)或外圍器件同樣如此,多個(gè)同類型的設(shè)備可以復(fù)用一份驅(qū)動(dòng),這不僅極大的提高了代碼復(fù)用率,縮小了程序占用的存儲(chǔ)空間,也給代碼的管理、維護(hù)、擴(kuò)展帶來了極大的便利。這是面向?qū)ο缶幊處淼暮锰帲谶@里,設(shè)備驅(qū)動(dòng)就相當(dāng)于一個(gè)類,而設(shè)備就是類的一個(gè)實(shí)例。
12.3 系統(tǒng)硬件資源
在開發(fā)實(shí)際應(yīng)用程序前,首先要規(guī)劃系統(tǒng)的硬件資源,即要構(gòu)建出如圖12.1(a)所示的硬件物理拓?fù)浣Y(jié)構(gòu)。接下來,就需要對(duì)系統(tǒng)軟件進(jìn)行配置,添加相應(yīng)的設(shè)備,以搭建出與之對(duì)應(yīng)的如圖12.1(b)所示的軟件拓?fù)浣Y(jié)構(gòu)。通常情況下,AWorks SDK提供的工程模板已經(jīng)配置好了系統(tǒng)相應(yīng)的硬件資源,完成了基礎(chǔ)軟件拓?fù)浣Y(jié)構(gòu)的搭建,對(duì)于不同的用戶需求,可能需要添加或刪除一些設(shè)備,這種情況下,可以直接在模板工程的基礎(chǔ)上對(duì)系統(tǒng)硬件資源進(jìn)行簡(jiǎn)要的調(diào)整。
12.3.1 硬件設(shè)備列表
AWBus-lite使用名為
awbus_lite_hwconf_usrcfg.c的硬件配置文件來定義系統(tǒng)的硬件資源,此文件存放于AWorks SDK提供的工程模板中。硬件配置文件的核心功能是為系統(tǒng)提供一個(gè)硬件列表,即一個(gè)名為:g_awbl_devhcf_list[]的數(shù)組,該數(shù)組的每一個(gè)成員都描述了系統(tǒng)中的一個(gè)硬件設(shè)備。一個(gè)簡(jiǎn)單的示例片段詳見程序清單12.1。
程序清單12.1 硬件設(shè)備列表(awbus_lite_hwconf_usrcfg.c)
在AWBus-lite中,以“awbl_”作為命名空間,“awbl”是AWBus-lite的縮寫。aw_const是用于定義常量的修飾符,其等效于C語(yǔ)言中的關(guān)鍵字:const。
g_awbl_devhcf_list[]數(shù)組為定義的硬件設(shè)備列表,g_awbl_devhcf_list_count定義了列表中設(shè)備的個(gè)數(shù)。AW_NELEMENTS()為獲取數(shù)組元素個(gè)數(shù)的宏,其定義如下(aw_common.h):
12.3.2 設(shè)備描述類型
由數(shù)組的定義可知,數(shù)組中每個(gè)元素的實(shí)際類型為struct awbl_devhcf,其描述了一個(gè)硬件設(shè)備在系統(tǒng)總線拓?fù)浣Y(jié)構(gòu)中的位置以及設(shè)備的配置,具體類型定義詳見程序清單12.2。
程序清單12.2 struct awbl_devhcf類型定義(awbus_lite.h)
1. 設(shè)備名
設(shè)備名為一個(gè)字符串,此名字需要與設(shè)備驅(qū)動(dòng)的名字一致,系統(tǒng)將根據(jù)此名字查找該設(shè)備對(duì)應(yīng)的驅(qū)動(dòng)。在系統(tǒng)啟動(dòng)時(shí),最重要的步驟之一就是將設(shè)備和設(shè)備驅(qū)動(dòng)綁定,以便正確使用各個(gè)設(shè)備。要使系統(tǒng)能夠正確查找到設(shè)備相應(yīng)的驅(qū)動(dòng),設(shè)備名必須與相應(yīng)的驅(qū)動(dòng)名一致。
為確保一致性,在開發(fā)驅(qū)動(dòng)時(shí),往往使用宏定義的形式將驅(qū)動(dòng)名定義在頭文件中,在描述一個(gè)硬件設(shè)備時(shí),直接使用該宏定義作為其設(shè)備名即可。
例如,i.MX28x的片上I2C設(shè)備驅(qū)動(dòng),其對(duì)應(yīng)的驅(qū)動(dòng)頭文件為:awbl_imx28_i2c.h,在該文件中,定義了驅(qū)動(dòng)名為AWBL_IMX28_I2C_NAME,完整定義如下:
基于此,在描述I2C設(shè)備(如描述I2C1設(shè)備),對(duì)應(yīng)的設(shè)備名應(yīng)該設(shè)定為:
AWBL_IMX28_I2C_NAME。
又如,對(duì)于PCF85063設(shè)備驅(qū)動(dòng),其對(duì)應(yīng)的驅(qū)動(dòng)頭文件為:awbl_pcf85063.h,在該文件中,定義了驅(qū)動(dòng)名為:AWBL_PCF85063_NAME。其完整的定義如下:
基于此,在描述PCF85063設(shè)備時(shí),其設(shè)備名應(yīng)該設(shè)定為:
AWBL_PCF85063_NAME。
2. 設(shè)備單元號(hào)
設(shè)備單元號(hào)用于區(qū)分系統(tǒng)中幾個(gè)相同的硬件設(shè)備,它們的設(shè)備名一樣,復(fù)用同一份驅(qū)動(dòng)。
AWBus-lite建議設(shè)備單元號(hào)從0開始連續(xù)分配。
例如,在i.MX28x中,具有兩個(gè)I2C片內(nèi)外設(shè),則I2C0的設(shè)備單元號(hào)為0,I2C1的設(shè)備單元號(hào)為1。又如,對(duì)于PCF85063設(shè)備,若只外接了一個(gè)PCF85063,則設(shè)備單元號(hào)為0,若外接了兩個(gè)PCF85063,則設(shè)備單元號(hào)分別為0、1。通常情況下,一個(gè)系統(tǒng)中只會(huì)使用一個(gè)外部RTC,不會(huì)連接兩個(gè)外部RTC芯片,此時(shí),將設(shè)備單元號(hào)設(shè)置為0即可。
注意,在通用接口中,通常有一個(gè)用于指定設(shè)備的ID,例如,在RTC接口中,使用ID指定要操作的RTC設(shè)備。設(shè)備單元號(hào)與該ID的概念是不同的,設(shè)備單元號(hào)用于區(qū)分幾個(gè)使用同一驅(qū)動(dòng)的設(shè)備,ID用于區(qū)分同一類的設(shè)備(這些設(shè)備不一定使用相同的驅(qū)動(dòng))。
例如,i.MX28x具有片上RTC外設(shè),其掛在PLB總線上,顯然,其驅(qū)動(dòng)方法與掛在I2C總線上的PCF85063是不一樣的。若系統(tǒng)同時(shí)使用了片上RTC外設(shè)和一個(gè)片外PCF85063,由于它們并不使用同一份驅(qū)動(dòng),因此,在描述這兩個(gè)設(shè)備時(shí),設(shè)備名是不一樣的,設(shè)備單元號(hào)可各自獨(dú)立分配,互不影響,均可設(shè)置為0。但是,由于這兩個(gè)設(shè)備均可以為系統(tǒng)RTC服務(wù),可以使用RTC通用接口操作這兩個(gè)設(shè)備,為了區(qū)分這兩個(gè)設(shè)備,它們的ID必須統(tǒng)一編排,例如,為片上RTC外設(shè)分配編號(hào)0,為PCF85063分配編號(hào)1,不可設(shè)置為一樣。ID在一個(gè)設(shè)備對(duì)應(yīng)的設(shè)備信息中配置,將在后文詳細(xì)介紹。
3. 設(shè)備父總線的類型
設(shè)備父總線的類型指出了設(shè)備掛接在哪種類型的總線上,例如,PLB、I2C、SPI、USB、SDIO、PCI等。各總線的類型已經(jīng)在awbus_lite.h文件中定義,部分常用總線對(duì)應(yīng)的宏定義詳見表12.1。
表12.1 總線類型宏定義
例如,i.MX28x的片上I2C1設(shè)備,其由CPU直接控制,掛接在PLB總線上,因此,對(duì)于I2C1設(shè)備,bus_type的值為:AWBL_BUSID_PLB。
對(duì)于PCF85063設(shè)備,其作為一種I2C從機(jī)器件,掛接在I2C總線上,因此,對(duì)于PCF85063設(shè)備,bus_type的值為:AWBL_BUSID_I2C。
4. 設(shè)備父總線的編號(hào)
設(shè)備父總線的編號(hào)用于區(qū)分系統(tǒng)中多條類型相同的總線。AWBus-lite建議總線編號(hào)從0開始連續(xù)分配。
在AWBus-lite中,PLB總線是一條特殊的虛擬總線,只有一條,因此,對(duì)于掛在PLB總線上的設(shè)備,比如i.MX28x的片上I2C1設(shè)備,它們的設(shè)備父總線編號(hào)總是為0。其它類型的總線可能有多條,例如,i.MX28x具有兩個(gè)I2C片上外設(shè):I2C0、I2C1,它們作為一種總線控制器,可以各自擴(kuò)展出一條I2C總線,致使系統(tǒng)中有兩條I2C總線,可將它們的總線編號(hào)分別設(shè)置為0、1。對(duì)于PCF85063,若其連接在I2C0總線上,則bus_index的值為0;若其連接在I2C1總線上,則bus_index的值為1。
5. 設(shè)備實(shí)例內(nèi)存
設(shè)備驅(qū)動(dòng)相當(dāng)于定義了一個(gè)類,而具體的設(shè)備相當(dāng)于這個(gè)類的一個(gè)實(shí)例,顯然,實(shí)例需要占用一定的內(nèi)存空間。而在AWBus-lite中,并不使用動(dòng)態(tài)內(nèi)存分配,因此,需要在描述一個(gè)設(shè)備的同時(shí),完成設(shè)備實(shí)例的靜態(tài)定義,為設(shè)備實(shí)例分配必要的內(nèi)存空間。p_dev即為指向靜態(tài)定義的設(shè)備實(shí)例的指針,其類型struct awbl_dev是AWBus-lite定義的基礎(chǔ)設(shè)備類型,其具體定義用戶無(wú)需關(guān)心。實(shí)際設(shè)備類型均是從基礎(chǔ)設(shè)備類型派生而來的,例如,PCF85063的設(shè)備類型可能定義為:
由于實(shí)際設(shè)備類型僅用于在描述設(shè)備時(shí)分配設(shè)備實(shí)例相關(guān)的內(nèi)存,并不需要操作其中的成員,因此,用戶并不需要關(guān)心實(shí)際設(shè)備類型的具體定義(比如,具體包含哪些成員等)。用戶只需要了解到實(shí)際設(shè)備類型是從基礎(chǔ)設(shè)備類型派生而來的,因而可以將實(shí)際設(shè)備類型的指針強(qiáng)轉(zhuǎn)為基礎(chǔ)設(shè)備類型的指針進(jìn)行使用(之類轉(zhuǎn)換為父類)。
例如,對(duì)于i.MX28x的片上I2C1設(shè)備,在其對(duì)應(yīng)的驅(qū)動(dòng)頭文件awbl_imx28_i2c.h中定義了I2C設(shè)備的類型為struct awbl_imx28_i2c_dev,使用該類型定義一個(gè)I2C1設(shè)備實(shí)例,即可完成設(shè)備實(shí)例的內(nèi)存分配,例如:
注: aw_local用于將函數(shù)作用域限制在文件內(nèi)部,或?qū)⒆兞康淖饔糜蛳拗圃谖募蚝瘮?shù)內(nèi)部,同時(shí),將aw_local修飾的變量存放在全局靜態(tài)區(qū)域,在整個(gè)程序的生命周期均保持有效。其本質(zhì)上等效于C語(yǔ)言中的關(guān)鍵字:static。
其地址&__g_imx28_i2c1_dev即可作為設(shè)備描述中p_dev的值。雖然其類型與p_dev的類型并不相同,但由于struct awbl_imx28_i2c_dev類型繼承自struct awbl_dev類型,是基礎(chǔ)設(shè)備類型的一個(gè)子類,可以將子類轉(zhuǎn)換為父類使用,例如,將p_dev設(shè)置為:
同理,對(duì)于PCF85063設(shè)備,在其對(duì)應(yīng)的驅(qū)動(dòng)頭文件awbl_pcf85063.h中定義了PCF85063的設(shè)備類型為struct awbl_pcf85063_dev,使用該類型定義一個(gè)PCF85063設(shè)備實(shí)例,即可完成設(shè)備實(shí)例的內(nèi)存分配,例如:
其地址&__g_pcf85063_0_dev即可作為設(shè)備描述中p_dev的值,例如,將p_dev設(shè)置為:
6. 設(shè)備信息
設(shè)備信息描述了設(shè)備的一些配置信息,例如,設(shè)備的基地址、中斷號(hào)等信息。設(shè)備信息的具體類型是由設(shè)備驅(qū)動(dòng)定義的。用戶需要根據(jù)實(shí)際設(shè)備信息的類型定義一個(gè)設(shè)備信息,并將其地址賦值給設(shè)備描述中的p_devinfo。該信息最終會(huì)傳遞給驅(qū)動(dòng)使用,以便正確的驅(qū)動(dòng)相應(yīng)設(shè)備。
-
I2C1設(shè)備信息定義范例
對(duì)于i.MX28x的片上I2C1設(shè)備,在其對(duì)應(yīng)的驅(qū)動(dòng)頭文件awbl_imx28_i2c.h中定義了I2C設(shè)備信息類型為struct awbl_imx28_i2c_devinfo,其具體定義詳見程序清單12.3。
程序清單12.3 I2C設(shè)備信息類型定義(awbl_imx28_i2c.h)
I2C設(shè)備是一個(gè)I2C控制器,可以擴(kuò)展出一條I2C總線,i2c_master_devinfo即用于提供I2C總線相關(guān)的信息,比如:總線的編號(hào)、速率、超時(shí)時(shí)間等。其類型structawbl_i2c_master_devinfo的定義詳見程序清單12.4。
程序清單12.4 struct awbl_i2c_master_devinfo類型定義(awbl_i2cbus.h)
其中bus_index表示該I2C控制器擴(kuò)展出的I2C總線對(duì)應(yīng)的編號(hào),若某一設(shè)備(如PCF85063)在硬件上與I2C1連接,則在其設(shè)備描述中,父總線的編號(hào)應(yīng)與該值保持一致。speed表示該I2C總線的速率。通常情況下,為了便于配置,將總線編號(hào)和速率使用宏的形式定義在aw_prj_param.h文件中,例如,將總線ID定義為1,速率定義為200KHz:
后續(xù)使用這兩個(gè)宏分別作為bus_index和speed的值即可。
timeout表示超時(shí)時(shí)間,若使用通用I2C接口在該總線上的某一操作(如讀數(shù)據(jù)或?qū)憯?shù)據(jù))超過了該處定義的超時(shí)超時(shí),則相應(yīng)接口將返回超時(shí)錯(cuò)誤。特別地,若將該值設(shè)置為
(其是在awbl_i2cbus.h文件中定義的宏),則表示永久等待,也可以設(shè)置為其它正整數(shù)值,例如,500,則表示超時(shí)時(shí)間為500個(gè)tick。
regbase表示I2C設(shè)備的基地址,對(duì)于i.MX28x,所有片內(nèi)外設(shè)的基地址均在imx28x_regbase.h文件中定義,例如,I2C1的基地址定義如下:
由此可見,I2C1設(shè)備的基地址為0x8005A000,該值可以從i.MX28x的用戶手冊(cè)中獲得。
inum表示I2C設(shè)備的中斷號(hào),驅(qū)動(dòng)可以使用該中斷號(hào)使用系統(tǒng)中斷資源,以使I2C設(shè)備可以基于中斷機(jī)制進(jìn)行數(shù)據(jù)通信。對(duì)于i.MX28x,所有片內(nèi)外設(shè)的中斷號(hào)均在imx28x_inum.h文件中定義,例如,I2C1設(shè)備的中斷號(hào)定義如下:
由此可見,I2C1設(shè)備的中斷號(hào)為110,該值可以從i.MX28x的用戶手冊(cè)中獲得。
clkfreq表示I2C模塊的輸入時(shí)鐘頻率,在i.MX28x中,默認(rèn)頻率為24MHz,該值通常不需要修改。
pfunc_plfm_init是一個(gè)函數(shù)指針,指向一個(gè)無(wú)參數(shù)、無(wú)返回值的平臺(tái)初始化函數(shù),用于完成平臺(tái)相關(guān)的初始化操作,比如引腳配置等。例如,在定義一個(gè)平臺(tái)初始化函數(shù),完成I2C1設(shè)備的SCL和SDA引腳配置,詳見詳見程序清單12.5。
程序清單12.5 實(shí)現(xiàn)一個(gè)平臺(tái)初始化函數(shù)
其中,__imx28_i2c1_plfm_init為實(shí)現(xiàn)的平臺(tái)初始化函數(shù),其可直接作為設(shè)備信息中
pfunc_plfm_init的值。
基于上面對(duì)各個(gè)成員的描述,可以定義一個(gè)典型的設(shè)備信息,詳見程序清單12.6。
程序清單12.6 I2C1設(shè)備信息定義
完成設(shè)備信息的定義后,其地址
&__g_imx28_i2c1_devinfo即可作為設(shè)備描述中p_devinfo的值。
-
PCF85063設(shè)備信息定義范例
對(duì)于PCF85063設(shè)備,在其對(duì)應(yīng)的驅(qū)動(dòng)頭文件awbl_pcf85063.h中定義了PCF85063的設(shè)備信息類型為awbl_pcf85063_devinfo_t,其具體定義詳見程序清單12.7。
程序清單12.7 PCF85063設(shè)備信息類型定義(awbl_pcf85063.h)
其中,rtc_servinfo包含了RTC標(biāo)準(zhǔn)服務(wù)相關(guān)的信息,目前僅包含了RTC的編號(hào),其類型定義詳見程序清單12.8。
程序清單12.8 RTC通用服務(wù)信息類型定義(awbl_rtc.h)
通過RTC通用接口的介紹可知,在使用通用接口操作RTC時(shí),需要通過rtc_id指定使用的RTC設(shè)備,rtc_id通常從0開始編號(hào)。rtc_servinfo中的rtc_id即用于指定該設(shè)備對(duì)應(yīng)的ID號(hào),如果設(shè)置為0,則用戶在使用RTC通用接口時(shí),將rtc_id參數(shù)設(shè)置為0即可操作到此處定義的硬件設(shè)備。
addr為PCF85063的7位I2C從機(jī)地址,通過查看PCF85063的數(shù)據(jù)手冊(cè)可知,PCF85063的7位I2C從機(jī)地址為0x51。
基于rtc_id和addr的值,可以完成PCF85063設(shè)備信息的定義,詳見程序清單12.9。
程序清單12.9 PCF85063設(shè)備信息定義范例
完成設(shè)備信息的定義后,其地址
&__g_pcf85063_0_devinfo即可作為設(shè)備描述中p_devinfo的值。
12.3.3 設(shè)備描述宏定義
在g_awbl_devhcf_list[]數(shù)組中,每個(gè)元素都是以“AWBL_HWCONF_”作為前綴的一個(gè)宏。該宏本質(zhì)上完成了一個(gè)設(shè)備描述的定義。
例如,對(duì)于i.MX28x的片上I2C1設(shè)備,其對(duì)應(yīng)的宏為:AWBL_HWCONF_IMX28_I2C0。基于前面介紹的設(shè)備描述中各個(gè)成員的值,可以完成該宏的定義,詳見程序清單12.10。
程序清單12.10 I2C1設(shè)備描述宏定義
對(duì)于PCF85063設(shè)備,其對(duì)應(yīng)的宏為
AWBL_HWCONF_PCF8563_0,基于前面介紹的設(shè)備描述中各個(gè)成員的值,可以完成該宏的定義,詳見程序清單12.11。
程序清單12.11 PCF85063設(shè)備描述宏定義
通常情況下,為了保持
awbus_lite_hwconf_usrcfg.c文件的簡(jiǎn)潔,將設(shè)備描述宏的定義(包括設(shè)備、設(shè)備信息的定義)單獨(dú)存放到一個(gè)頭文件中,I2C1設(shè)備描述宏定義相關(guān)的信息存放在awbl_hwconf_imx28_i2c1.h文件中,PCF85063設(shè)備描述宏定義相關(guān)的信息存放在awbl_hwconf_pcf85063_0.h文件中。
這些文件已經(jīng)在模板工程中提供,在硬件設(shè)備列表中,只需加入該宏即可,詳見程序清單12.1。通過設(shè)備的描述可知,I2C1設(shè)備掛在PLB總線上,PCF85063設(shè)備掛在I2C1總線上,設(shè)備描述與拓?fù)浣Y(jié)構(gòu)的關(guān)系詳見圖12.4。
圖12.4 I2C1和PCF85063設(shè)備描述與拓?fù)浣Y(jié)構(gòu)的對(duì)應(yīng)關(guān)系
12.3.4 設(shè)備的配置與裁剪
設(shè)備配置主要是基于工程模板中提供的配置文件,進(jìn)行設(shè)備描述或設(shè)備信息的修改。用戶若需修改硬件設(shè)備的配置,只需找到該硬件設(shè)備相應(yīng)的頭文件,修改其中的相關(guān)信息即可。
例如,需要修改PCF85063的rtc_id為1,僅需將程序清單12.9中的第3行修改為1。若需調(diào)整設(shè)備在總線拓?fù)浣Y(jié)構(gòu)中的位置。一般來講,一個(gè)設(shè)備的父總線類型是確定的,不會(huì)修改。如PCF85063,其父總線類型必定為:
AWBL_BUSID_I2C。調(diào)整設(shè)備在總線拓?fù)浣Y(jié)構(gòu)中的位置往往是修改父總線的編號(hào),如要將PCF85063掛在I2C0上,僅需將程序清單12.11中,第6行對(duì)應(yīng)的父總線編號(hào)修改為I2C0對(duì)應(yīng)的總線總線編號(hào),即:IMX28_I2C0_BUSID。
除簡(jiǎn)單的配置外,另外一種特殊的操作是裁剪,例如,用戶不需要使用PCF85063,則可以在硬件列表中刪除該設(shè)備的描述宏:
AWBL_HWCONF_PCF85063_0。為了便于用戶裁剪,避免直接操作g_awbl_devhcf_list[]數(shù)組,在awbl_hwconf_pcf85063_0.h文件中,使用了另外一個(gè)使能宏來控制
AWBL_HWCONF_PCF85063_0宏的定義,詳見程序清單12.12。
程序清單12.12 增加PCF85063設(shè)備使能宏(awbl_hwconf_pcf85063_0.h)
程序中,增加了一個(gè)使能宏:
AW_DEV_EXTEND_PCF85063_0。若該宏被有效定義,則AWBL_HWCONF_PCF85063_0宏的定義為完整的設(shè)備描述,此時(shí),PCF85063設(shè)備正常的加入到設(shè)備列表中;反之,若使能宏未被定義,則AWBL_HWCONF_PCF85063_0宏將是一個(gè)空的宏定義,同時(shí),相關(guān)的設(shè)備實(shí)例,設(shè)備信息也不會(huì)被定義。此時(shí),在設(shè)備列表中,將不存在PCF85063設(shè)備的描述,相當(dāng)于裁剪掉了該設(shè)備。同理可以新增一個(gè)I2C1設(shè)備的使能宏,以便對(duì)I2C1設(shè)備進(jìn)行裁剪,詳見程序清單12.13。
程序清單12.13 增加I2C1設(shè)備使能宏(awbl_hwconf_imx28_i2c1.h)
程序中,新增了AW_DEV_IMX28_I2C_1宏對(duì)I2C1設(shè)備是否使能進(jìn)行控制。為便于查找,在AWorks中,類似的設(shè)備相關(guān)的使能宏均在模板工程下的aw_prj_params.h文件中進(jìn)行統(tǒng)一的定義,詳見程序清單12.14。
程序清單12.14 設(shè)備使能宏定義(aw_prj_params.h)
若其中的某一個(gè)宏被用戶注釋掉了,則對(duì)應(yīng)的設(shè)備就會(huì)被裁剪。通過查看aw_prj_params.h文件,用戶可以了解哪些設(shè)備被使能了,哪些設(shè)備被禁能了,并根據(jù)需要,靈活的調(diào)整。例如,不再使用PCF85063,則可以注釋掉該宏,詳見程序清單12.15。
程序清單12.15 設(shè)備裁剪范例(aw_prj_params.h)
值得注意的是,部分特殊的片上外設(shè),例如,GPIO、中斷控制器等,系統(tǒng)必須使用,不能被裁剪,此時(shí),將不會(huì)在相應(yīng)的配置文件中增加額外的使能宏。
12.3.5 注冊(cè)設(shè)備驅(qū)動(dòng)
在描述一個(gè)設(shè)備時(shí),通過設(shè)備名指定了該設(shè)備對(duì)應(yīng)的驅(qū)動(dòng),要使設(shè)備正常工作,系統(tǒng)中必須存在設(shè)備對(duì)應(yīng)的驅(qū)動(dòng)。AWorks作為一個(gè)完備的軟件平臺(tái),已經(jīng)支持眾多的芯片和外圍器件,提供了許許多多的設(shè)備驅(qū)動(dòng),隨著AWorks的進(jìn)一步發(fā)展,提供的驅(qū)動(dòng)還會(huì)越來越多。
顯然,為了節(jié)省系統(tǒng)資源,并不能將所有驅(qū)動(dòng)都加載到系統(tǒng)中,而應(yīng)該只將使用到的驅(qū)動(dòng)加載到系統(tǒng)中,驅(qū)動(dòng)的加載在aw_prj_config.c文件中的awbl_group_init()函數(shù)中完成,該函數(shù)在系統(tǒng)啟動(dòng)時(shí)被自動(dòng)調(diào)用。
每個(gè)驅(qū)動(dòng)都提供了一個(gè)驅(qū)動(dòng)注冊(cè)函數(shù),要使用該驅(qū)動(dòng),則應(yīng)在awbl_group_init()函數(shù)中調(diào)用驅(qū)動(dòng)提供的注冊(cè)函數(shù)。例如,對(duì)于PCF85063設(shè)備驅(qū)動(dòng),其提供的驅(qū)動(dòng)注冊(cè)函數(shù)在驅(qū)動(dòng)頭文件awbl_pcf85063.h文件中聲明,即:
如需使用PCF85063,則應(yīng)將該驅(qū)動(dòng)加載到系統(tǒng)中,即:
一般來講,新增的驅(qū)動(dòng)都添加到函數(shù)尾部。同理,為了便于裁剪,不直接修改aw_prj_config.c文件,往往使用一個(gè)宏對(duì)是否注冊(cè)相應(yīng)驅(qū)動(dòng)進(jìn)行控制,只有當(dāng)宏使能時(shí),才進(jìn)行相應(yīng)的驅(qū)動(dòng)注冊(cè),詳見程序清單12.16。
程序清單12.16 通過宏控制驅(qū)動(dòng)是否注冊(cè)的原理
程序中,若定義了
AW_DRV_EXTEND_PCF85063_0宏,則會(huì)調(diào)用驅(qū)動(dòng)注冊(cè)函數(shù)將驅(qū)動(dòng)注冊(cè)到系統(tǒng)之中;否則,驅(qū)動(dòng)將不會(huì)被注冊(cè),相應(yīng)的驅(qū)動(dòng)代碼就得到了裁剪。
為便于管理,在AWorks中,類似的驅(qū)動(dòng)相關(guān)的使能宏均在模板工程下的aw_prj_params.h文件中進(jìn)行統(tǒng)一的定義,例如:
實(shí)際中,只要使用PCF85063設(shè)備,就必須將PCF85063的設(shè)備驅(qū)動(dòng)注冊(cè)到系統(tǒng)之中,為了確保這一關(guān)系,模板工程中,做了一個(gè)簡(jiǎn)單的自動(dòng)定義操作,在設(shè)備和設(shè)備驅(qū)動(dòng)的使能宏之間進(jìn)行了恰當(dāng)?shù)年P(guān)聯(lián),即:
由此可見,只要PCF85063設(shè)備被使能,AW_DRV_AWBL_EXTEND_PCF85063_0宏將被自動(dòng)定義,使相應(yīng)的驅(qū)動(dòng)也隨之注冊(cè)到系統(tǒng)之中。
這里僅僅只是簡(jiǎn)單的展示了設(shè)備驅(qū)動(dòng)加載的原理,幫助用戶更深入的理解AWBus-lite。實(shí)際中,模板工程已經(jīng)對(duì)此進(jìn)行了恰當(dāng)?shù)奶幚恚?dāng)一個(gè)設(shè)備被使能后,其相應(yīng)的驅(qū)動(dòng)會(huì)被一并使能,用戶只需要控制設(shè)備的使能/禁能即可。
12.3.6 硬件設(shè)備的父總線設(shè)備
對(duì)于PCF85063,其父總線類型為:
AWBL_BUSID_I2C,即PCF85063掛在某一I2C總線上,顯然,I2C總線需要由I2C總線控制器設(shè)備產(chǎn)生,比如在i.MX28x中,片上外設(shè)I2C0和I2C1均可以產(chǎn)生I2C總線。
這也就意味著,要使用PCF85063設(shè)備,除使能PCF85063設(shè)備本身外,還必須使能其父總線對(duì)應(yīng)的設(shè)備。如在i.MX28x中,I2C0和I2C1設(shè)備對(duì)應(yīng)的使能宏在aw_prj_params.h文件中定義為:
基于此,若PCF85063掛在I2C0上,則必須使能AW_DEV_IMX28_I2C_0宏。若掛在I2C1上,則必須使能AW_DEV_IMX28_I2C_1宏。
在i.MX28x中,I2C設(shè)備又掛在PLB總線上,PLB總線作為CPU本地總線,不需要額外使能,始終有效。特別地,若父總線設(shè)備又掛在另外一條總線上,而不是PLB總線上,則相應(yīng)的父總線設(shè)備對(duì)應(yīng)的控制器同樣需要使能,以此類推,確保所有父總線設(shè)備均被使能。
例如,在圖12.1(b)所示的結(jié)構(gòu)圖中,若需要使用SC16IS752設(shè)備,則必須使能SC16IS752設(shè)備的父總線設(shè)備:SC18IS602B設(shè)備,同時(shí),還需使能SC18IS602B設(shè)備的父總線設(shè)備:I2C0設(shè)備。
12.4 訪問設(shè)備
若系統(tǒng)硬件資源定義正確,并且所需的驅(qū)動(dòng)也注冊(cè)到了系統(tǒng)中,則可以通過AWorks定義的通用接口訪問這些硬件設(shè)備。
12.4.1 通用接口
AWorks 為每一類設(shè)備都定義了一套精簡(jiǎn)強(qiáng)大的通用接口,不同的平臺(tái)、不同的硬件,只要是通用接口支持的類型,都可以使用通用接口進(jìn)行訪問。例如,使用RTC通用接口訪問RTC設(shè)備,使用GPIO通用接口訪問GPIO設(shè)備,使用LED通用接口訪問LED。
無(wú)論硬件設(shè)備掛在何種總線上,處在AWbus-lite拓?fù)浣Y(jié)構(gòu)中的何種位置,對(duì)同一類硬件設(shè)備,均可使用相同的接口對(duì)它們進(jìn)行訪問。例如,在一個(gè)基于i.MX28x的系統(tǒng)中,使用了兩個(gè)RTC設(shè)備:i.MX28x 片上RTC外設(shè),外圍器件PCF85063。它們的編號(hào)分別為0、1,使用通用接口對(duì)它們進(jìn)行訪問的示意圖詳見圖12.5。
圖12.5 使用RTC通用接口訪問RTC設(shè)備
由此可見,盡管它們處于不同的總線上,但卻可以使用相同的接口進(jìn)行操作。對(duì)應(yīng)用程序來說,硬件設(shè)備的具體位置并不會(huì)對(duì)應(yīng)用程序產(chǎn)生任何影響。這就將硬件底層和應(yīng)用層進(jìn)行了很好的隔離,后續(xù)即使將PCF85063更換為其它RTC器件(例如,RX8025T、DS1302等),應(yīng)用程序也不需要做任何改動(dòng)。
再以串口為例,查看一種更加復(fù)雜的拓?fù)浣Y(jié)構(gòu),示意圖詳見圖12.6。
圖12.6 使用RTC通用接口訪問RTC設(shè)備
在圖12.6中,SC16IS752是一種SPI轉(zhuǎn)兩路UART芯片。這里僅作為訪問UART設(shè)備的一種示例,以便于用戶理解,用戶無(wú)需深入了解這款芯片,僅需知道SC16IS752是一種SPI轉(zhuǎn)串口芯片即可。
在圖12.6中,總共有5個(gè)串口:MCU片內(nèi)有1個(gè)串口,兩片SC16IS752外擴(kuò)了4個(gè)串口,它們的串口號(hào)分別為COM0、COM1、COM2、COM3和COM4。在實(shí)際硬件連接中,訪問SC16IS752芯片需要經(jīng)過PLB總線、I2C總線和SPI總線,進(jìn)而使用其中的UART功能,但對(duì)于用戶來講,同樣只需要簡(jiǎn)單的調(diào)用串行通用接口即可使用SC16IS752芯片提供的串口功能,和使用片內(nèi)的UART外設(shè)并無(wú)區(qū)別。
再如,每個(gè)MCU都具有一定數(shù)量的GPIO,但是,當(dāng)GPIO不夠用時(shí),可能需要通過外圍器件對(duì)GPIO進(jìn)行擴(kuò)展,示意圖詳見圖12.7。
圖12.7 使用GPIO通用接口訪問GPIO設(shè)備
在圖12.7中,總共有兩個(gè)GPIO設(shè)備:
-
MCU片內(nèi)GPIO,引腳編號(hào)范圍:
PIO0_0~PIO6_24;
-
外擴(kuò)芯片CAT9555,引腳編號(hào)范圍:
EXPIO0_0~EXPIO0_7、
EXPIO1_0~EXPIO1_7。
它們同樣可以使用相同的接口進(jìn)行訪問。
12.4.2 資源ID
在前面的例子中,一個(gè)系統(tǒng)中可能存在多個(gè)同類設(shè)備,它們之間使用“資源ID”進(jìn)行區(qū)分,通用接口則使用“資源ID”指定要訪問的設(shè)備。
通常情況下,“資源ID”為int類型的整數(shù),并從0開始順序編號(hào)。為了便于管理以及增強(qiáng)程序的可讀性,通常將這些資源ID定義為宏,通過宏名體現(xiàn)其真實(shí)的含義。例如,在i.MX28x的I2C0配置文件awbl_hwconf_imx28_i2c0.h中,定義了I2C0設(shè)備的設(shè)備信息,詳見程序清單12.17。
程序清單12.17 I2C0設(shè)備信息配置(awbl_hwconf_imx28_i2c0.h)
在設(shè)備信息中,IMX28_I2C0_BUSID即為I2C0總線的ID宏,默認(rèn)情況下,該宏在aw_prj_param.h文件中定義為0,詳見程序清單12.18。
程序清單12.18 I2C0設(shè)備對(duì)應(yīng)的資源ID宏定義(aw_prj_param.h)
后續(xù)要修改I2C0的ID,僅需修改該宏的值即可。
需要注意的是,“資源ID”的類型并不局限于int類型,只要用于區(qū)分同種類型下的多個(gè)設(shè)備,都可以視為一種“資源ID”,可以是指針類型,字符串類型等等。
在同一個(gè)系統(tǒng)中,某類設(shè)備的資源ID必須統(tǒng)一分配,某一資源ID不能被重復(fù)分配至多個(gè)設(shè)備,確保每個(gè)設(shè)備資源ID的唯一性。例如,在i.MX28x的GPIO配置文件awbl_hwconf_imx28_gpio.h中,定義了GPIO設(shè)備信息,詳見程序清單12.19。
程序清單12.19 GPIO設(shè)備信息配置(awbl_hwconf_imx28_gpio.h)
其中,PIO0_0 ~ PIO6_24為GPIO資源ID宏,它們的定義詳見程序清單12.20。
程序清單12.20 GPIO設(shè)備資源ID宏定義(imx28x_pin.h)
由此可見,PIO0_0的值為0,PIO6_24的值為216,因此,i.MX28x的片上GPIO占用的資源ID范圍為:0 ~ 216。此時(shí),若使用擴(kuò)展芯片(比如:CAT9555)對(duì)GPIO進(jìn)行了擴(kuò)展,則為擴(kuò)展芯片分配的資源ID范圍就必須大于216(不含),以避免范圍重疊。
-
mcu
+關(guān)注
關(guān)注
146文章
17229瀏覽量
351967 -
總線
+關(guān)注
關(guān)注
10文章
2896瀏覽量
88228 -
AWorks
+關(guān)注
關(guān)注
1文章
16瀏覽量
5715
原文標(biāo)題:AWorks軟件篇 — AWBus-lite 總線框架
文章出處:【微信號(hào):ZLG_zhiyuan,微信公眾號(hào):ZLG致遠(yuǎn)電子】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論