Linux USB 子系统(三): 通过 USBFS 操作设备的用户空间驱动
介绍
在 Linux 上,USB 设备被连接到系统后,内核会根据设备的类别和 ID 进行识别和自动加载驱动模块,从而让其能够正常使用。一般情况下,我们编写的用户空间应用程序只需要与内核交互,而不需要直接操作设备。
但是,有些情况下,我们需要在用户空间直接操作 USB 设备,比如要调试驱动的实现,该设备的驱动程序不存在等等情况。此时,我们可以使用 USB 文件系统 (USBFS) 在用户空间中操作 USB 设备。
USBFS
USBFS 是一种虚拟文件系统,由内核提供,可以让用户空间程序访问 USB 子系统以及 USB 设备。USBFS 在根据 USB 设备的 class 和 subclass 进行自动挂载时,会在 /proc/bus/usb 下创建相应的 USB 设备文件:
/proc/bus/usb/001/001
/proc/bus/usb/001/002
...
其中 /proc/bus/usb/001
表示 USB 控制器的端口号,001
表示该端口上的第一个设备的设备号,002
表示第二个设备的设备号,以此类推。
操作流程
操作流程如下:
- 打开 USB 设备
在用户空间可以使用 open()
函数打开 USB 设备文件,比如:
int fd;
fd = open("/proc/bus/usb/001/001", O_RDWR);
if (fd < 0) {
perror("open");
exit(1);
}
- 获取设备描述符
打开 USB 设备之后,我们需要获取设备描述符,可以使用 ioctl()
函数,调用 USBDEVFS_CONTROL
命令,获取设备描述符:
int ret;
struct usbdevfs_ctrltransfer ctrl;
unsigned char buf[256];
ctrl.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
ctrl.wValue = cpu_to_le16(USB_DT_DEVICE << 8);
ctrl.wIndex = 0;
ctrl.data = buf;
ctrl.wLength = 18;
ret = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
if (ret < 0) {
perror("ioctl");
exit(1);
}
通过上面的代码,可以获取设备描述符,存放在 buf
数组中。设备描述符的具体格式可以参考 USB 规范。
- 发送控制命令
如果需要给 USB 设备发送控制命令,可以使用 ioctl()
函数,调用 USBDEVFS_CONTROL
命令,发送控制命令:
int ret;
struct usbdevfs_ctrltransfer ctrl;
ctrl.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
ctrl.bRequest = 0x11;
ctrl.wValue = 0x1234;
ctrl.wIndex = 0;
ctrl.data = NULL;
ctrl.wLength = 0;
ret = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
if (ret < 0) {
perror("ioctl");
exit(1);
}
通过上面的代码,可以给 USB 设备发送一个 vendor 命令,命令值为 0x11
,参数为 0x1234
。
- 读取、写入数据
如果需要读取或写入 USB 设备的数据,可以使用 read()
和 write()
函数读写 USB 设备文件。
int ret;
unsigned char buf[64];
ret = read(fd, buf, sizeof(buf));
if (ret < 0) {
perror("read");
exit(1);
}
ret = write(fd, buf, sizeof(buf));
if (ret < 0) {
perror("write");
exit(1);
}
- 关闭 USB 设备
最后,需要使用 close()
函数关闭 USB 设备文件:
close(fd);
总结
通过 USBFS,在用户空间中可以直接操作 USB 设备,实现 USB 设备的调试、测试等功能。但是需要注意的是,这种方式并不安全,因为用户空间程序可以直接修改 USB 设备的寄存器等数据。
因此,如果需要在用户空间中编写 USB 设备驱动程序,建议使用更加安全的 libusb
库。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:linuxusb子系统(三):通过usbfs操作设备的用户空间驱动 - Python技术站