• 正文
    • 示例源碼
    • 編譯
    • 修改設(shè)備樹
    • 測試
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

飛凌嵌入式ElfBoard ELF 1板卡-platform總線驅(qū)動簡單示例

04/01 14:45
140
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

例程代碼路徑:ELF 1開發(fā)板資料包3-例程源碼3-2 驅(qū)動例程源碼6_platformplatform

示例源碼

#include <linux/init.h>

#include <linux/module.h>

#include <linux/platform_device.h>

static int my_platform_probe(struct platform_device *pdev)

{

printk(KERN_INFO "my_platform_probe: Platform device probedn");

return 0;

}

static int my_platform_remove(struct platform_device *pdev)

{

printk(KERN_INFO "my_platform_remove: Platform device removedn");

return 0;

}

static const struct of_device_id of_platform_match[] = {

{ .compatible = "platform", },

{},

};

static struct platform_driver my_platform_driver = {

.driver = {

.name = "my_platform_driver",

.owner = THIS_MODULE,

.of_match_table = of_platform_match,

},

.probe = my_platform_probe,

.remove = my_platform_remove,

};

module_platform_driver(my_platform_driver);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Your Name");

MODULE_DESCRIPTION("Platform Driver Example");

上述示例定義了一個名為 "my_platform_driver" 的平臺驅(qū)動程序。驅(qū)動程序中的 my_platform_probe() 函數(shù)是探測函數(shù),my_platform_remove() 函數(shù)是移除函數(shù)。還定義了一個platform_driver類型的結(jié)構(gòu)體,結(jié)構(gòu)體定義如下:

struct platform_driver {

int (*probe)(struct platform_device *);

int (*remove)(struct platform_device *);

void (*shutdown)(struct platform_device *);

int (*suspend)(struct platform_device *, pm_message_t);

int (*resume)(struct platform_device *);

struct device_driver driver;

const struct platform_device_id *id_table;

bool prevent_deferred_probe;

};

定義說明:

(一)probe:驅(qū)動探測函數(shù)指針,當設(shè)備與驅(qū)動匹配時調(diào)用。它接收一個指向structplatform_device的指針作為參數(shù),返回一個整數(shù)類型的值。

(二)remove:驅(qū)動移除函數(shù)指針,當設(shè)備被移除時調(diào)用。它接收一個指向structplatform_device的指針作為參數(shù),返回一個整數(shù)類型的值。

(三)shutdown:關(guān)機回調(diào)函數(shù)指針,當系統(tǒng)關(guān)機時調(diào)用。它接收一個指向struct platform_device的指針作為參數(shù),無返回值。

(四)suspend:掛起回調(diào)函數(shù)指針,當系統(tǒng)進入掛起狀態(tài)時調(diào)用。它接收一個指向struct platform_device的指針和pm_message_t類型的參數(shù)作為輸入,返回一個整數(shù)類型的值。

(五)resume:恢復回調(diào)函數(shù)指針,當系統(tǒng)從掛起狀態(tài)恢復時調(diào)用。它接收一個指向struct platform_device的指針作為參數(shù),返回一個整數(shù)類型的值。

(六)driver:包含了驅(qū)動的名稱、擁有者等信息的 struct device_driver 結(jié)構(gòu)體。

(七)id_table:一個指向平臺設(shè)備ID表的指針,用于與設(shè)備匹配。它可以為空,或者指向一個以NULL結(jié)尾的數(shù)組。

(八)prevent_deferred_probe:一個布爾值,用于指示是否禁止推遲的探測。如果設(shè)置為true,則在設(shè)備匹配時不會推遲探測過程。

通過使用module_platform_driver宏,我們可以將驅(qū)動程序的注冊和注銷過程簡化為一行代碼。宏會自動為驅(qū)動程序注冊和注銷函數(shù),并處理必要的初始化和清理工作。

需要注意的是,驅(qū)動程序中的probe和remove回調(diào)函數(shù)必須與平臺驅(qū)動程序的結(jié)構(gòu)體字段對應(yīng),以正確地處理設(shè)備的探測和移除。

of_platform_match[]數(shù)組中定義了設(shè)備兼容性匹配項,當內(nèi)核在設(shè)備初始化過程中加載驅(qū)動時,會遍歷設(shè)備樹中的設(shè)備節(jié)點,并將每個設(shè)備節(jié)點的compatible屬性與驅(qū)動中的兼容屬性進行匹配。只有當匹配成功時,才會執(zhí)行相應(yīng)的probe函數(shù)。

編譯

復制上一節(jié)驅(qū)動中的Makefile文件,將其中的myirq_key.o修改為platform.o,效果如下:

. /opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi

elf@ubuntu:~/work/test/06_platform/platform$?make

將編譯生成的platform.ko模塊拷貝到開發(fā)板中

修改設(shè)備樹

在設(shè)備樹根節(jié)點下添加設(shè)備,否則無法進行匹配。打開arch/arm/boot/dts/imx6ull-elf1-emmc.dts添加如下內(nèi)容:

my_device {

compatible = "platform";

};

添加后效果如下:

編譯設(shè)備樹,單獨替換設(shè)備樹并重啟。

測試

root@ELF1:~# insmod platform.ko

my_platform_probe: Platform device probed

root@ELF1:~# rmmod platform.ko

my_platform_remove: Platform device removed

可以看到在驅(qū)動加載時,進入到了probe函數(shù),在驅(qū)動卸載時進入到了remove函數(shù)。從上面示例中可以了解到使用 module_platform_driver 宏可以大大簡化平臺驅(qū)動程序的編寫過程,并提高代碼的可讀性和可維護性。

相關(guān)推薦