日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

嵌入式Linux设备驱动程序:发现硬件配置

發(fā)布時(shí)間:2023/11/28 生活经验 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 嵌入式Linux设备驱动程序:发现硬件配置 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

嵌入式Linux設(shè)備驅(qū)動(dòng)程序:發(fā)現(xiàn)硬件配置

Embedded Linux device drivers: Discovering the hardware configuration

Interfacing with Device Drivers

了解硬件配置

虛擬驅(qū)動(dòng)程序演示了一個(gè)設(shè)備驅(qū)動(dòng)程序的結(jié)構(gòu),但是由于它只操作內(nèi)存結(jié)構(gòu),因此它缺乏與實(shí)際硬件的交互。設(shè)備驅(qū)動(dòng)程序通常是用來與硬件交互的。部分原因是能夠在第一時(shí)間發(fā)現(xiàn)硬件,記住它可能位于不同配置的不同地址。

在某些情況下,硬件本身提供信息。PCI或USB等可發(fā)現(xiàn)總線上的設(shè)備具有查詢模式,該模式返回資源需求和唯一標(biāo)識(shí)符。內(nèi)核將標(biāo)識(shí)符和可能的其他特征與設(shè)備驅(qū)動(dòng)程序匹配,并將它們結(jié)合起來。

然而,嵌入式板上的大多數(shù)硬件塊沒有這樣的標(biāo)識(shí)符。您必須自己以設(shè)備樹的形式或稱為平臺(tái)數(shù)據(jù)的C結(jié)構(gòu)來提供信息。

在Linux的標(biāo)準(zhǔn)驅(qū)動(dòng)程序模型中,設(shè)備驅(qū)動(dòng)程序向相應(yīng)的子系統(tǒng)注冊(cè):PCI、USB、開放固件(設(shè)備樹)、平臺(tái)設(shè)備等等。注冊(cè)包括一個(gè)標(biāo)識(shí)符和一個(gè)稱為探測(cè)函數(shù)的回調(diào)函數(shù),如果硬件ID和驅(qū)動(dòng)程序的ID匹配,則調(diào)用該函數(shù)。對(duì)于PCI和USB,ID基于供應(yīng)商和設(shè)備的產(chǎn)品ID;對(duì)于設(shè)備樹和平臺(tái)設(shè)備,它是一個(gè)名稱(文本字符串)。

設(shè)備樹

我在第三章中介紹了設(shè)備樹,都是關(guān)于引導(dǎo)程序的。在這里,我想向您展示Linux設(shè)備驅(qū)動(dòng)程序是如何與這些信息連接起來的。

作為一個(gè)例子,我將使用ARM多功能板,arch/ARM/boot/dts/Versatile-ab.dts公司,以太網(wǎng)適配器在此處定義:

net@10010000 { compatible = “smsc,lan91c111”; reg = <0x10010000 0x10000>; interrupts = <25>;};

平臺(tái)數(shù)據(jù)

在沒有設(shè)備樹支持的情況下,有一種使用C結(jié)構(gòu)描述硬件的后備方法,稱為平臺(tái)數(shù)據(jù)。

每個(gè)硬件由struct platform_device描述,它有一個(gè)名稱和一個(gè)指向資源數(shù)組的指針。資源的類型由標(biāo)志確定,這些標(biāo)志包括:

IORESOURCE_MEM:這是內(nèi)存區(qū)域的物理地址

IORESOURCE_IO:這是IO寄存器的物理地址或端口號(hào)

IORESOURCE_IRQ:這是中斷號(hào)

下面是一個(gè)以太網(wǎng)控制器的平臺(tái)數(shù)據(jù)示例,該數(shù)據(jù)取自arch/arm/mach versatile/core.c,為清晰起見,對(duì)其進(jìn)行了編輯:

#define VERSATILE_ETH_BASE 0x10010000 #define IRQ_ETH 25 static struct resource smc91x_resources[] = { [0] = { .start = VERSATILE_ETH_BASE, .end = VERSATILE_ETH_BASE + SZ_64K - 1, .flags = IORESOURCE_MEM,},

  [1] = {       .start          = IRQ_ETH,       .end            = IRQ_ETH,       .flags          = IORESOURCE_IRQ,}, 

}; static struct platform_device smc91x_device = { .name = “smc91x”, .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources,};

它有一個(gè)64KB的內(nèi)存區(qū)和一個(gè)中斷。平臺(tái)數(shù)據(jù)必須在內(nèi)核中注冊(cè),通常在板初始化時(shí):

