溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SylixOS_x86_PCI串口驅(qū)動(dòng)淺析

發(fā)布時(shí)間:2020-08-03 21:10:40 來(lái)源:網(wǎng)絡(luò) 閱讀:988 作者:翼輝小健健 欄目:編程語(yǔ)言

1. 適用范圍

    本文僅針對(duì)于3.0及上版本的SylixOS x86平臺(tái)PCI轉(zhuǎn)串口相關(guān)驅(qū)動(dòng)架構(gòu)進(jìn)行簡(jiǎn)單的分析。

2. PCI簡(jiǎn)介

    外部鏈接標(biāo)準(zhǔn)(或稱個(gè)人電腦界面,Personal Computer Interface),實(shí)際應(yīng)用中簡(jiǎn)稱為PCI(Peripheral Component Interconnect),是一種連接電腦主板和外部設(shè)備的總線標(biāo)準(zhǔn)。一般PCI裝置可分為以下兩種形式:

    直接內(nèi)建于主板上的集成電路,在PCI規(guī)范中稱作“嵌入裝置”(planar device);或者安裝在插槽上的擴(kuò)充界面卡。

    PCI 總線見(jiàn)于現(xiàn)代的個(gè)人電腦中,并已取代了ISA和VESA局部總線,成為了標(biāo)準(zhǔn)擴(kuò)充總線。PCI總線亦常見(jiàn)于其他電腦類型中。PCI總線最終將被PCI Express和其他更先進(jìn)的技術(shù)取代,這些技術(shù)現(xiàn)在已經(jīng)被用于最新款的電腦中。

    PCI規(guī)范規(guī)定了該總線的物理尺寸(包括線寬)、電氣特性、總線時(shí)序和協(xié)議。該規(guī)范可從美國(guó)PCI-SIG協(xié)會(huì)購(gòu)得。

    常見(jiàn)的PCI卡包括網(wǎng)絡(luò)卡、聲卡、調(diào)變解調(diào)器(調(diào)制解調(diào)器)、電視卡和硬盤控制器等,另外還有USB和串列埠等端口。原本顯卡通常也是PCI裝置,但很快其頻寬已不足以支援顯卡的性能。PCI顯卡現(xiàn)在僅用在需要額外的外接顯示器或主板上沒(méi)有AGP和PCI Express槽的情況。

3. PCI串口卡簡(jiǎn)介

    串口卡主要是用來(lái)擴(kuò)展PC的串口數(shù)量和種類。常見(jiàn)的x86機(jī)器主板上可能只有一個(gè)或者兩個(gè)RS232的串口接口,在某些場(chǎng)景下不能滿足對(duì)串口的需求,于是就有了PCI串口卡。通常PCI串口卡會(huì)支持拓展2至8個(gè)串口,也會(huì)支持RS232,RS485,RS422這幾種串口格式。PCI串口卡在工業(yè)和軍工領(lǐng)域運(yùn)用廣泛。

4. PCI串口驅(qū)動(dòng)架構(gòu)分析

4.1      SylixOS下一般的PCI驅(qū)動(dòng)架構(gòu)

    在x86的base工程libsylixos/SylixOS/driver/pci/null路徑下,提供了SylixOS PCI驅(qū)動(dòng)示例:pciNullDev.c。

        pciNullDev.c中主要實(shí)現(xiàn)了如表 41所示五個(gè)主體框架函數(shù)。

表 41  pciNullDev.c中主體函數(shù)

函數(shù)名函數(shù)功能
pciNullDevInitPCI設(shè)備驅(qū)動(dòng)初始化
pciNullDevProbePCI設(shè)備ID探測(cè)和資源信息初始化
pciNullDevRemove刪除PCI設(shè)備
pciNullDevIdTblGet獲取PCI設(shè)備ID表的表頭與表頭大小
pciNullDevIsrPCI設(shè)備驅(qū)動(dòng)中斷服務(wù)程序
  • 函數(shù)pciNullDevInit

        該函數(shù)主要用來(lái)初始化PCI設(shè)備驅(qū)動(dòng),其調(diào)用pciNullDevIdTblGet等函數(shù)將相關(guān)的PCI設(shè)備結(jié)構(gòu)體填充完成,并調(diào)用API_PciDrvRegister函數(shù)注冊(cè)PCI設(shè)備驅(qū)動(dòng)。

  • 函數(shù)pciNullDevProbe

        該函數(shù)由SylixOS PCI子系統(tǒng)回調(diào),主要完成更新設(shè)備驅(qū)動(dòng)版本信息,設(shè)備索引號(hào),獲取設(shè)備MEM、IO、IRQ等資源信息以及中斷連接與使能操作。

  • 函數(shù)pciNullDevRemove

        該函數(shù)由SylixOS PCI子系統(tǒng)回調(diào),主要完成刪除PCI設(shè)備的一系列操作,在該示例中沒(méi)有實(shí)現(xiàn)相關(guān)功能代碼。

  • 函數(shù)pciNullDevIdTblGet

        該函數(shù)主要由pciNullDevInit函數(shù)調(diào)用,用來(lái)獲取相關(guān)PCI設(shè)備的ID表的表頭與表的大小。

  • 函數(shù)pciNullDevIsr

        該函數(shù)為驅(qū)動(dòng)服務(wù)函數(shù),主要提供了該P(yáng)CI設(shè)備驅(qū)動(dòng)的中斷服務(wù)處理,在該示例中中斷服務(wù)處理沒(méi)有實(shí)現(xiàn)相關(guān)功能代碼。

        pciNullDev.c示例中的PCI設(shè)備驅(qū)動(dòng)的流程如圖 41所示:

