usb_001

LogBus.java  
/* 
 * Java libusb wrapper
 * Copyright (c) 2005-2006 Andreas Schläpfer <spandi at users.sourceforge.net>
 *
 * http://libusbjava.sourceforge.net
 * This library is covered by the LGPL, read LGPL.txt for details.
 */
package ch.ntb.usb.demo;

import ch.ntb.usb.LibusbJava;
import ch.ntb.usb.Usb_Bus;
import ch.ntb.usb.Utils;

/**
 * Initalises Libusb and prints the bus(ses) with attached devices to the
 * standard out.<br>
 * 
 * 
 * @author schlaepfer
 * 
 */
public class LogBus {

  private static void logBus() {
    // if you don't use the ch.ntb.usb.Device class you must initialise
    // Libusb before use
    LibusbJava.usb_init();
    LibusbJava.usb_find_busses();
    LibusbJava.usb_find_devices();

    // retrieve a object tree representing the bus with its devices and
    // descriptors
    Usb_Bus bus = LibusbJava.usb_get_busses();

    // log the bus structure to standard out
    Utils.logBus(bus);
  }

  public static void main(String[] args) {
    logBus();
  }
}  

 

<think>我们正在分析 `retval = usb_register(&usbfs_driver);` 这行代码,它位于USB核心初始化过程中(如引用[1]所示)。下面将详细解释其作用、流程和调试要点。 ### 1. 代码作用 `usb_register(&usbfs_driver)` 的功能是**注册一个USB设备驱动**,具体是注册 `usbfs_driver` 这个驱动。它的核心目的是: - 为 **USB设备文件系统(usbfs)** 提供支持,使用户空间程序(如libusb)能够通过文件节点(如 `/dev/bus/usb/001/002`)访问USB设备[^1]。 - 实现 **USB设备的动态管理**:当USB设备插入或拔出时,该驱动会响应并创建设备节点(通过 `devtmpfs` 或 `udev`)。 ### 2. 驱动结构解析 `usbfs_driver` 的定义通常如下(简化): ```c static struct usb_device_driver usbfs_driver = { .name = "usbfs", .probe = usbfs_probe, .disconnect = usbfs_disconnect, .supports_autosuspend = 1, }; ``` - **name**:驱动名称,在 `/sys/bus/usb/drivers/` 下可见 - **probe**:设备匹配时的回调函数,负责创建设备节点 - **disconnect**:设备移除时的清理函数 - **supports_autosuspend**:支持USB自动休眠机制 ### 3. 工作流程 #### (1) 注册驱动 ```c retval = usb_register(&usbfs_driver); ``` - 调用 `usb_register_driver()` 将驱动注册到USB总线(`usb_bus_type`)[^2] - 触发USB总线的匹配机制:遍历所有已连接的USB设备,对匹配的设备调用 `.probe` #### (2) 设备匹配与探测 当有USB设备连接时: 1. USB核心检测到设备并添加到总线 2. 总线调用 `usb_device_match()` 匹配驱动(引用[2]) 3. 匹配成功后调用 `usbfs_probe()`: ```c static int usbfs_probe(struct usb_device *udev) { dev_t devnum = MKDEV(USB_MAJOR, udev->devnum); return usb_mkdev(udev, devnum); // 创建设备节点 } ``` - 生成设备号:主设备号 `USB_MAJOR`(通常为180),次设备号 `udev->devnum` - 调用 `device_create()` 在 `/dev` 下创建设备节点(如 `/dev/bus/usb/001/002`) #### (3) 设备移除 当设备拔出时: ```c usbfs_disconnect(struct usb_device *udev) { device_destroy(usb_class, MKDEV(USB_MAJOR, udev->devnum)); } ``` - 销毁对应的设备节点 ### 4. 调试要点 #### (1) 返回值检查 如引用[1]所示,注册失败时跳转到错误处理: ```c retval = usb_register(&usbfs_driver); if (retval) goto driver_register_failed; // 通常打印错误日志并回滚初始化 ``` 常见错误: - **-ENOMEM**:内存不足(如分配 `struct device` 失败) - **-EEXIST**:驱动名称冲突(`usbfs` 已被注册) #### (2) 关键日志 在内核启动参数添加 `usbcore.debug=1` 可打印调试信息: ``` dmesg | grep usbfs [ 12.345] usbfs: registered new driver usbfs [ 12.348] usbfs: probe device 1-2.1 (bus 1, devnum 5) ``` 若未出现注册日志,需检查: - `usb_major_init()` 是否成功(主设备号是否分配) - USB总线是否已注册(`bus_register(&usb_bus_type)` 的返回值) #### (3) 设备节点验证 成功注册后,插入USB设备应出现节点: ```bash ls /dev/bus/usb/001/ 001 002 003 # 数字对应设备的次设备号 ``` 若无节点生成,需排查: - 内核配置是否启用 `CONFIG_USB_DEVICEFS` - 用户空间 `udev` 或 `devtmpfs` 是否正常工作 ### 5.usbfs 的关系 `usbfs_driver` 是 **usbfs 的底层驱动**,但它不直接处理文件操作: - 文件操作(open/read/ioctl)由 `usb_fops` 处理(通过 `usb_major_init()` 注册) - `usbfs_driver` 仅负责**设备节点的生命周期管理** > 注:现代内核中,usbfs 已被 `devtmpfs` 替代,但驱动注册逻辑保留。 ### 6. 错误处理示例 若注册失败,内核初始化会回滚: ```c driver_register_failed: usb_major_cleanup(); // 注销主设备号 bus_unregister_notifier(&usb_bus_type, &usb_bus_nb); bus_notifier_failed: bus_unregister(&usb_bus_type); bus_register_failed: usb_acpi_unregister(); out: return retval; ``` §§相关问题§§ 1. `usbfs_driver` 和普通USB设备驱动(如USB鼠标驱动)有何区别? 2. 如何手动触发 `usbfs_probe` 函数进行调试? 3. USB设备号(主设备号180)冲突时如何解决?</think>### `usb_register(&usbfs_driver)` 详解与调试指南 在 USB 核心初始化流程中(如引用[1]所示),`retval = usb_register(&usbfs_driver)` 是**注册 USB 设备文件系统(usbfs)驱动**的关键步骤。以下是详细解析和调试要点: --- #### 1. 核心作用 ```c retval = usb_register(&usbfs_driver); // 引用[1] ``` - **功能**:向 USB 总线注册 `usbfs_driver` 驱动,实现用户空间通过文件系统访问 USB 设备 - **调用位置**:在 `usb_major_init()`(主设备号初始化)之后,`usb_hub_init()`(集线器初始化)之前 - **返回值**: - **0**:注册成功 - **负值错误码**:注册失败(如内存不足或总线未注册) --- #### 2. 驱动结构解析 `usbfs_driver` 是预定义的全局驱动对象,典型结构如下: ```c static struct usb_device_driver usbfs_driver = { .name = "usbfs", .probe = usbfs_probe, // 设备匹配时调用 .disconnect = usbfs_disconnect, // 设备移除时调用 .supports_autosuspend = 1, // 支持自动休眠 }; ``` - **name**:驱动标识名(在 `/sys/bus/usb/drivers/` 可见) - **probe**:设备匹配时的初始化函数(核心!) - **disconnect**:设备移除时的清理函数 --- #### 3. 工作流程(结合引用) 1. **驱动注册**: ```c retval = usb_register(&usbfs_driver); // 引用[1] ``` - 调用 `driver_register()` 将驱动挂载到 USB 总线(`usb_bus_type`) - 触发总线匹配机制(`usb_device_match`,引用[2]) 2. **设备匹配**: - 当 USB 设备插入时,总线调用 `usb_device_match()` 匹配驱动 - 匹配成功后调用 `.probe` 函数(即 `usbfs_probe`) 3. **文件系统集成**: - 在 `usbfs_probe` 中创建设备节点(如 `/dev/bus/usb/001/002`) - 关联通知链(引用[3]),响应设备热插拔事件: ```c case USB_DEVICE_ADD: // 引用[3] usbfs_add_device(dev); // 添加设备节点 ``` --- #### 4. 调试要点 ##### (1) 返回值检查(关键!) ```c if (retval) goto driver_register_failed; // 引用[1] ``` 常见错误码: - **-ENOMEM**:内存不足(检查 `kmalloc` 调用) - **-EBUSY**:驱动名冲突(检查 `usbfs_driver.name` 唯一性) - **-ENODEV**:USB 总线未注册(确认 `bus_register(&usb_bus_type)` 已成功) ##### (2) 日志跟踪 在内核启动参数添加: ```bash usbcore.debug=1 // 启用 USB 核心调试日志 dmesg | grep usbfs ``` 预期成功日志: ``` [ 12.345] usbfs: registered new driver usbfs [ 12.348] usbfs: probe device 1-2.1 (bus 1, devnum 5) ``` ##### (3) 崩溃排查 若在 `probe` 崩溃: 1. 检查 `usbfs_probe` 函数: ```c static int usbfs_probe(struct usb_device *udev) { dev_t devnum = MKDEV(USB_MAJOR, udev->devnum); // 设备号生成 return device_create(usb_class, NULL, devnum, ...); // 创建设备节点 } ``` 2. 验证依赖项: - 确认 `usb_major_init()` 已成功(主设备号有效) - 检查 `usb_class` 是否在 `usb_init()` 中初始化 ##### (4) 热插拔测试 ```bash # 插入设备后检查节点 ls /dev/bus/usb/001/ # 应出现新设备号 # 触发断开事件(模拟错误) echo 0 > /sys/bus/usb/devices/1-2.1/power/autosuspend_delay_ms ``` --- #### 5. 与相关步骤的关系 在初始化序列中的位置: ```mermaid graph LR A[bus_register] --> B[usb_major_init] --> C[usb_register<br>usbfs_driver] --> D[usb_hub_init] ``` - **前置依赖**:必须等待 `bus_register(&usb_bus_type)` 完成(引用[1],[2]) - **后置动作**:`usbfs_driver` 注册后,USB 集线器才能初始化(`usb_hub_init()`) --- #### 6. 用户空间可见效果 注册成功后: 1. 生成设备节点:`/dev/bus/usb/BBB/DDD` - `BBB`:总线编号 - `DDD`:设备编号 2. 启用 `libusb` 等库的底层访问 3. 在 `/sys/bus/usb/drivers/usbfs` 出现驱动目录 > ⚠️ 注意:现代内核中 `/proc/bus/usb` 已被弃用,优先使用 `/dev/bus/usb`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值