linux-kernel - command to know kernel version in linux
QuiƩn llama a la sonda() del controlador (6)
Consideremos un ejemplo de un platform device driver
:
La función de inicio de disparador para la devolución de llamada
module_init()
driver->probe()
es la macromodule_init()
llamada mientras se carga el controlador; estamacro
se define eninclude/linux/module.h
.module_init(my_driver_init)
tiene la devolución de llamada a la funciónmy_driver_init()
.my_driver_init()
funciónmy_driver_init()
debería tener una llamada aplatform_driver_register(my_driver)
platform_driver_register(my_driver)
asignamy_driver -> probe()
handle a genéricodrv -> probe()
y llama a la funcióndriver_register(my_driver)
.driver_register(my_driver)
agregamy_driver
al bus de plataforma y llama a la funcióndriver_attach()
.De la misma manera, incluso el
platform_device
necesita conectarse al bus de la plataforma.Finalmente, solo si el
driver_match_device()
devuelve éxito basado en.name
&.id_table
de las coincidencias deldriver
en la lista de dispositivos de plataforma que proviene deACPI/DTS
, entonces sedriver_probe_device()
aldriver_probe_device()
que tiene eldrv->probe()
devolución de llamada.
¿Cómo se llama a la llamada probe()
? ¿Quién lo llama? Según tengo entendido, __init()
registra el driver
y luego se __init()
algún modo a probe()
para register
los datos del dispositivo y el irq
etc. ¿Cómo sucede exactamente?
Estoy trabajando en el controlador de pantalla táctil y su __init
registra en el i2c driver
. Luego, la sonda espera datos i2c_clien
t que devuelve null. Quiero rastrear dónde se llena.
He preparado un gráfico que rastrea la función de sonda de la plataforma. Está trabajando con el controlador I2C, que AFAIK es un controlador de plataforma. Espero que esto te ayude a rastrear el problema.
Además, consulte el siguiente enlace para ver la discusión sobre kernelnewbies.
https://www.mail-archive.com/kernelnewbies%40kernelnewbies.org/msg12423.html
Para abreviar: la función probe () del controlador se llama como resultado de llamar al controlador de register_driver
para ese bus específico. Más precisamente, es llamado por la probe()
de esa estructura de tipo bus_type
. En tu caso: i2c_bus_type
.
Aquí está la cadena de llamadas en su caso I2C:
- i2c_register_driver
- driver_register
- bus_add_driver
- driver_attach
- __driver_attach (para su dispositivo)
- driver_probe_device
- really_probe
- i2c_device_probe (esto es lo que dev-> bus-> sonda es para un controlador i2c)
- your_probe_function
Se llamará a la función de sonda cuando el nombre coincida con la estructura de los controladores de forma a la estructura del dispositivo. A continuación se menciona, por ejemplo, para el controlador y la estructura del dispositivo.
1: estructura del conductor
static struct driver your_driver = {
.driver = {
.name = YUR_NAME,
},
p.ej.
static struct i2c_driver l3gd20_driver = {
.driver = {
.name = l3gd20_gyr,
}
2: estructura del dispositivo
static structure device your_devices = {
.name = YUR_NAME,
},
p.ej.
static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
{
I2C_BOARD_INFO("l3gd20_gyr", 0x6a),
},
Nota: Cuando el nombre (l3gd20_gyr) del controlador y dispositivo coincida, su sonda recibirá una llamada.
Se solicitará la función de sonda para cada interfaz del dispositivo detectado, excepto las que ya están registradas.
@iSegFault : se llamará a probe () para asegurarse de que el dispositivo existe y la funcionalidad es buena. Si el dispositivo no es de acoplamiento activo, la funcionalidad de probe () se puede poner dentro del método init (). Esto reducirá el tiempo de ejecución del controlador huella de memoria. link PS
La sonda () ocurre al momento del inicio del dispositivo o cuando el dispositivo está conectado. Para un dispositivo de "plataforma", la función de sondeo se invoca cuando se registra un dispositivo de plataforma y su nombre coincide con el nombre especificado en el controlador del dispositivo. link PS
La función i2c_detect prueba el adaptador I2C, buscando las diferentes direcciones especificadas en la estructura addr_data. Si se encuentra un dispositivo, se llama a la función chip_detect. link PS
Un enlace que seguramente despejará su duda. link PS
En kernel 2.4.29, puedo mostrarle cómo ocurre la sonda. Por favor, ver más abajo (Nombre de archivo: drivers / bell / 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
};
Nombre de archivo: 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;
}
Pocos enlaces importantes:
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-device-driver
En PCI para kernel-2.4.29, se llama cuando se identifican la identificación del proveedor y del dispositivo. El controlador de bus PCI hace esto por usted. Por favor vea el siguiente código:
Nombre de archivo: 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;
}