百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

操作USB时不使用libusb库函数直接使用ioctl的方式

liebian365 2024-10-27 13:21 37 浏览 0 评论

我们需要更深入地了解 Linux 下 USB 设备的底层操作。例如libusb_control_transfer 处理 USB 控制传输,而使用 ioctl 则需要你自己构建控制传输请求并通过 USBDEVFS_CONTROL 命令发送。

1. 打开 USB 设备文件:

你首先需要打开 USB 设备的文件,这个文件通常位于 /dev/bus/usb/BBB/DDD,其中 BBB 是总线号,DDD 是设备号。

int fd = open("/dev/bus/usb/001/002", O_RDWR);
if (fd < 0) {
    perror("Failed to open device");
    return -1;
}

2. 准备 USB 控制传输:

要使用 ioctl 发送 USB 控制传输,你需要构建 usbdevfs_ctrltransfer 结构体来指定传输的参数。

struct usbdevfs_ctrltransfer control;
control.bRequestType = request_type;       // 设置请求类型
control.bRequest = request;                // 设置请求
control.wValue = value;                    // 设置 wValue
control.wIndex = index;                    // 设置 wIndex
control.wLength = length;                  // 设置传输数据长度
control.data = data;                       // 指向数据缓冲区
control.timeout = timeout;                 // 超时时间(毫秒)
  • bRequestType: 请求类型(如标准、类或厂商特定),以及数据传输方向(主机到设备或设备到主机)。
  • bRequest: 请求码,定义了要执行的特定操作(如获取描述符、设置配置等)。
  • wValue: 请求的特定值,通常是描述符索引、配置值等。
  • wIndex: 通常用于指定接口或端点号。
  • wLength: 数据缓冲区的长度,用于指定要传输的数据量。
  • data: 指向要发送的数据缓冲区,或用于接收数据的缓冲区。
  • timeout: 超时时间,单位是毫秒。

3. 发送 ioctl 命令:

使用 ioctl 系统调用来执行控制传输。

int rc = ioctl(fd, USBDEVFS_CONTROL, &control);
if (rc < 0) {
    perror("Control transfer failed");
    close(fd);
    return -1;
}

4. 关闭设备文件:

传输完成后,关闭设备文件描述符。

close(fd);

完整案例代码:

以下是一个完整的示例,展示如何通过 ioctl 实现 USB 控制传输:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/usbdevice_fs.h>
#include <sys/ioctl.h>
#include <errno.h>

int usb_control_transfer(int fd, uint8_t request_type, uint8_t request,
                         uint16_t value, uint16_t index, unsigned char *data,
                         uint16_t length, unsigned int timeout) {
    struct usbdevfs_ctrltransfer control;
    control.bRequestType = request_type;
    control.bRequest = request;
    control.wValue = value;
    control.wIndex = index;
    control.wLength = length;
    control.data = data;
    control.timeout = timeout;

    int rc = ioctl(fd, USBDEVFS_CONTROL, &control);
    if (rc < 0) {
        perror("Control transfer failed");
        return errno;
    }

    return 0;
}

int main() {
    int fd = open("/dev/bus/usb/001/002", O_RDWR);
    if (fd < 0) {
        perror("Failed to open device");
        return -1;
    }

    unsigned char data[8] = {0};
    int rc = usb_control_transfer(fd, 0x80, 0x06, 0x0100, 0x0000, data, sizeof(data), 1000);
    if (rc == 0) {
        printf("Control transfer successful\n");
    }

    close(fd);
    return 0;
}

重要考虑事项:

  • 设备权限:确保你有权限访问设备文件。你可能需要使用 sudo 或调整设备文件的权限。
  • 请求类型和请求码:正确设置 bRequestType 和 bRequest,以确保你发送的请求符合设备的协议。
  • 超时处理:使用合理的超时时间,避免因等待太久而阻塞程序。
  • 错误处理:注意检查 ioctl 的返回值,并正确处理错误情况。
  • 清理工作:每次传输后,确保正确关闭文件描述符。

设备状态管理:

  • 如果设备在传输过程中进入不稳定状态,可以考虑通过 ioctl(fd, USBDEVFS_RESET, 0) 重置设备。
  • 如果端点陷入停滞状态,可以使用 USBDEVFS_CLEAR_HALT 来清除端点的停止状态。

总结:

直接使用 ioctl 进行 USB 控制传输操作可以实现对设备更底层的控制,但也增加了复杂性。如果你的应用需要跨平台支持,继续使用 libusb 可能更合适。

相关推荐