SylixOS_x86_PCI串口驅(qū)動(dòng)淺析

圖 41  pciNullDev.c設(shè)備驅(qū)動(dòng)大致流程

4.2      SylixOS下PCI串口設(shè)備的驅(qū)動(dòng)架構(gòu)

    在x86的base工程libsylixos/SylixOS/driver/pci/sio路徑存放的是PCI串口卡驅(qū)動(dòng)。pciSioExar.c和pciSioNetmos.c均是PCI串口卡的驅(qū)動(dòng),是針對(duì)不同廠商的適配。一般PCI串口卡都是使用了16c500這一系列的串口芯片,這里著重分析pciSioNetmos.c。

4.2.1   PCI設(shè)備ID表

    如程序清單 41所示pciSioNetmos.c中有一個(gè)驅(qū)動(dòng)支持的設(shè)備ID表結(jié)構(gòu)體數(shù)組。PCI驅(qū)動(dòng)通過(guò)PCI總線獲取設(shè)備相關(guān)ID數(shù)據(jù)和驅(qū)動(dòng)中的驅(qū)動(dòng)支持設(shè)備ID表來(lái)匹配加載相關(guān)的驅(qū)動(dòng)。

程序清單 41  驅(qū)動(dòng)支持設(shè)備ID表

/*********************************************************************************************************
  驅(qū)動(dòng)支持的設(shè)備 ID 表, 用于驅(qū)動(dòng)與設(shè)備進(jìn)行自動(dòng)匹配, 與 Linux 參數(shù)保持一致.
*********************************************************************************************************/
staticconstPCI_DEV_ID_CB  pciSioNetmosIdTbl[] = {
    {
        PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,
        0xa000, 0x1000, 0, 0,
        netmos_9912
    },
    {
        PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912,
        0xa000, 0x1000, 0, 0,
        netmos_9912
    },
    {
        PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922,
        0xa000, 0x1000, 0, 0,
        netmos_9912
    },
    {
        PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9904,
        0xa000, 0x1000, 0, 0,
        netmos_9912
    },
    {
        PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
        0xa000, 0x1000, 0, 0,
        netmos_9912
    },
    {
    }                                                                   /* terminatelist               */
}

    如程序清單 42,在x86的base工程libsylixos/SylixOS/system/drvice/pci/pciDrv.h中定義了設(shè)備ID表數(shù)據(jù)結(jié)構(gòu)體PCI_DEV_ID_CB,其中包含廠商ID,設(shè)備ID,子廠商ID,子設(shè)備ID,設(shè)備類,設(shè)備子類,設(shè)備私有數(shù)據(jù)這7個(gè)相關(guān)屬性,與Linux的PCI結(jié)構(gòu)一致。

程序清單 42  驅(qū)動(dòng)支持設(shè)備ID表結(jié)構(gòu)體

/*********************************************************************************************************
  驅(qū)動(dòng)支持設(shè)備列表控制塊
*********************************************************************************************************/
typedefstruct {
    UINT32                  PCIDEVID_uiVendor;                          /* 廠商 ID                      */
    UINT32                  PCIDEVID_uiDevice;                          /* 設(shè)備 ID                      */
 
    UINT32                  PCIDEVID_uiSubVendor;                       /* 子廠商 ID                    */
    UINT32                  PCIDEVID_uiSubDevice;                       /* 子設(shè)備 ID                    */
 
    UINT32                  PCIDEVID_uiClass;                           /* 設(shè)備類                       */
    UINT32                  PCIDEVID_uiClassMask;                       /* 設(shè)備子類                     */
 
    ULONG                   PCIDEVID_ulData;                            /* 設(shè)備私有數(shù)據(jù)                 */
} PCI_DEV_ID_CB;

4.2.2   函數(shù)介紹

    如表 42所示在pciSioNetmos.c除了實(shí)現(xiàn)了和示例驅(qū)動(dòng)中類似的Init、Probe、Remove、IdTblGet、Isr這五個(gè)相關(guān)類型的函數(shù)外,還實(shí)現(xiàn)了其他的設(shè)備相關(guān)驅(qū)動(dòng)的函數(shù)。

表 4-2  pciSioNetmos.c實(shí)現(xiàn)的相關(guān)函數(shù)

函數(shù)名函數(shù)功能
pciSioNetmosInitPCI NETMOS 16c550 控制器驅(qū)動(dòng)相關(guān)初始化
pciSioNetmosProbePCI NETMOS 16c550 板卡驅(qū)動(dòng)探測(cè)設(shè)備
pciSioNetmosRemove總線上移除 PCI 設(shè)備
pciSioNetmosIdTblGet獲取PCI設(shè)備ID表的表頭與表頭大小
pciSioNetmosChan創(chuàng)建一個(gè) SIO 通道
pciSioNetmosIsrPCI設(shè)備驅(qū)動(dòng)中斷服務(wù)程序
pciSioNetmosGetReg獲得 NETMOS 16C550 寄存器的值
pciSioNetmosGetReg設(shè)置 NETMOS 16C550 寄存器
  • 函數(shù)pciSioNetmosInit

        該函數(shù)和pciNullDevInit一樣,調(diào)用pciNullDevIdTblGet獲取驅(qū)動(dòng)支持設(shè)備ID表的表頭和大小,并設(shè)置驅(qū)動(dòng)名為“pci_netmos”,pciSioNetmosProbe和pciSioNetmosRemove復(fù)制給PCI設(shè)備驅(qū)動(dòng)控制塊,調(diào)用API_PciDrvRegister函數(shù)注冊(cè)PCI設(shè)備驅(qū)動(dòng)。

  • 函數(shù)pciSioNetmosProbe

        該函數(shù)通過(guò)驅(qū)動(dòng)設(shè)置的參數(shù)獲取設(shè)備MEM的其實(shí)地址和MEM的大小,通過(guò)調(diào)用API_PciDevIoRemap重新映射驅(qū)動(dòng)的內(nèi)存空間地址,根據(jù)驅(qū)動(dòng)設(shè)置的參數(shù)獲取設(shè)備中斷資源并注冊(cè),啟動(dòng)PCI總線的主模式,并調(diào)用pciSioNetmosChan函數(shù)來(lái)初始化串口設(shè)備的通道參數(shù),最后通過(guò)ttyDevCreate函數(shù)創(chuàng)建出串口設(shè)備。

  • 函數(shù)pciSioNetmosRemove

        和函數(shù)pciNullDevRemove一樣,實(shí)現(xiàn)總線上移除PCI設(shè)備時(shí)的處理,這里在pciSioNetmos.c里面沒(méi)有實(shí)現(xiàn)相關(guān)方法。

  • 函數(shù)pciSioNetmosIdTblGet

        和pciNullDevIdTblGet一樣,用來(lái)從驅(qū)動(dòng)支持設(shè)備ID表中獲取相關(guān)PCI設(shè)備的ID表的表頭與表的大小。

  • 函數(shù)pciSioNetmosChan

        PCI串口驅(qū)動(dòng)的關(guān)鍵函數(shù),該函數(shù)將PCI設(shè)備驅(qū)動(dòng)和串口設(shè)備驅(qū)動(dòng)相互連接起來(lái)了。將驅(qū)動(dòng)設(shè)置好的串口參數(shù),PCI串口的中斷和pciSioNetmosSetReg,pciSioNetmosGetReg函數(shù)賦值給PCI設(shè)備串口通道結(jié)構(gòu)體,調(diào)用API_PciDevInterDisable先禁能PCI串口設(shè)備的中斷,然后調(diào)用系統(tǒng)的16c550串口驅(qū)動(dòng)中的sio16c550Init來(lái)初始化相關(guān)PCI串口通道,隨后調(diào)用API_PciDevInterConnect,API_PciDevInterEnable連接并使能PCI串口設(shè)備中斷,完成PCI串口通道的創(chuàng)建。

  • 函數(shù)pciSioNetmosIsr

        PCI串口的中斷服務(wù)函數(shù),該函數(shù)是在PCI設(shè)備的中斷函數(shù)服務(wù)中調(diào)用了系統(tǒng)的16c550串口驅(qū)動(dòng)服務(wù)函數(shù),來(lái)完成對(duì)應(yīng)的串口中斷處理事務(wù)。

  • 函數(shù)pciSioNetmosGetReg

        該函數(shù)被系統(tǒng)串口驅(qū)動(dòng)回調(diào),用于讀取PCI設(shè)備對(duì)應(yīng)通道相關(guān)寄存器地址的值。

  • 函數(shù)pciSioNetmosSetReg

        該函數(shù)被系統(tǒng)串口驅(qū)動(dòng)回調(diào),用于設(shè)置PCI設(shè)備對(duì)應(yīng)通道相關(guān)寄存器地址的值。

    pciSioNetmos.c示例中的PCI設(shè)備驅(qū)動(dòng)的函數(shù)結(jié)構(gòu)如圖 44所示:

SylixOS_x86_PCI串口驅(qū)動(dòng)淺析

圖 44  pciSioNetmos.c設(shè)備驅(qū)動(dòng)大體流程

5. 總結(jié)

    PCI串口驅(qū)動(dòng)本質(zhì)上是PCI驅(qū)動(dòng)和串口驅(qū)動(dòng)的一個(gè)結(jié)合,上層通過(guò)系統(tǒng)的串口驅(qū)動(dòng)來(lái)封裝出串口所需要的操作接口,下層由PCI驅(qū)動(dòng)來(lái)和PCI總線上的設(shè)備進(jìn)行各種操作。


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI