开发板作为USB主机,负责为连接的从设备供电并控制数据传输。
设备作为从设备(被主机控制),无法连接其他USB设备。
设备可动态切换主机模式或设备模式,无需固定角色。
按照如下工程路径修改设备树文件:
在该文件里添加如下内容:
x/include/ "system-conf.dtsi"
/ {
};
# Added content/ { usb_phy0: phy0@e0002000 { compatible = "ulpi-phy"; #phy-cells = <0>; reg = <0xe0002000 0x1000>; view-port = <0x0170>; drv-vbus; };};&usb0 { # Select the mode as needed dr_mode = "otg"; /*dr_mode = "peripheral";*/ /*dr_mode = "host";*/ usb-phy = <&usb_phy0>; usb-reset = <&gpio0 10 0>;};参考:
1.https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842272/Zynq+Linux+USB+Device+Driver
使用命令:
xxxxxxxxxxpetalinux-config -c kernel在弹出的字符界面中使能如下内容:驱动可以编译到内核中,也可以编译成内核模块,在系统启动后再动态加载该模块。建议编译成内核模块。
xxxxxxxxxx#直接编译到内核Device Drivers --->[*]USB support ---> [*]USB Gadget Support ---> [*]USB Gadget functions configurable through configfs [*]Abstract controlo Model(CDC ACM) [*]USB Gadget precomposed confiurations-----> [*]Mass Storage Gadget [*]Serial Gadget(with CDC ACM and CDC OBEX support) #编译成内核模块Device Drivers --->[*]USB support ---> [*]USB Gadget Support ---> [M]USB Gadget functions configurable through configfs [M]Abstract controlo Model(CDC ACM) [*]USB Gadget precomposed confiurations-----> [M]Mass Storage Gadget [M]Serial Gadget(with CDC ACM and CDC OBEX support) # [*]:表示选中并启用了该功能,意味着该功能将被编译进内核中,成为内核的一部分。也就是 内核静态编译。例如,如果选择了 USB Gadget Support 选项中的 Mass Storage Gadget,这意味着该功能会被直接编译进内核,并且每次内核启动时都会启用该功能,无需加载任何模块。# [M]:表示该功能会被编译成一个 内核模块,也就是说,它不会直接编译进内核,而是在系统启动后动态加载。这种配置方式提供了更大的灵活性,可以在需要时加载或卸载模块,而无需重新编译内核。例如,如果选择了 Serial Gadget (with CDC ACM and CDC OBEX support) 并选择了 [M],该功能会作为一个模块编译,可以通过 modprobe 或者 insmod 命令手动加载或卸载该模块,便于动态管理。 运用命令
xxxxxxxxxxpetalinux-build -c kernel将重新编译后的内核,设备树拷贝到SD卡里。上电加载系统,在console或者telnet中手动加载内核模块:
xxxxxxxxxxcd /lib/modules/5.10.0-xilinx-v2021.1/kernel/drivers/usb/gadget/legacyinsmod u_serial.koinsmod libcomposite.koinsmod usb_f_serial.koinsmod usb_f_obex.koinsmod usb_f_acm.koinsmod g_serial.ko
# insmod libcomposite.ko;insmod u_serial.ko;insmod usb_f_serial.ko;insmod usb_f_acm.ko;insmod g_serial.ko# rmmod g_serial;rmmod usb_f_acm;rmmod usb_f_serial;rmmod u_serial;rmmod libcomposite;会看到/dev/ttyGS0设备:
如果不想每次上电都手动去加载内核模块,可以将这些命令写入到一个启动脚本中,上电后自动加载该启动脚本。
提前准备好的一个 U盘(必须是fat32格式),通过电脑在这个U盘上几个文档,比如创建两个文档分别命名为a.txt和b.txt。
将开发板上的JP2和JP3用跳线帽短接,上电启动后,将U盘插入OTG对应的type-c接口(需要一个TYPE-C转TYPE-A母头的转换接头),将会在console串口上看到如下提示信息:
接下来输入命令:查看U盘挂载及内存等使用情况。
xxxxxxxxxxdf -h可以看到挂载点的位置处于”/run/media/sda1",按照上面的图上U盘的位置,输入 cd /run/media/sda1 进入U盘 。
xxxxxxxxxxcd /run/media/sda1接下来可以输入“ls"查看U盘内容:
xxxxxxxxxxls可以看到 文件夹下有 a.txt 和 b.txt两个文件。也可以直接对U盘内容进行修改。
我们在内核配置时,使能了USB CDC,所以当通过USB线接入到电脑上时,这个USB会被虚拟成串口。
正常上电并系统启动后,需要先加载前面的虚拟串口对应的内核模块。再用两端都是TYPE-C接口的USB线将开发板与电脑进行连接,可以看到在串口调试助手里面有两个串口,其中COM11是USB OTG接口所虚拟出来的串口,COM12则是zynq linux系统的console串口。
虚拟出来的串口在zynq上对应的是/dev/ttyGS0。
开发板通过虚拟串口给电脑发送数据
在开发板的console串口上使用如下命令给电脑发送数据:
xxxxxxxxxxecho 123 > /dev/ttyGS0
在电脑的串口终端上就会显示收到的数据:
电脑也可以通过虚拟串口给开发板发送数据
在开发板上通过‘cat'命令读取虚拟串口接收到的数据。在电脑的虚拟串口对应的终端输入:hello\n,这时在开发板的console终端上就会显示收到的数据。
注:在终端中发送与接收串口数据都是以'\n'为终止条件,即发送的数据会追加'\n',接收的数据必须在收到'\n'时回显。