Como carregar meu módulo de driver personalizado no dispositivo USB conectado?

1

Estou escrevendo um pequeno módulo de driver simples para um emblema de LED. Eu segui alguns tutoriais e referências para fazer o trabalho. Todos eles parecem implicar que o módulo será carregado automaticamente quando o dispositivo estiver conectado. No entanto, quando eu executar usb-devices , o dispositivo correspondente tem o driver Driver=usbfs .

Eu tenho outro terminal fazendo um follow em dmesg e não é em nenhum momento cuspindo nenhuma das minhas mensagens de depuração. Quando tento conectar e desconectar isso é o que aparece:

[36078.726962] usb 1-2: USB disconnect, device number 24
[36080.925619] usb 1-2: new full-speed USB device number 25 using xhci_hcd
[36081.067062] usb 1-2: New USB device found, idVendor=0483, idProduct=5750
[36081.067067] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[36081.067071] usb 1-2: Product: CHW20160112 HID
[36081.067075] usb 1-2: Manufacturer: Chuanghongweitech1
[36081.068695] input: Chuanghongweitech1 CHW20160112 HID as /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/0003:0483:5750.0018/input/input40
[36081.069072] hid-generic 0003:0483:5750.0018: input,hidraw2: USB HID v1.10 Device [Chuanghongweitech1 CHW20160112 HID] on usb-0000:00:14.0-2/input0

Meu módulo descarrega / carrega se eu emitir um sudo insmod ledbadge_drv.ko ( rmmod para descarregar) com esta saída para o log:

[36216.554620] ledbadge:, Unloading module. Handler: ledbadge_exit
[36216.554620] ledbadge:, Attempting to deregister USB device.
[36216.554621] usbcore: deregistering interface driver ledbadge
[36216.554647] ledbadge:, Leaving module!
[36217.632615] ledbadge:, Loading module. Handler: ledbadge_init
[36217.632616] ledbadge:, Attempting to register USB device.
[36217.632636] usbcore: registered new interface driver ledbadge

O código do módulo é o seguinte:

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



#define LEDBADGE_VENDOR_ID  0x0483
#define LEDBADGE_PRODUCT_ID 0x5750
#define LEDBADGE_MOD_NAME   "ledbadge"
#define LEDBADGE_DRV_NAME   "ledbadge"


/************* usb operations *************/

/* 
    ledbadge_probe

        called when plugging the USB device */


static int ledbadge_probe(struct usb_interface *interface, const struct usb_device_id *id)
{   
    printk(KERN_NOTICE "Led Badge driver (%04X: %04X) plugged \n", id->idVendor, id->idProduct);
    return 0;
}


/* 
    ledbadge_disconnect

        called when unplugging the USB device */

static void ledbadge_disconnect(struct usb_interface *interface) 
{
    printk(KERN_NOTICE "%s:, ledbage USB device removed", LEDBADGE_DRV_NAME);
}




/************* usb driver *************/

// information required to recognize the device

static struct usb_device_id ledbadge_table [] = {
    {USB_DEVICE(LEDBADGE_VENDOR_ID, LEDBADGE_PRODUCT_ID)},
    { }, // terminating entry
};
MODULE_DEVICE_TABLE(usb, ledbadge_table);


static struct usb_driver ledbadge_driver = {
    .name = LEDBADGE_DRV_NAME,
    .id_table = ledbadge_table,
    .probe = ledbadge_probe,
    .disconnect = ledbadge_disconnect,
};








/************** module definition **************/

/* ledbadge_init

        caled on module loading */

static int __init ledbadge_init(void) 
{
    int ret = -1; 

    printk(KERN_NOTICE "%s:, Loading module. Handler: %s",
             LEDBADGE_MOD_NAME, __FUNCTION__); 

    printk(KERN_NOTICE "%s:, Attempting to register USB device.", LEDBADGE_MOD_NAME); 

    // attempt to register usb device
    ret = usb_register(&ledbadge_driver);

    // log dmesg of status
    if(ret == 0) printk(KERN_NOTICE "%s:, Device registered!", LEDBADGE_MOD_NAME);
    else         printk(KERN_ERR    "%s:, Device registration failed > %d", LEDBADGE_MOD_NAME, ret);

    return ret; 
}

/* ledbadge_exit

        caled on module unloading */

static void __exit ledbadge_exit(void) 
{
    printk(KERN_NOTICE "%s:, Unloading module. Handler: %s",
             LEDBADGE_MOD_NAME, __FUNCTION__); 

    printk(KERN_NOTICE "%s:, Attempting to deregister USB device.", LEDBADGE_MOD_NAME); 

    // attempt to deregister usb device
    usb_deregister(&ledbadge_driver);

    // log dmesg of status
    printk(KERN_NOTICE "%s:, Leaving module!", LEDBADGE_MOD_NAME);
}

module_init(ledbadge_init);
module_exit(ledbadge_exit); 

MODULE_LICENSE("GPL"); 
    
por David Cabrera 26.04.2018 / 21:12

1 resposta

2

Você colocou seu módulo na árvore de diretórios /lib/modules/<your kernel version> e executou depmod depois disso?

Se sim, então o arquivo /lib/modules/<your kernel version>/modules.alias deve ser uma linha como esta:

alias usb:v0483p5750d*dc*dsc*dp*ic*isc*ip*in* ledbadge

Quando o kernel vê um novo dispositivo USB, ele lê seus IDs de fornecedores e produtos e vários outros atributos, e os usa como componentes para um nome de alias de módulo sistematicamente criado, como acima. Em seguida, o kernel faz com que o comando modprobe seja executado (o mecanismo real para isso variou um pouco no histórico do Linux 2.6 e acima) com esse nome de alias. Se modprobe encontrar uma definição de alias que corresponda a ela, o módulo listado nessa definição de alias será carregado.

Acho que a correspondência acontece de forma que a partida mais específica seja vencida. Atualmente, parece que o módulo hid-generic pode estar ganhando seu módulo (supondo que você tenha executado depmod depois de instalar seu módulo), portanto, seu dispositivo ledbadge pode ser um dispositivo de classe USB HID. Portanto, talvez seja necessário também declarar um alias de dispositivo USB HID. Algo assim:

static const struct hid_device_id ledbadge_hid_table[] = {
        {HID_USB_DEVICE(LEDBADGE_VENDOR_ID,LEDBADGE_PRODUCT_ID)},
        { } // terminating entry
};

MODULE_DEVICE_TABLE(hid, ledbadge_hid_table);

A linha resultante no arquivo modules.alias deve ser como:

alias hid:b0003g*v00000483p00005750 ledbadge
    
por 26.04.2018 / 22:19