“版本末期”了?下周平衡补丁!国服最强5套牌!上分首选

明天,酒馆战棋就将迎来大更新,也聊了很多天战棋相关的内容了,趁此机会,给兄弟们穿插一篇构筑模式的卡组推荐!老规矩,我们先来看10职业胜率。目前10职业胜率排名与一周前基本类似,没有太多的变化。平衡补丁...

VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符&quot;

首先,程序中头文件的选择,要选择头文件,在文件中是没有对M_PI的定义的。选择:项目——>”XXX属性"——>配置属性——>C/C++——>预处理器——>预处理器定义,...

东营交警实名曝光一批酒驾人员名单 88人受处罚

齐鲁网·闪电新闻5月24日讯酒后驾驶是对自己和他人生命安全极不负责的行为,为守护大家的平安出行路,东营交警一直将酒驾作为重点打击对象。5月23日,东营交警公布最新一批饮酒、醉酒名单。对以下驾驶人醉酒...

Qt界面——搭配QCustomPlot(qt platform)

这是我第一个使用QCustomPlot控件的上位机,通过串口精确的5ms发送一次数据,再将读取的数据绘制到图表中。界面方面,尝试卡片式设计,外加QSS简单的配了个色。QCustomPlot官网:Qt...

大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写

老友相聚,仗剑江湖!《大话西游2》2021全民PK季4月激燃打响,各PK玩法鏖战齐开,零门槛参与热情高涨。PK季期间,不仅各种玩法奖励丰厚,参与PK趣闻录活动,投稿自己在PK季遇到的趣事,还有机会带走...

测试谷歌VS Code AI 编程插件 Gemini Code Assist

用ClaudeSonnet3.7的天气测试编码,让谷歌VSCodeAI编程插件GeminiCodeAssist自动编程。生成的文件在浏览器中的效果如下:(附源代码)VSCode...

顾爷想知道第4.5期 国服便利性到底需优化啥?

前段时间DNF国服推出了名为“阿拉德B计划”的系列改版计划,截至目前我们已经看到了两项实装。不过关于便利性上,国服似乎还有很多路要走。自从顾爷回归DNF以来,几乎每天都在跟我抱怨关于DNF里面各种各样...

掌握Visual Studio项目配置【基础篇】

1.前言VisualStudio是Windows上最常用的C++集成开发环境之一,简称VS。VS功能十分强大,对应的,其配置系统较为复杂。不管是对于初学者还是有一定开发经验的开发者来说,捋清楚VS...

还嫌LED驱动设计套路深?那就来看看这篇文章吧

随着LED在各个领域的不同应用需求,LED驱动电路也在不断进步和发展。本文从LED的特性入手,推导出适合LED的电源驱动类型,再进一步介绍各类LED驱动设计。设计必读:LED四个关键特性特性一:非线...

Visual Studio Community 2022(VS2022)安装图文方法

直接上步骤:1,首先可以下载安装一个VisualStudio安装器,叫做VisualStudioinstaller。这个安装文件很小,很快就安装完成了。2,打开VisualStudioins...

Qt添加MSVC构建套件的方法(qt添加c++11)

前言有些时候,在Windows下因为某些需求需要使用MSVC编译器对程序进行编译,假设我们安装Qt的时候又只是安装了MingW构建套件,那么此时我们该如何给现有的Qt添加一个MSVC构建套件呢?本文以...

Qt为什么站稳c++GUI的top1(qt c)

为什么现在QT越来越成为c++界面编程的第一选择,从事QT编程多年,在这之前做C++界面都是基于MFC。当时为什么会从MFC转到QT?主要原因是MFC开发界面想做得好看一些十分困难,引用第三方基于MF...

qt开发IDE应该选择VS还是qt creator

如果一个公司选择了qt来开发自己的产品,在面临IDE的选择时会出现vs或者qtcreator,选择qt的IDE需要结合产品需求、部署平台、项目定位、程序猿本身和公司战略,因为大的软件产品需要明确IDE...

Qt 5.14.2超详细安装教程,不会来打我

Qt简介Qt(官方发音[kju:t],音同cute)是一个跨平台的C++开库,主要用来开发图形用户界面(GraphicalUserInterface,GUI)程序。Qt是纯C++开...

Cygwin配置与使用(四)——VI字体和颜色的配置

简介:VI的操作模式,基本上VI可以分为三种状态,分别是命令模式(commandmode)、插入模式(Insertmode)和底行模式(lastlinemode),各模式的功能区分如下:1)...

取消回复欢迎 发表评论: