关于“Process xxx called USBDEVFS_CLEAR_HALT for active endpoint xx”

当用户级别的应用错误调用USBDEVFS_CLEAR_HALT导致USB设备异常,尤其是在一个USB键盘接口的Android板上,可能会出现通信混乱。问题源于Linux系统对这种操作的警告。通过分析设备MCU的USB库代码,发现当接收到clear_feature请求时,如果端点未处于stall状态,设备不应响应。修复方案是检查端点状态,仅在stall时响应,避免了异常数据导致的系统紊乱。该问题在国产MCU库中尤为明显,相比STM32等其他品牌,其异常处理不够健壮。

这本来是linux下的问题,由于在用户级的app里调用了驱动函数对usb设备进行了clear halt的操作,linux的开发者于是在log里打印出这个警告,用以提示程序员们:这样做可能有问题!具体请膜拜这个帖子:[PATCH] USB: complain if userspace resets an active endpoint — Linux USB

于是,真的有问题了。我的设备实现了一个usb键盘接口,接在一个android板上,没招谁没惹谁的跑着,偶尔发点数据给上位机而已。突然之间,收到了上位机给的这个clear_halt的请求,于是听话地来了个clear,然后本来好好的通信变得紊乱,链路上的数据直接被当做键盘值丢给主机,从抓取数据上看,完全是不合理的按键的组合,导致android系统瞎响应,随机打开某些app。。。

我真难,真的----linux我还没真正上过项目呢。。后来主板驱动开发人员说,这个命令不是发给你的设备的。。。但为什么我受到了,搞不懂哎。。既然主机那边不归我管,那就练练内功吧,看自己设备mcu的usb库代码。当然少不了mcu的支持朋友啦,人家给了个usb协议分析仪,神器!!确定了,设备真的收到了clear_feature请求,随后就抓到一段乱七八糟的键盘码数据。结合支持方 建议,对usb协议库中对应的代码做了处理:

如果接到clear_feature请求,让usb端点从stall变成active,则先判断,当前端点是否处于stall状态,是则响应,不是则不鸟之。。测试n久,抓数据确定设备在接收到乱命后不再抓狂,搞定!!

思考一下,mcu的usb库看起来不够完善,其本身应该是考虑到上位机不会在设备处于active状态下还会让设备去reset端点,即,usb库的代码对于异常情况考虑不周,不健壮。ps,这里用的是某国产mcu,对比过stm32的库,多数型号的mcu片子的库也没有这个处理哦^_^。

从出问题到解决问题花了小两周时间,各种障碍,没法子。感叹一下,linux的系统一致性问题可能比windows高。

### 回答1: `libusb_clear_halt` 是 `libusb` 库中的一个函数,用于清除 USB 设备上的端点(endpoint)上的暂停(halt)状态。在 USB 通信中,如果在数据传输过程中发生错误,设备会将该端点置为暂停状态,此时需要使用 `libusb_clear_halt` 函数来清除该状态,以便继续进行数据传输。该函数的原型如下: ```c int libusb_clear_halt(libusb_device_handle *dev_handle, unsigned char endpoint); ``` 其中,`dev_handle` 是指向打开的 USB 设备的设备句柄(handle)的指针,`endpoint` 是要清除暂停状态的端点地址。函数返回值为 0 表示成功,否则表示失败。 ### 回答2: libusb_clear_halt 是libusb库中的一个函数,用于清除USB端点的暂停状态。在USB通信过程中,如果某个端点发生错误,例如数据包传输失败或者CRC校验错误,USB主机会将该端点设置为暂停状态,进而导致该端点无法继续进行数据传输。为了恢复端点的正常状态,我们需要使用libusb_clear_halt函数来清除该暂停状态。 使用libusb_clear_halt函数的过程如下:首先我们需要获取与目标USB设备的连接,即打开一个USB设备的会话。然后,我们需要通过libusb_claim_interface函数来声明我们要操作的USB接口。接下来,我们可以使用libusb_clear_halt函数来清除目标USB端点的暂停状态。 libusb_clear_halt函数的参数包括设备会话、端点地址及其方向。通过调用该函数,我们可以成功清除暂停状态,使得端点恢复正常的数据传输。在清除暂停状态后,我们可以继续操作USB设备,进行数据的读取和写入,以实现所需的功能。 总之,libusb_clear_halt是libusb库中一个非常有用的函数,用于清除USB端点的暂停状态,使得USB设备能够恢复正常的数据传输,帮助我们更好地进行USB通信。 ### 回答3: libusb_clear_halt 是一个函数,用于清除 USB 设备上特定端点的暂停状态。在USB通信中,当某个端点出现错误或异常情况时,操作系统会将该端点设置为暂停状态,以便进行错误恢复或重新初始化。 libusb_clear_halt 函数接受一个 libusb_device_handle 对象参数和一个端点地址参数,通过这两个参数可以确定要清除暂停状态的具体端点。 这个函数的作用是将特定端点的暂停状态清除,使其恢复为可用状态,以便继续进行数据传输。调用该函数之前,应先获取对应设备的 libusb_device_handle 对象,并确定要清除暂停状态的端点地址。 libusb_clear_halt 的调用方式如下: ``` int libusb_clear_halt(libusb_device_handle *dev_handle, unsigned char endpoint); ``` 其中,dev_handle 是设备的句柄,即通过 libusb_open()函数打开设备后返回的对象;endpoint 是端点的地址,用于指定清除暂停状态的具体端点。 成功调用 libusb_clear_halt 函数将返回 0,表示清除暂停状态成功。如果返回其他值,表示调用出现错误或端点未处于暂停状态。 总之,libusb_clear_halt 函数可用于清除 USB 设备上特定端点的暂停状态,使其恢复为可用状态,以便继续进行数据传输。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值