Linux設備驅動學習二 在module中註冊設備

以module的方式註冊設備,並在驅動中調用設備的參數

在前面的博客我記錄瞭如何註冊設備和如何註冊驅動,我們可以明顯的看出設備的註冊是很麻煩的,需要修改平臺文件,需要配置menuconfig,需要重新編譯內核,需要將編譯好的zImage燒錄到開發板,而驅動的註冊就簡單多了,只要執行insmod就可以了,那麼在學習中有沒有什麼簡單的註冊設備的方式呢?有的,設備也可以作爲module的方式來註冊,雖然說做產品的話絕大多數還是會使用修改平臺文件的方式,但是以module的方式來註冊設備可以大大簡化我們的學習過程,不用頻繁的燒錄內核
資料來源於網上和迅爲提供的視頻學習。

前面一節的設備註冊使用的是CONFIG_HELLO_CTL的形式,通過結構體platform_device的調用直接配置,實現註冊設備的功能。

本節通過直接調用的註冊設備的函數來是其功能。

主要函數:

platform_device_register  :drivers/base/platform.c
流程:
文件drivers/base/platform.c定義了設備的register函數,然後通過platform_device_add.
所以我們只需要會使用platform_device_register即可。
/**
 * platform_device_register - add a platform-level device
 * @pdev: platform device we're adding
 */
int platform_device_register(struct platform_device *pdev)
{
        device_initialize(&pdev->dev);
        return platform_device_add(pdev);
}
EXPORT_SYMBOL_GPL(platform_device_register);
platform_device_unregister:同上
更詳細的以後參考內核代碼分析:
/**
 * platform_device_unregister - unregister a platform-level device
 * @pdev: platform device we're unregistering
 *
 * Unregistration is done in 2 steps. First we release all resources
 * and remove it from the subsystem, then we drop reference count by
 * calling platform_device_put().
 */
void platform_device_unregister(struct platform_device *pdev)
{
        platform_device_del(pdev);
        platform_device_put(pdev);
}
EXPORT_SYMBOL_GPL(platform_device_unregister);

還有一個結構體:platform_device,作爲上面兩個函數的使用參數,結構體類型具體如下:

下面的是調用具體函數的sample:

文件名:platform_device_test.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>

static  void leds_release(struct device *dev)
{
    printk("leds_release\n");
}

struct platform_device platform_device_hello = {
    .name = "my_code_led",
    .id = -1,
    .dev = {
        .release = leds_release,

    }
};

static int hello_init(void)
{
    printk(KERN_EMERG "init \n");
    platform_device_register(&platform_device_hello);
        return 0;
}

static void hello_exit(void)
{
    platform_device_unregister(&platform_device_hello); //unregister會查找release,如果找不到會報錯
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("NANZH");

編譯

$ make
make -C /home/nan/iTOP4412/iTop4412_Kernel_3.0 M=/home/nan/iTOP4412/3 modules
make[1]: Entering directory '/home/nan/iTOP4412/iTop4412_Kernel_3.0'
  CC [M]  /home/nan/iTOP4412/3/platform_device_test.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/nan/iTOP4412/3/platform_device_test.mod.o
  LD [M]  /home/nan/iTOP4412/3/platform_device_test.ko
make[1]: Leaving directory '/home/nan/iTOP4412/iTop4412_Kernel_3.0'

拷貝到開發板並查看

# insmod platform_device_test.ko 
[  544.778744] init 
# ls /sys/devices/
platform/ system/   virtual/  
# ls /sys/devices/platform/
my_code_led  ...

至此達到和設備註冊一中的mach-itop4412.c中註冊方法達到相同的結果。

總結
1、除了最特殊的USB設備,其他的設備驅動,都徐亞驅動工程師註冊設備,用module的方式註冊設備只是爲了方便學習和調試,在絕大多數情況下,都是以平臺文件的方式統一在內核文件中來註冊設備
2、驅動註冊和設備註冊都是將代碼嵌入到Linux內核中,屬於“對中”的部分(不是面向下層硬件,也沒有對上層提供接口)
3、設備驅動中設備和驅動是分離的,無論是在平臺文件中註冊設備,還是以module的方式註冊設備,設備都要優先驅動註冊,否則驅動無法進入probe
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章