Wie wird der probe()
-Anruf angerufen? Wer ruft es an Nach meinem Verständnis registriert __init()
driver
und dann wird probe()
irgendwie aufgerufen, register
die Gerätedaten und irq
usw. aufgerufen.
Ich arbeite an einem Touchscreen-Treiber und sein __init
registriert sich bei i2c driver
. Dann erwarten Probe i2c_clien
t-Daten, die null zurückgeben. Ich möchte verfolgen, wo es gefüllt wird.
Um es kurz zu machen: Die Probe () - Funktion des Treibers wird als Ergebnis des Aufrufs von register_driver
für diesen bestimmten Bus aufgerufen. Genauer gesagt, es wird von der probe()
dieser bus_type
-Struktur aufgerufen. In Ihrem Fall: i2c_bus_type
.
Hier ist die Anrufkette in Ihrem I2C-Fall:
Ich habe ein Diagramm vorbereitet, das die Sondenfunktion von Platform Drive aufzeichnet. Sie arbeiten mit einem I2C-Treiber, bei dem AFAIK ein Plattformtreiber ist. Ich hoffe, das hilft Ihnen, das Problem aufzuspüren.
Schauen Sie sich auch den folgenden Link an, um die Diskussion über Kernel-Neuheiten zu sehen.
https://www.mail-archive.com/kernelnewbies%40kernelnewbies.org/msg12423.html
@iSegFault: probe () wird aufgerufen, um sicherzustellen, dass das Gerät vorhanden ist und die Funktionalität in Ordnung ist. Wenn das Gerät nicht Hot-Plug-fähig ist, kann die Funktion von probe () in die Methode init () gestellt werden Reduzieren Sie den Speicherbedarf des Treibers zur Laufzeit. P.S Link
Probe () geschieht zum Zeitpunkt des Gerätestarts oder wenn das Gerät angeschlossen ist. Bei einem "Plattform" -Gerät wird die Probe-Funktion aufgerufen, wenn ein Plattformgerät registriert wird und dessen Gerätename mit dem im Gerätetreiber angegebenen Namen übereinstimmt. P.S Link
Die Funktion i2c_detect prüft den I2C-Adapter und sucht nach den verschiedenen Adressen, die in der Struktur addr_data angegeben sind. Wird ein Gerät gefunden, wird die Funktion chip_detect aufgerufen. P.S link .
Ein Link, der sicherlich Ihre Zweifel klären wird. P.S Link
In Kernel 2.4.29 kann ich Ihnen zeigen, wie die Untersuchung geschieht. Bitte sehen Sie unten (Dateiname: drivers/acorn/char/pcf8583.c)
static struct i2c_driver pcf8583_driver = {
name: "PCF8583",
id: I2C_DRIVERID_PCF8583,
flags: I2C_DF_NOTIFY,
attach_adapter: pcf8583_probe, /* This will be called from i2c-core.c P.S see below function i2c_add_driver()*/
detach_client: pcf8583_detach,
command: pcf8583_command
};
Dateiname: drivers/i2c/i2c-core.c
int i2c_add_driver(struct i2c_driver *driver)
{
........................
........................
/* now look for instances of driver on our adapters
*/
if (driver->flags& (I2C_DF_NOTIFY|I2C_DF_DUMMY)) {
for (i=0;i<I2C_ADAP_MAX;i++)
if (adapters[i]!=NULL)
/* Ignore errors */
driver->attach_adapter(adapters[i]); /*This is a location from where probe is called. Pointer **driver** is of type **pcf8583_driver** which you have passed into this function*/
}
ADAP_UNLOCK();
return 0;
}
Einige wichtige Links:
1) http://www.slideshare.net/varunmahajan06/i2c-subsystem-in-linux2624
2) http://www.programering.com/a/MjNwcTMwATM.html
3) http://www.linuxjournal.com/article/6717
4) http://www.developermemo.com/2943157/
5) http://free-electrons.com/doc/kernel-architecture.pdf
6) http://www.techques.com/question/1-3014627/Probe-problem-when-writing-a-I2C-geraetreiber
In PCI für Kernel-2.4.29 wird es aufgerufen, wenn Hersteller- und Geräte-ID identifiziert werden. PCI-Bustreiber tun dies für Sie. Bitte sehen Sie den Code unten:
Dateiname: drivers/pci/pci.c
static int pci_announce_device(struct pci_driver *drv, struct pci_dev *dev)
{
const struct pci_device_id *id;
int ret = 0;
if (drv->id_table) {
id = pci_match_device(drv->id_table, dev); /* check for device presence*/
if (!id) {
ret = 0;
goto out;
}
} else
id = NULL;
dev_probe_lock();
if (drv->probe(dev, id) >= 0) { /* This is a location from where probe is called*/
dev->driver = drv;
ret = 1;
}
dev_probe_unlock();
out:
return ret;
}
Betrachten wir ein Beispiel für ein platform device driver
:
Die Start-Trigger-Funktion für den driver->probe()
-Callback ist das module_init()
-Makro, das beim Laden des Treibers aufgerufen wird. Dieses macro
ist in include/linux/module.h
definiert.
module_init(my_driver_init)
hat den Rückruf an die my_driver_init()
-Funktion. Die Funktion my_driver_init()
sollte einen Aufruf an platform_driver_register(my_driver)
haben.
platform_driver_register(my_driver)
weist das my_driver -> probe()
-Handle dem generischen drv -> probe()
zu und ruft die Funktion driver_register(my_driver)
auf.
Die Funktion driver_register(my_driver)
fügt dem Plattformbus my_driver
hinzu und ruft die Funktion driver_attach()
auf.
Auf die gleiche Weise muss auch der platform_device
an den Plattformbus angeschlossen werden.
Erst wenn driver_match_device()
erfolgreich auf der Grundlage von .name
& .id_table
der driver
-Übereinstimmungen in der Liste der Plattformgeräte, die entweder von ACPI/DTS
stammt, zurückgegeben wird, wird die driver_probe_device()
aufgerufen, die den Rückruf drv->probe()
enthält.
Die Sondenfunktion wird für jede Schnittstelle des erkannten Geräts aufgerufen, mit Ausnahme der bereits registrierten.
Die Testfunktion wird aufgerufen, wenn name die Formeltreiberstruktur an die Gerätestruktur anpasst. Nachfolgend erwähnt, z. B. für Treiber- und Gerätestruktur.
1: Treiberstruktur
static struct driver your_driver = {
.driver = {
.name = YUR_NAME,
},
z.B.
static struct i2c_driver l3Gd20_driver = {
.driver = {
.name = l3Gd20_gyr,
}
2: Gerätestruktur
static structure device your_devices = {
.name = YUR_NAME,
},
z.B.
static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
{
I2C_BOARD_INFO("l3Gd20_gyr", 0x6a),
},
Hinweis: Wenn der Name (l3Gd20_gyr) von Treiber und Gerät übereinstimmt, wird Ihr Probe aufgerufen.