LEDバッジ用の小さなシンプルなドライバーモジュールを書いています。私は仕事をするためにいくつかのチュートリアルとリファレンスに従いました。これらはすべて、デバイスが接続されたときにモジュールが自動的にロードされることを意味しているようです。ただし、usb-devices
を実行すると、対応するデバイスにドライバーDriver=usbfs
があります。
dmesg
をフォローしている別の端末がありますが、デバッグメッセージを吐き出すことはありません。接続と切断を試みると、次のように表示されます。
[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
この出力をログに出力してSudo insmod ledbadge_drv.ko
(アンロードの場合はrmmod
)を発行すると、モジュールはアンロード/ロードを実行します。
[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
モジュールのコードは次のとおりです。
#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");
モジュールを/lib/modules/<your kernel version>
ディレクトリツリーに配置し、その後depmod
を実行しましたか?
その場合、/lib/modules/<your kernel version>/modules.alias
ファイルには次のような行が必要です。
alias usb:v0483p5750d*dc*dsc*dp*ic*isc*ip*in* ledbadge
カーネルは新しいUSBデバイスを検出すると、ベンダーIDと製品ID、およびその他のいくつかの属性を読み取り、上記のように体系的に作成されたモジュールエイリアス名のコンポーネントとしてそれらを使用します。次に、カーネルはそのエイリアス名でmodprobe
コマンドを実行します(その実際のメカニズムはLinux 2.6以降の歴史で多少異なります)。 modprobe
がそれに一致するエイリアス定義を見つけると、そのエイリアス定義にリストされているモジュールがロードされます。
マッチングは、最も具体的なマッチが勝つような方法で行われると思います。現在、hid-generic
モジュールがモジュールに勝っている可能性があるようです(モジュールのインストール後にdepmod
を実行したと仮定)。したがって、ledbadgeデバイスはUSBHIDクラスデバイスである可能性があります。そのため、USBHIDデバイスエイリアスも宣言する必要がある場合があります。このようなもの:
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);
modules.alias
ファイルの結果の行は次のようになります。
alias hid:b0003g*v00000483p00005750 ledbadge