保姆级教程:在Firefly RK3568开发板上搞定USB Host与OTG的完整配置流程
刚拿到Firefly RK3568开发板时,USB功能的配置往往是第一个需要攻克的难题。无论是连接键盘鼠标、外接存储设备,还是进行设备间的数据传输,USB Host和OTG模式都是嵌入式开发中最基础却最容易出问题的环节。本文将带你从硬件引脚配置、设备树修改到内核编译与功能验证,一步步完成RK3568开发板的USB功能配置,避开那些新手常踩的坑。
1. 硬件准备与引脚配置
在开始修改设备树之前,我们需要先了解RK3568开发板的USB电源控制逻辑。以常见的Firefly-RK3568开发板为例,USB3.0 Host和OTG的5V电源分别由不同的GPIO控制:
- USB3.0 Host:VCC5V_USB3由GPIO1_D4控制
- USB2.0 OTG:OTG5V由GPIO0_A5控制(通常默认已使能)
实际操作中,我们需要在设备树的pinctrl节点中添加以下配置:
usb { vcc5v0_host_en: vcc5v0-host-en { rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; }; vcc5v0_otg_en: vcc5v0-otg-en { rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; }; };注意:不同开发板的GPIO控制引脚可能不同,务必查阅具体板子的原理图确认。
2. 设备树关键节点配置
RK3568的USB控制器主要包括USB3.0 DRD(Dual Role Device)和USB3.0 Host两部分。我们需要在设备树中正确配置这些节点。
2.1 USB3.0 DRD控制器配置
USB3.0 DRD控制器支持OTG功能,可以在Host和Device模式间切换:
usbdrd30: usbdrd { compatible = "rockchip,rk3568-dwc3", "rockchip,rk3399-dwc3"; clocks = <&cru CLK_USB3OTG0_REF>, <&cru CLK_USB3OTG0_SUSPEND>, <&cru ACLK_USB3OTG0>, <&cru PCLK_PIPE>; clock-names = "ref_clk", "suspend_clk", "bus_clk", "pipe_clk"; #address-cells = <2>; #size-cells = <2>; ranges; status = "okay"; usbdrd_dwc3: dwc3@fcc00000 { compatible = "snps,dwc3"; reg = <0x0 0xfcc00000 0x0 0x400000>; interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; dr_mode = "otg"; phys = <&u2phy0_otg>, <&combphy0_us PHY_TYPE_USB3>; phy-names = "usb2-phy", "usb3-phy"; phy_type = "utmi_wide"; power-domains = <&power RK3568_PD_PIPE>; resets = <&cru SRST_USB3OTG0>; reset-names = "usb3-otg"; snps,dis_enblslpm_quirk; snps,dis-u1-entry-quirk; snps,dis-u2-entry-quirk; status = "okay"; }; };2.2 USB3.0 Host控制器配置
独立的USB3.0 Host控制器配置如下:
usbhost30: usbhost { compatible = "rockchip,rk3568-dwc3", "rockchip,rk3399-dwc3"; clocks = <&cru CLK_USB3OTG1_REF>, <&cru CLK_USB3OTG1_SUSPEND>, <&cru ACLK_USB3OTG1>, <&cru PCLK_PIPE>; clock-names = "ref_clk", "suspend_clk", "bus_clk", "pipe_clk"; #address-cells = <2>; #size-cells = <2>; ranges; status = "okay"; usbhost_dwc3: dwc3@fd000000 { compatible = "snps,dwc3"; reg = <0x0 0xfd000000 0x0 0x400000>; interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>; dr_mode = "host"; phys = <&u2phy0_host>, <&combphy1_usq PHY_TYPE_USB3>; phy-names = "usb2-phy", "usb3-phy"; phy_type = "utmi_wide"; power-domains = <&power RK3568_PD_PIPE>; resets = <&cru SRST_USB3OTG1>; reset-names = "usb3-host"; snps,dis_enblslpm_quirk; status = "okay"; }; };3. 内核配置与编译
设备树修改完成后,我们需要确保内核配置正确并重新编译:
首先检查内核配置:
make menuconfig确保以下选项已启用:
CONFIG_USB=yCONFIG_USB_XHCI_HCD=yCONFIG_USB_XHCI_PLATFORM=yCONFIG_USB_DWC3=yCONFIG_USB_DWC3_HOST=yCONFIG_USB_DWC3_GADGET=yCONFIG_USB_DWC3_DUAL_ROLE=y
编译设备树:
make ARCH=arm64 dtbs编译内核:
make ARCH=arm64 -j$(nproc)
提示:如果遇到
dwc3相关驱动编译错误,可能是内核版本与DWC3驱动不兼容,可以尝试更新内核或调整配置选项。
4. 功能验证与问题排查
烧录新编译的内核和设备树后,可以通过以下步骤验证USB功能:
4.1 Host模式验证
插入USB设备(如鼠标、U盘)后,查看内核日志:
dmesg | grep usb正常应该看到类似以下输出:
[ 2.385741] usb 1-1: new high-speed USB device number 2 using xhci-hcd [ 2.543821] usb 1-1: New USB device found, idVendor=0930, idProduct=65454.2 OTG模式验证
将开发板通过USB-C接口连接到电脑,检查是否被识别为设备:
lsusb应该能看到Rockchip USB设备的相关信息。
4.3 常见问题排查
USB设备无反应:
- 检查5V电源是否正常输出
- 测量GPIO控制引脚电平是否正确
- 确认设备树中
status = "okay"
内核报错
dwc3相关错误:- 检查PHY时钟配置
- 确认DWC3驱动已正确编译进内核
OTG模式无法切换:
- 确认
dr_mode设置为otg - 检查ID引脚检测电路
- 确认
5. 高级配置与优化
对于需要深度定制USB功能的开发者,还可以考虑以下配置:
5.1 USB电源管理
在设备树中添加USB电源控制节点,实现动态电源管理:
vcc5v0_usb: vcc5v0-usb { compatible = "regulator-fixed"; regulator-name = "vcc5v0_usb"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; gpio = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&vcc5v0_host_en>; enable-active-high; };5.2 USB性能优化
调整DWC3控制器参数提升传输性能:
usbdrd_dwc3: dwc3@fcc00000 { /* ...其他配置... */ snps,usb3_lpm_capable; snps,dis_u2_susphy_quirk; snps,dis_u3_susphy_quirk; tx-fifo-resize; };5.3 多USB端口配置
对于具有多个USB端口的开发板,需要为每个端口单独配置PHY:
&u2phy0_host { status = "okay"; }; &u2phy0_otg { status = "okay"; }; &combphy0_us { status = "okay"; };在实际项目中,我发现最常出问题的环节是PHY时钟的配置和GPIO控制引脚的初始化顺序。建议在修改设备树后,先用fdtdump工具检查编译后的dtb文件,确认配置已正确应用。