以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