天天看點

linux misc裝置 ioctl,字元裝置、misc裝置、platform裝置驅動的使用

Linus Torvalds 在 2011 年 3 月 17 日的 ARM Linux 郵件清單宣稱“this whole ARM thing is a f*cking pain in the ass”,引發 ARM Linux 社群的地震,随後 ARM 社群進行了一系列 的重大修正。在過去的 ARM Linux 中,arch/arm/plat-xxx 和 arch/arm/mach-xxx 中充斥着大 量的垃圾代碼,相當多數的代碼隻是在描述闆級細節,而這些闆級細節對于核心來講,不 過是垃圾,如闆上的 platform 裝置、resource、i2c_board_info、spi_board_info 以及各種硬 件的 platform_data。讀者有興趣可以統計下常見的 s3c2410、s3c6410 等闆級目錄,代碼量 在數萬行。

社群必須改變這種局面,于是 PowerPC 等其他體系架構下已經使用的 Flattened Device Tree(FDT)進入 ARM 社群的視野。Device Tree 是一種描述硬體的資料結構,它起源于 OpenFirmware (OF)。在 Linux 2.6 中,ARM 架構的闆極硬體細節過多地被寫死在 arch/arm/plat-xxx 和 arch/arm/mach-xxx,采用 Device Tree 後,許多硬體的細節可以直接透 過它傳遞給 Linux,而不再需要在 kernel 中進行大量的備援編碼。

是以現在有節操的代碼中,可能沒有了resource的定義,裝置相關的描述統一的放在了arch/arm(arm64)/boot/dts路徑下的dts檔案中,dt的内容本文不做讨論。

在加入dt以後,驅動程式的變化是,不再需要對裝置資源有描述,沒有了platfrom_device_register函數來注冊裝置,這些工作都由核心來替我們完成(解析dt的代碼為of_*開頭的源檔案), 驅動隻要做driver相關的定義和注冊即可。相應的如果想要使用本裝置的資源,依然是調用platform_get_resource函數擷取;如果想要使用其他裝置的資源,則需要擷取該裝置的節點,再擷取其resource内容。

假如DT的一個節點如下:

點選(此處)折疊或打開

device01{

compatible = "compa ny,device01";

reg = <0 0x30040000 0 0xA0000 //裝置資源的描述

0 0x20F00000 0 0x300000>;

interrupts = <0 86 0x0>;

}

如果使用dt,驅動中還要給platform_driver中.driver的.of_match_table填充一個of_device_id結構,比如:

點選(此處)折疊或打開

static const struct of_device_id of_match[] = {

{ .compatible = "company,device01", },

{ }

};

static struct platform_driver xx_driver = {

.probe = xx_probe,

.remove = xx_remove,

.suspend = xx_suspend,

.resume = xx_resume,

.driver = {

.owner = THIS_MODULE,

.name = "device01",

.of_match_table = of_match

}

}

如果驅動中想要使用其他節點(裝置)定義的資源,由于沒有相應platform device在本驅動中,不能簡單的通過platform_get_resource來擷取,platform_get_resource第一個參數就是paltform device,即本裝置。則需要通過一系列的of_*開頭的函數來擷取。在driver/of目錄下有相關的源檔案,比如下面廣兩個函數可以滿足簡單需求:

擷取dt節點:

struct device_node *of_find_compatible_node (struct device_node *from, const char *type, const char *compatible)

struct device_node *of_find_node_by_name(struct device_node *from, const char *name)

将節點中的指定資源,轉到resource變量中:

int of_address_to_resource (struct device_node *dev, int index, struct resource *r)

最後:在項目過程中,感覺簡單的字元裝置應用并不常見,有的完全可以用misc裝置代替,并且platform引入以後,linux下大部分的驅動都可以以此架構實作,是以platfrom更為常見,并可配合misc裝置向上提供節點,供引用層使用。也可以配合sys節點,建立裝置的屬性檔案,供上層使用,友善并且容易實作。