lsusb命令在arm上的移植

嵌入式Linux USB工具编译指南
本文介绍如何在嵌入式Linux环境下从源码编译安装libusb-0.1.10及usbutils-0.80,包括环境配置、编译过程中的常见问题解决方法以及将编译好的工具移植到开发板的过程。

1、下载源码:

     #wget http://dist.momonga-linux.org/pub/momonga/2/SOURCES/libusb-0.1.10.tar.gz

     #wget http://down1.chinaunix.net/distfiles/usbutils-0.80.tar.gz

      其中libusb分为1.0版和0.1版两种版本,1.0并不向下兼容0.1,需要libusb-compat的支持;因此,你可以同时装上1.0和0.1,但不可同时装0.1版和libusb-compat。详见:http://www.libusb.org/

     usbutils 是Linux下查看usb设备信息的工具

2、解压:  

  1)tar -xvf usbutils-0.80.tar.gz   

  2)tar -xvf libusb-0.1.10.tar.gz

3、设环境变量(可省略): 

  export PATH=/usr/local/arm /4.5.1/arm-linux/bin/:$PATH

4、编译:   

  #cd  libusb-0.1.10

  #./configure CC=arm-linux-gcc--prefix="$PWD/../_install" --host=arm-linux

       #make install

       #cd ..

       #cd usbutils-0.80

       #./configure CC=arm-linux-gcc --host=arm-linux

LIBUSB_CFLAGS="$PWD/../_install/include/"LIBUSB_LIBS="$PWD/../_install/lib/libusb.so"

CPPFLAGS=-I"$PWD/../_install/include/"

CFLAGS="-O2"

      #make

5、修改错误

      如在编译libusb时出现错误usbpp.cpperror:'printf' was not declared in this scope,就在usbpp.cpp文件开头部分中添加头文件#include <stdio.h>

6、复制到开发板

     经过上面编译成功后,命令lsusb就出来了,就是位于usbutils-0.80目录下的lsusb可执行文件,将其复制到开发板文件系统中的bin目录中。