void __init versatile_init(void) { platform_device_register(&versatile_flash_device); platform_device_register(&versatile_i2c_device); platform_device_register(&smc91x_device); [ …]

將硬件與設(shè)備驅(qū)動(dòng)程序鏈接

在上一節(jié)中,您已經(jīng)看到了如何使用設(shè)備樹和平臺(tái)數(shù)據(jù)來描述以太網(wǎng)適配器。相應(yīng)的驅(qū)動(dòng)程序代碼在drivers/net/ethernet/smsc/smc91x.c中,它同時(shí)處理設(shè)備樹和平臺(tái)數(shù)據(jù)。以下是初始化代碼,為清晰起見再次編輯:

static const struct of_device_id smc91x_match[] = { { .compatible = “smsc,lan91c94”, }, { .compatible = “smsc,lan91c111”, }, {}, }; MODULE_DEVICE_TABLE(of, smc91x_match); static struct platform_driver smc_driver = {.probe = smc_drv_probe,

 .remove = smc_drv_remove, .driver ={       .name   = "smc91x",       .of_match_table = of_match_ptr(smc91x_match),     },   };   static int __init smc_driver_init(void)   {     return platform_driver_register(&smc_driver);   }   static void __exit smc_driver_exit(void)   {     platform_driver_unregister(&smc_driver);   }   module_init(smc_driver_init);   module_exit(smc_driver_exit);

當(dāng)驅(qū)動(dòng)程序初始化時(shí),它調(diào)用platform_driver_register(),指向struct
platform_driver,其中有一個(gè)對(duì)探測(cè)函數(shù)的回調(diào)、一個(gè)驅(qū)動(dòng)程序名smc91x和一個(gè)指向“設(shè)備”id的struct的指針。
如果這個(gè)驅(qū)動(dòng)程序是由設(shè)備樹配置的,內(nèi)核將在設(shè)備樹節(jié)點(diǎn)中的compatible屬性和compatible structure元素所指向的字符串之間尋找匹配。對(duì)于每個(gè)匹配,它調(diào)用probe函數(shù)。
另一方面,如果它是通過平臺(tái)數(shù)據(jù)配置的,則將為指向的字符串上的每個(gè)匹配調(diào)用probe函數(shù)驅(qū)動(dòng)程序名.

probe函數(shù)提取有關(guān)接口的信息:

static int smc_drv_probe(struct platform_device *pdev) { struct smc91x_platdata *pd = dev_get_platdata(&pdev->dev); const struct of_device_id *match = NULL; struct resource *res, *ires; int irq;

 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);     ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);     [...]     addr = ioremap(res->start, SMC_IO_EXTENT);     irq = ires->start;[...] 

}

對(duì)platform_get_resource()的調(diào)用從設(shè)備樹或平臺(tái)數(shù)據(jù)中提取內(nèi)存和irq信息。由驅(qū)動(dòng)程序映射內(nèi)存并安裝中斷處理程序。第三個(gè)參數(shù)在前面的兩種情況下都為零,如果有一個(gè)以上的特定類型的資源,則會(huì)起作用。

設(shè)備樹允許您配置的不僅僅是基本內(nèi)存范圍和中斷。probe函數(shù)中有一段代碼從設(shè)備樹中提取可選參數(shù)。在此代碼段中,它獲取register io width屬性:

match = of_match_device(of_match_ptr(smc91x_match), &pdev->dev); if (match) { struct device_node *np = pdev->dev.of_node; u32 val; […] of_property_read_u32(np, “reg-io-width”, &val); […]}

對(duì)于大多數(shù)驅(qū)動(dòng)程序,在Documentation/deviceree/bindings中記錄了特定的綁定。對(duì)于這個(gè)特定的驅(qū)動(dòng)程序,信息在Documentation/deviceree/bindings/net/smsc911x.txt中。
這里要記住的主要一點(diǎn)是,驅(qū)動(dòng)程序應(yīng)該注冊(cè)一個(gè)探測(cè)函數(shù)和足夠的信息,以便內(nèi)核調(diào)用探測(cè),因?yàn)樗l(fā)現(xiàn)與它所知道的硬件匹配。設(shè)備樹描述的硬件和設(shè)備驅(qū)動(dòng)程序之間的鏈接是通過compatible屬性實(shí)現(xiàn)的。平臺(tái)數(shù)據(jù)和驅(qū)動(dòng)程序之間的鏈接是通過名稱實(shí)現(xiàn)的。

摘要

設(shè)備驅(qū)動(dòng)程序的工作是處理設(shè)備,通常是物理硬件,但有時(shí)是虛擬接口,并以一致和有用的方式將它們呈現(xiàn)給用戶空間。Linux設(shè)備驅(qū)動(dòng)程序分為三大類:字符、塊和網(wǎng)絡(luò)。在這三種接口中,字符驅(qū)動(dòng)接口是最靈活的,因此也是最常見的。Linux驅(qū)動(dòng)程序適合于一個(gè)稱為驅(qū)動(dòng)程序模型的框架,該模型通過sysfs公開。在/sys中幾乎可以看到設(shè)備和驅(qū)動(dòng)程序的整個(gè)狀態(tài)。

每個(gè)嵌入式系統(tǒng)都有自己獨(dú)特的硬件接口和需求集。Linux為大多數(shù)標(biāo)準(zhǔn)接口提供了驅(qū)動(dòng)程序,通過選擇正確的內(nèi)核配置,您可以很快得到一個(gè)工作的目標(biāo)板。這就給您留下了非標(biāo)準(zhǔn)組件,您必須添加自己的設(shè)備支持。

在某些情況下,您可以通過使用GPIO、I2C等的通用驅(qū)動(dòng)程序來回避這個(gè)問題,并編寫用戶空間代碼來完成這項(xiàng)工作。我建議將此作為一個(gè)起點(diǎn),因?yàn)樗屇袡C(jī)會(huì)在不編寫內(nèi)核代碼的情況下熟悉硬件。編寫內(nèi)核驅(qū)動(dòng)程序并不是特別困難,但是如果你真的這么做了,你需要小心編碼,以免損害系統(tǒng)的穩(wěn)定性。

我已經(jīng)討論過如何編寫內(nèi)核驅(qū)動(dòng)程序代碼:如果你沿著這條路走下去,你將不可避免地想知道如何檢查它是否正常工作并檢測(cè)出任何錯(cuò)誤。

總結(jié)

以上是生活随笔為你收集整理的嵌入式Linux设备驱动程序:发现硬件配置的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。