1. 从“一根线”到“两种角色”:理解USB OTG的核心玩法
玩嵌入式开发板,尤其是像F1C200S这种资源紧凑但功能齐全的芯片,USB接口绝对是我们的“瑞士军刀”。你可能已经用它来连接U盘、鼠标键盘,或者通过USB转串口线进行调试。但有没有想过,为什么我们插上U盘,板子就能读取数据,而插上电脑,板子又能被识别为一个设备?这背后就是USB的“主从”模式在起作用。
简单来说,USB世界里有两个角色:Host(主机) 和 Device(从设备)。你可以把Host想象成电脑的USB口,它负责提供电源、发起和控制数据传输,比如读取U盘里的文件。而Device则是U盘、鼠标这类“听话”的设备,它们响应Host的命令。我们平时用的电脑,它的USB口天生就是Host模式。
那F1C200S的USB接口是什么角色呢?答案是:它天生是OTG(On-The-Go)。OTG是个“两面派”,它既能当Host,也能当Device,具体扮演哪个角色,可以通过硬件或软件来切换。这就像你手机上的Type-C口,既能给电脑传文件(Device模式),也能插U盘读照片(Host模式)。
在F1C200S的硬件设计里,通常会有一个叫usb0_id_det的引脚(比如PE2)来决定初始角色。如果这个引脚被硬件拉高,上电后默认就是Device模式;如果拉低,就是Host模式。很多开发板为了兼容烧录工具(比如sunxi-tool),会默认把这个引脚拉高,让板子一启动就是个“从设备”,方便电脑给它“刷机”。但这并不意味着我们被硬件锁死了,通过软件配置,我们完全可以“夺回控制权”,让它在运行时动态切换模式。这就是我们这篇文章要玩转的核心:用软件指挥F1C200S的USB接口,在Host和Device之间自由切换,并解锁一个超实用的功能——RNDIS网络共享。
2. 软件定义角色:内核驱动与设备树配置详解
要让F1C200S的USB OTG听我们的话,我们需要在内核里做好两件事:修改设备树(Device Tree)来告诉硬件“你是谁”,以及配置和编译正确的内核驱动来提供“能力”。这个过程就像给一个演员(芯片)写剧本(设备树)并培训演技(驱动),让他能胜任不同的角色。
2.1 设备树(DTS)的“角色设定”
设备树是Linux内核用来描述硬件的一份“硬件说明书”。对于F1C200S的USB OTG,我们需要在设备树源文件(通常是suniv-f1c100s.dtsi)里添加两个关键节点:USB控制器(usb_otg)和USB物理层(usbphy)。
首先,我们找到soc节点,在里面添加USB控制器。这里有个关键点,F1C200S的USB控制器和全志A10系列是兼容的,所以我们可以借用sun4i-a10-musb的驱动。但为了更精确,社区通常使用一个为suniv系列(F1C100s/F1C200s)定制的兼容字符串。下面是我在实际项目中验证过的配置:
usb_otg: usb@1c13000 {
compatible = "allwinner,suniv-musb";
reg = <0x01c13000 0x0400>;
clocks = <&ccu CLK_BUS_OTG>;
resets = <&ccu RST_BUS_OTG>;
interrupts = <26>;
interrupt-names = "mc";
phys = <&usbphy 0>;
phy-names = "usb";
extcon = <&usbphy 0>;
dr_mode = "otg"; /* 关键!这里先设为otg,允许动态切换 */
allwinner,sram = <&otg_sram 1>;
status = "disabled";
};
我来拆解一下几个关键属性:
compatible = "allwinner,suniv-musb": 这是告诉内核,这个设备匹配哪个驱动程序。suniv-musb是专门为F1C系列适配的。reg = <0x01c13000 0x0400>: 这是USB控制器的寄存器起始地址和长度,直接从芯片手册里查。dr_mode = "otg": 这是模式切换的钥匙!它有3个可选值:"host"(强制主机)、"peripheral"(强制从设备)、"otg"(动态切换)。我们这里先设为"otg",为后续的软件切换留出可能。allwinner,sram = <&otg_sram 1>: 指定OTG功能使用的SRAM区域,这是全志芯片的一个特性,需要配合sram-controller节点中的otg_sram定义。
接下来是USB物理层(PHY)的配置,它负责处理底层的电气信号:
usbphy: phy@1c13400 {
compatible = "allwinner,suniv-usb-phy";
reg = <0x01c13400 0x10>;
reg-names = "phy_ctrl";
clocks = <&ccu CLK_USB_PHY0>;
clock-names = "usb0_phy";

USB OTG模式切换与RNDIS网络共享——F1C200S嵌入式开发实战&spm=1001.2101.3001.5002&articleId=154631399&d=1&t=3&u=093b0d50c06c444a878c842fe584acc2)
397

被折叠的 条评论
为什么被折叠?