驱动开发向来是内核开发中工作量最多的一块,随着USB设备的普及,大量的USB设备的驱动开发也成为驱动开发者手头上做的最多的事情。本文主要介绍Linux平台下基于libusb的驱动开发,希望能够给从事Linux驱动开发的朋友带来些帮助,更希望能够给其他平台上的无驱设计带来些帮助。文章是我在工作中使用libusb的一些总结,难免有错误,如有不当的地方,还请指正。 [1]   Linux 平台上的usb驱动开发,主要有内核驱动的开发和基于libusb的无驱设计。   对于内核驱动的大部分设备,诸如带usb接口的hid设备,linux本身已经自带了相关的驱动,我们只要操作设备文件便可以完成对设备大部分的操作,而另外一些设备,诸如自己设计的硬件产品,这些驱动就需要我们驱动工程师开发出相关的驱动了。内核驱动有它的优点,然而内核驱动在某些情况下会遇到如下的一些问题:   1 当使用我们产品的客户有2.4内核的平台,同时也有2.6内核的平台,我们要设计的驱动是要兼容两个平台的,就连makefile 我们都要写两个。   2 当我们要把linux移植到嵌入平台上,你会发现原先linux自 带的驱动移过去还挺大的,我的内核当然是越小越好拉,这样有必要么。这还不是最郁闷的地方,如果嵌入平台是客户的,客户要购买你的产品,你突然发现客户设 备里的系统和你的环境不一样,它没有你要的驱动了,你的程序运行不了,你会先想:“没关系,我写个内核驱动加载一下不就行了“。却发现客户连insmod加载模块的工具都没移植,那时你就看看老天,说声我怎么那么倒霉啊,客户可不想你动他花了n时间移植的内核哦   3 花了些功夫写了个新产品的驱动,挺有成就感啊,代码质量也是相当的有水准啊。正当你沉醉在你的代码中时,客服不断的邮件来了,“客户需要2.6.5内核的驱动,config文件我已经发你了” “客户需要双核的 2.6.18-smp 的驱动” “客户的平台是自己定制的是2.6.12-xxx “ 你恨不得把驱动的源代码给客户,这样省得编译了。你的一部分工作时间编译内核,定制驱动   有问题产生必然会有想办法解决问题的人, libusb的出现给我们带来了某些方便,即节约了我们的时间,也降低了公司的成本。 所以在一些情况下,就可以考虑使用libusb的无驱设计了。   下面我们就来详细讨论一下libusb, 并以写一个hid设备的驱动来讲解如何运用libusb,至于文章中涉及的usb协议的知识,限于篇幅,就不详细讲解了,相关的可自行查看usb相关协议。   一 libusb 介绍   libusb 设计了一系列的外部API 为应用程序所调用,通过这些API应用程序可以操作硬件,从libusb的源代码可以看出,这些API 调用了内核的底层接口,和kernel driver中所用到的函数所实现的功能差不多,只是libusb更加接近USB 规范。使得libusb的使用也比开发内核驱动相对容易的多。   Libusb 的编译安装请查看Readme,这里不做详解   二 libusb 的外部接口   2.1 初始化设备接口   这些接口也可以称为核心函数,它们主要用来初始化并寻找相关设备。   usb_init   函数定义: void usb_init(void);   从函数名称可以看出这个函数是用来初始化相关数据的,这个函数大家只要记住必须调用就行了,而且是一开始就要调用的.   usb_find_busses   函数定义: int usb_find_busses(void);   寻找系统上的usb总线,任何usb设备都通过usb总线和计算机总线通信。进而和其他设备通信。此函数返回总线数。   usb_find_devices   函数定义: int usb_find_devices(void);   寻找总线上的usb设备,这个函数必要在调用usb_find_busses()后使用。以上的三个函数都是一开始就要用到的,此函数返回设备数量。   usb_get_busses   函数定义: struct usb_bus *usb_get_busses(void);   这个函数返回总线的列表,在高一些的版本中已经用不到了,这在下面的实例中会有讲解   2.2 操作设备接口   usb_open   函数定义: usb_dev_handle *usb_open(struct *usb_device dev);   打开要使用的设备,在对硬件进行操作前必须要调用usb_open 来打开设备,这里大家看到有两个结构体 usb_dev_handle 和 usb_device 是我们在开发中经常碰到的,有必要把它们的结构看一看。在libusb 中的usb.h和usbi.h中有定义。   这里我们不妨理解为返回的 usb_dev_handle 指针是指向设备的句柄,而行参里输入就是需要打开的设备。   usb_close   函数定义: int usb_close(usb_dev_handle *dev);   与usb_open相对应,关闭设备,是必须调用的, 返回0成功,<0 失败。   usb_set_configuration   函数定义: int usb_set_configuration(usb_dev_handle *dev, int configuration);   设置当前设备使用的configuration,参数configuration 是你要使用的configurtation descriptoes中的bConfigurationValue, 返回0成功,<0失败( 一个设备可能包含多个configuration,比如同时支持高速和低速的设备就有对应的两个configuration,详细可查看usb标准)   usb_set_altinterface   函数定义: int usb_set_altinterface(usb_dev_handle *dev, int alternate);   和名字的意思一样,此函数设置当前设备配置的interface descriptor,参数alternate是指interface descriptor中的bAlternateSetting。返回0成功,<0失败   usb_resetep   函数定义: int usb_resetep(usb_dev_handle *dev, unsigned int ep);   复位指定的endpoint,参数ep 是指bEndpointAddress,。这个函数不经常用,被下面介绍的usb_clear_halt函数所替代。   usb_clear_halt   函数定义: int usb_clear_halt (usb_dev_handle *dev, unsigned int ep);   复位指定的endpoint,参数ep 是指bEndpointAddress。这个函数用来替代usb_resetep   usb_reset   函数定义: int usb_reset(usb_dev_handle *dev);   这个函数现在基本不怎么用,不过这里我也讲一下,和名字所起的意思一样,这个函数reset设备,因为重启设备后还是要重新打开设备,所以用usb_close就已经可以满足要求了。   usb_claim_interface   函数定义: int usb_claim_interface(usb_dev_handle *dev, int interface);   注册与操作系统通信的接口,这个函数必须被调用,因为只有注册接口,才能做相应的操作。   Interface 指 bInterfaceNumber. (下面介绍的usb_release_interface 与之相对应,也是必须调用的函数)   usb_release_interface   函数定义: int usb_release_interface(usb_dev_handle *dev, int interface);   注销被usb_claim_interface函数调用后的接口,释放资源,和usb_claim_interface对应使用。   2.3 控制传输接口   usb_control_msg   函数定义:int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout);   从默认的管道发送和接受控制数据   usb_get_string   函数定义: int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, size_t buflen);   usb_get_string_simple   函数定义: int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen);   usb_get_descriptor   函数定义: int usb_get_descriptor(usb_dev_handle *dev, unsigned char type, unsigned char index, void *buf, int size);   usb_get_descriptor_by_endpoint   函数定义: int usb_get_descriptor_by_endpoint(usb_dev_handle *dev, int ep, unsigned char type, unsigned char index, void *buf, int size);   2.4 批传输接口   usb_bulk_write   函数定义: int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);   usb_interrupt_read   函数定义: int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);   2.5 中断传输接口   usb_bulk_write   函数定义: int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);   usb_interrupt_read   函数定义: int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);
<think>首先,用户的问题是关于在ARM架构的Linux系统上为联发科MT7921U芯片安装或配置驱动程序。具体问题是:“请问联发科 MT7921U ARM Linux 驱动安装配置”。 我需要遵循系统级指令: 1. **行内数学表达式**:使用 `$...$` 格式。但在这个主题中,可能没有数学表达式,所以我会注意如果有的话。 2. **独立公式**:使用 `$$...$$` 并单独成段。同样,可能不适用。 3. **LaTeX语法正确**:确保所有LaTeX格式正确。 4. **使用中文回答**:整个回答必须用中文。 5. **生成相关问题**:在回答结束后,添加一个“相关问题”部分,列出几个相关问题。 6. **引用标识**:在回答中引用的段落末尾自然地添加引用标识,如 `[^1]`。用户提供了引用[1]、[2]、[3],我需要基于这些引用内容来构建回答。 用户可见层指令: - 回答结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠。 参考引用内容: - 引用[1]:讨论MTK芯片的Linux移植和驱动移植,包括步骤如获取源代码、配置内核、编译内核、部署内核、启动测试、驱动移植等。 - 引用[2]:关于MT7601WIFI驱动的安装,包括下载源码包和设置Makefile。 - 引用[3]:关于安装MT7601U无线网卡驱动,提到硬件ID和驱动识别问题。 用户的问题是针对MT7921U芯片,不是MT7601。我需要确保回答是针对MT7921U的。引用中提到了MT7601,但用户的问题是关于MT7921U。我应该基于一般原理来回答,因为引用可能不直接匹配。 用户说:“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。” 但在这个上下文中,没有提到上一次问题。所以,我专注于当前问题。 结构回答: 1. **引言**:简要介绍主题。 2. **步骤**:逐步指导如何安装和配置驱动程序。 - 基于引用[1],步骤包括:获取源代码、配置内核、编译、部署、测试。 - 引用[2]提到下载源码包和设置Makefile。 - 引用[3]提到硬件ID问题。 3. **具体针对MT7921U**:我需要推断或一般化,因为引用是针对MT7601,但原理类似。MT7921U是较新的芯片,可能驱动在Linux内核中可用或需要下载。 4. **真实可靠**:确保信息准确。MT7921U驱动可能已在Linux内核主线支持,或者需要从联发科获取。 快速搜索知识:MT7921U是联发科的Wi-Fi 6芯片。在Linux中,驱动可能包括在主线内核,如`mt7921u`模块。用户应检查内核版本。 在回答中,建议用户: - 检查内核版本是否支持MT7921U。 - 如果需要,从联发科下载驱动。 - 编译和安装步骤。 5. **添加引用标识**:当引用参考内容时,在末尾加 `[^1]` 等。 6. **相关问题**:在结束时生成相关问题。 回答结构: - **标题**:清晰,如“联发科 MT7921U ARM Linux 驱动安装配置指南”。 - **步骤**: 1. 准备工作:确保系统环境。 2. 获取驱动源代码。 3. 配置和编译驱动。 4. 加载驱动和测试。 5. 常见问题解决。 - **代码块**:如果需要,提供示例命令。 - **结尾**:添加相关问题。 使用中文回答。 生成相关问题: 1. 如何验证MT7921U驱动是否正常工作? 2. 在编译驱动时遇到错误怎么办? 3. MT7921U驱动支持哪些特性? 4. 如何优化MT7921U驱动的性能? 确保回答基于引用: - 引用[1]:通用驱动移植步骤。 - 引用[2]:下载源码和Makefile设置。 - 引用[3]:硬件ID问题。 所以,在回答中融入这些。</think>### 联发科 MT7921U ARM Linux 驱动安装配置指南 在 ARM 架构的 Linux 系统上为联发科 MT7921U 芯片安装或配置驱动程序,需要遵循 Linux 驱动移植和安装的基本步骤。MT7921U 是一款支持 Wi-Fi 6 的无线网卡芯片,其驱动可能已集成在较新的 Linux 内核中(5.10 或更高版本),但如果内核不支持或需要自定义配置,则需要从源码编译安装。以下步骤基于联发科芯片驱动移植的通用流程[^1],并结合 MT7921U 的具体情况。整个过程包括:准备工作、获取驱动源码、编译驱动、加载驱动和测试。确保您的系统具备 ARM 交叉编译工具链(如 `gcc-arm-linux-gnueabihf`)和必要依赖(如 `build-essential`、`linux-headers`)。 #### 1. **准备工作:检查系统环境和内核支持** - 确认您的 Linux 系统运行在 ARM 架构上(例如树莓派或嵌入式开发板)。使用命令检查: ```bash uname -a # 查看架构和内核版本 ``` 如果输出显示 `ARM` 且内核版本 >= 5.10,MT7921U 驱动可能已内置(模块名为 `mt7921u`)。检查驱动是否可用: ```bash lsmod | grep mt7921u # 查看驱动是否加载 ``` 如果未加载,尝试加载: ```bash sudo modprobe mt7921u ``` 如果失败,说明驱动未编译或内核不支持,需手动安装源码驱动[^1]。 - 安装编译依赖: ```bash sudo apt update sudo apt install build-essential linux-headers-$(uname -r) git ``` #### 2. **获取驱动源代码** - **如果内核已支持**:跳过此步,直接使用内置驱动。否则,从联发科官网或 Linux 内核源码获取驱动。联发科通常提供专用驱动包,但需注意 MT7921U 的驱动可能包含在 `mt76` 项目中(开源 Wi-Fi 驱动栈)。 - 从官方源下载(推荐): ```bash git clone https://github.com/openwrt/mt76.git # MT76 驱动仓库,包含 MT7921U 支持 cd mt76 ``` 或从联发科官网下载(需注册账户),但官网可能不直接提供 MT7921U 驱动包;参考类似驱动(如 MT7601)的源码获取方式[^2]。 - 验证源码:确保下载的源码包含 `mt7921` 目录(驱动核心代码)。 #### 3. **配置和编译驱动** - 进入源码目录并配置编译环境。基于联发科驱动移植流程,需设置 Makefile 和内核路径[^1][^2]。 ```bash cd mt76 # 假设进入驱动源码根目录 make clean # 清理旧编译文件 ``` - 编辑 Makefile(如果需要):类似 MT7601 驱动,需指定目标平台和模式。在 Makefile 中设置: ```makefile MODE = STA # 设置为 STA(站点模式),适用于客户端设备 TARGET = LINUX # 目标系统为 Linux ``` 如果源码已预设,通常无需修改。 - 编译驱动: ```bash make -C /lib/modules/$(uname -r)/build M=$(pwd) modules # 使用当前内核头文件编译 ``` 编译成功后,生成 `mt7921u.ko`(驱动模块文件)。 - **交叉编译注意事项**:如果主机系统非 ARM(如 x86 编译后部署到 ARM),需指定交叉编译工具链: ```bash make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C /path/to/kernel/source M=$(pwd) modules ``` 其中 `/path/to/kernel/source` 是 ARM 内核源码路径。 #### 4. **加载驱动和测试** - 安装驱动模块: ```bash sudo make -C /lib/modules/$(uname -r)/build M=$(pwd) modules_install # 安装到系统模块目录 sudo depmod -a # 更新模块依赖 sudo modprobe mt7921u # 加载驱动 ``` - 如果加载失败,检查硬件 ID:MT7921U 的 USB ID 应为 `0e8d:7961`。使用 `lsusb` 命令验证设备是否被识别: ```bash lsusb | grep 0e8d:7961 ``` 如果输出为空,设备可能未连接或 ID 不匹配;参考类似问题,需在驱动代码中添加 ID(编辑源码中的设备 ID 表)[^3]。 - 测试驱动功能: ```bash dmesg | grep mt7921u # 查看内核日志,确认驱动初始化和硬件检测 iwconfig # 检查无线接口(如 wlan0)是否出现 sudo ifconfig wlan0 up # 启用接口 ``` 如果接口正常,使用 `nmcli` 或 `iwlist` 扫描网络测试连接。 #### 5. **常见问题解决** - **驱动加载失败**:可能因内核版本不兼容。尝试升级内核或从联发科获取专用驱动包。 - **硬件未识别**:如果 `lsusb` 显示不同 ID(如制造商标识符),需修改驱动源码的 ID 表(参考 MT7601U 的解决方式)[^3]。 - **编译错误**:确保 `linux-headers` 与运行内核版本一致;错误通常因依赖缺失或工具链问题。 - **性能优化**:在 `make menuconfig` 中调整内核配置(如启用 CONFIG_MT7921U_DEBUG 用于调试)[^1]。 #### 总结 以上步骤基于联发科芯片驱动移植的通用流程[^1],并结合 MT7921U 的特性。如果您的内核较新(>=5.15),驱动可能已内置,优先尝试 `modprobe mt7921u`。整个过程涉及源码获取、编译和测试,确保操作在 root 权限下进行。如果遇到问题,提供 `dmesg` 日志有助于进一步诊断。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值