linuxpro
A. linux spi設備驅動中probe函數何時被調用
這兩天被設備文件快搞瘋了,也怪自己學東西一知半解吧,弄了幾天總算能把設備注冊理清楚一點點了。就以spi子設備的注冊為例總結一下,免得自己忘記。
首先以注冊一個spidev的設備為例:
static struct spi_board_info imx5_spi_printer_device[] __initdata =
{
{
.modalias = "spidev",
.max_speed_hz = 8000000,
.bus_num = 1,
.chip_select = 1,
.mode = SPI_MODE_0,
},
};
spi_register_board_info(imx5_spi_printer_device,ARRAY_SIZE(imx5_spi_printer_device));
在mx5_loco.c文件中添加上面結構體spi_board_info,modalias必須指定已有的一個驅動,至於bus_num和chip_select,如果你不知道bus_num是多少,可以在你的父驅動中列印出來,這里的bus_num一定要和父類的bus_num一致,否則是無法生成設備文件的。如果spi一直沒有時鍾信號,很有可能是bus_num不對。
這樣系統起來之後就會在/dev目錄下出現一個名為spidev1.1的設備文件,讀寫這個文件就可以實現spi的操作
還有下面這種情況:
static struct spi_board_info prt_spi_device[] __initdata = {
{
.modalias = "HotPRT",
.max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
.bus_num = 1,
.chip_select = 1,
// .mode = SPI_MODE_0,
.platform_data = 0,
},
};
spi_register_board_info(prt_spi_device, ARRAY_SIZE(prt_spi_device));
我自己實現了一個spi的驅動,然後需要創建一個設備文件,設備文件的創建是在probe中完成。
static struct spi_driver prt_driver = {
.driver = {
.name = "HotPRT",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = prt_probe,
.remove = __devexit_p(prt_remove),
};
spi_register_driver(&prt_driver);
但是我開始一直觸發不了probe,於是找啊找,總算知道probe的調用過程了,如下:
int spi_register_driver(struct spi_driver *sdrv)
{
sdrv->driver.bus = &spi_bus_type;
if (sdrv->probe)
sdrv->driver.probe = spi_drv_probe;
if (sdrv->remove)
sdrv->driver.remove = spi_drv_remove;
if (sdrv->shutdown)
sdrv->driver.shutdown = spi_drv_shutdown;
return driver_register(&sdrv->driver);
}
然後調用driver_register
<pre name="code" class="cpp">int driver_register(struct device_driver *drv)
{
int ret;
struct device_driver *other;
BUG_ON(!drv->bus->p);
if ((drv->bus->probe && drv->probe) ||
(drv->bus->remove && drv->remove) ||
(drv->bus->shutdown && drv->shutdown))
printk(KERN_WARNING "Driver '%s' needs updating - please use "
"bus_type methods\n", drv->name);
other = driver_find(drv->name, drv->bus);
if (other) {
put_driver(other);
printk(KERN_ERR "Error: Driver '%s' is already registered, "
"aborting...\n", drv->name);
return -EBUSY;
}
ret = bus_add_driver(drv);
if (ret)
return ret;
ret = driver_add_groups(drv, drv->groups);
if (ret)
bus_remove_driver(drv);
return ret;
}
直接看bus_add_driver
klist_init(&priv->klist_devices, NULL, NULL);
priv->driver = drv;
drv->p = priv;
priv->kobj.kset = bus->p->drivers_kset;
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
"%s", drv->name);
if (error)
goto out_unregister;
if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);
if (error)
goto out_unregister;
}
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
mole_add_driver(drv->owner, drv);
這里只截取一部分,最後調用的是driver_attach
int driver_attach(struct device_driver * drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}
真正起作用的是__driver_attach:
static int __driver_attach(struct device * dev, void * data)
{
。。。
if (!dev->driver)
driver_probe_device(drv, dev);
。。。
}
int driver_probe_device(struct device_driver * drv, struct device * dev)
{
。。。
//1.先是判斷bus是否match:
if (drv->bus->match && !drv->bus->match(dev, drv))
goto done;
//2.再具體執行probe:
ret = really_probe(dev, drv);
。。。
}
really_probe才是我們要找的函數:
static int really_probe(struct device *dev, struct device_driver *drv)
{
。。。
//1.先是調用的驅動所屬匯流排的probe函數:
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
if (ret)
goto probe_failed;
} else if (drv->probe) {
//2.再調用你的驅動中的probe函數:
ret = drv->probe(dev);
if (ret)
goto probe_failed;
}
。。。
}
其中,drv->probe(dev),才是真正調用你的驅動實現的具體的probe函數。至此probe函數被調用。
在板文件中添加spi_board_info,並在板文件
B. linux驅動probe函數有什麼用
供驅動注冊時調用以便對設備進行相應的初始化等操作
C. linux驅動probe什麼時候調用
新的Linux內核中,probe函數是在模塊_init中調用的,其實作用就是初始化模塊
D. linux下,設備驅動什麼情況需要probe,什麼情況下不需要probe
我的理解是大多數支持熱插拔的設備都需要probe,少部分常住設備需要probe。
主要區別在如果在arch目錄下已經標注了設備的配置信息時,就不需要probe函數來進行設備描述性配置。當沒有相應的具體配置描述,就需要probe函數來進行設備配置
E. Linux驅動中,probe函數何時被調用
在驅動程序注冊的時候,會有一個match的過程,將驅動和設備兩個匹配。在匹配的過程中會調用probe函數。
在bus.c中會出現static
int
bus_match(struct
device
*
dev,
struct
device_driver
*
drv),這個函數就會調用
if
(drv->probe)
{
if
((error
=
drv->probe(dev)))
{
dev->driver
=
NULL;
return
error;
},這個時候就是調用Probe的時候了。
你可以看下這個連接
http://www.cnblogs.com/hoys/archive/2011/04/01/2002299.html
F. linux spi設備驅動中probe函數何時被調用
最近看到linux的設備驅動模型,關於Kobject、Kset等還不是很清淅。看到了struct device_driver這個結構時,想到一個問題:它的初始化函數到底在哪裡調用呢?以前搞PCI驅動時用pci驅動注冊函數就可以調用它,搞s3c2410驅動時只要在mach-smdk2410.c中的struct platform_device *smdk2410_devices {}中加入設備也會調用。但從來就沒有想過具體的驅動注冊並調用probe的過程。
於是打開SourceInsight追蹤了一下:
從driver_register看起:
復制代碼
int driver_register(struct device_driver * drv)
{
klist_init(&drv->klist_devices, klist_devices_get, klist_devices_put);
init_completion(&drv->unloaded);
return bus_add_driver(drv);
}
復制代碼
klist_init與init_completion沒去管它,可能是2.6的這個設備模型要做的一些工作。直覺告訴我要去bus_add_driver。
bus_add_driver中:
都是些Kobject 與 klist 、attr等。還是與設備模型有關的。但是其中有一句:
driver_attach(drv);
單聽名字就很像:
void driver_attach(struct device_driver * drv)
{
bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}
這個熟悉,遍歷匯流排上的設備並設用__driver_attach。
在__driver_attach中又主要是這樣:
driver_probe_device(drv, dev);
跑到driver_probe_device中去看看:
有一段很重要:
if (drv->bus->match && !drv->bus->match(dev, drv))
G. 如何修改linux下設備名稱
修改linux設備名稱:
(1)通過hostname命令
命令格式:hostname newhostname
此命令的作用是暫時修改linux的主機設備名稱,它的存活時間為linux當前的運行時間,即在重啟linux之前的運行時間內。一般修改以後就生效,但是不能夠永久修改。
(2)通過修改配置文件/etc/hostname
執行命令:
sudo vim /etc/hostname
在文件中將原來的主機設備名稱修改為所需要的新的設備名稱。需要重啟才能生效。Linux詳細且具體的命令介紹可如下查閱」Linux命令大全「
H. linux中的網卡驅動函數probe的具體作用。
probe在設備驅動被注冊到內核中的時候,被匯流排型驅動調用。
匯流排驅動類似於用輪訓方法探測匯流排上的所有設備,將設備的識別型信息和關鍵數據結構 (pci ids, usb ids, i2c ids and etc.)傳遞給probe函數,probe就會識別是否是自己負責驅動的設備,並負責完成該設備的初始化操作。
I. linux中的probe函數中文意思
你好,這個函數的字面意思就是探測的意思,就是循環來探測驅動的,它用於linux驅動級開發。
簡單來說就是這樣了,至於具體的含義和調用方法,我覺得說不清楚,但是網路能搜索到很多資料,你只要在網路搜索 probe函數 就能找到很多,鏈接我就不發了,發了鏈接老是要審核。