目标
进行USB的HDF适配,能使USB进行模式间的切换。
一、USB的HDF适配
步骤一 增加编译文件f_generic.c
1. kernel\linux\linux-5.10\arch\arm64\configs中的XXX_defconfig文件中增加
CONFIG_DRIVERS_HDF_USB_F_GENERIC=y
2. kernel\linux\linux-5.10\drivers\usb\gadget\Kconfig中增加
config DRIVERS_HDF_USB_F_GENERIC
bool "Enable F_GENERIC driver"
default y
depends on DRIVERS_HDF
help
Answer Y to choice HDF USB F_GENERIC driver.
3. kernel\linux\linux-5.10\drivers\usb\gadget\function\Makefile中增加
usb_f_generic-y := f_generic.o
obj-$(CONFIG_DRIVERS_HDF_USB_F_GENERIC) += usb_f_generic.o
步骤二 增加USB设备通知事件代码
1. 在kernel\linux\linux-5.10\drivers\usb\core\notify.c中增加
void usb_notify_online_status(bool online)
{
if (online) {
blocking_notifier_call_chain(&usb_notifier_list, USB_GADGET_ADD, NULL);
} else {
blocking_notifier_call_chain(&usb_notifier_list, USB_GADGET_REMOVE, NULL);
}
}
2. 在kernel\linux\linux-5.10\drivers\usb\dwc3\gadget.c中
3653行增加
usb_notify_online_status(false); //3653行
3661行增加
usb_notify_online_status(true);//3661行
3. kernel\linux\linux-5.10\include\linux\usb.h中增加2022行--2026行
#define USB_GADGET_ADD 0x0005
#define USB_GADGET_REMOVE 0x0006
extern void usb_register_notify(struct notifier_block *nb);
extern void usb_unregister_notify(struct notifier_block *nb);
extern void usb_notify_online_status(bool online);
步骤三 增加vendor仓下OH相关配置
1. 进行config.json文件配置,可以参考vendor\hihope\rk3568\config.json;
2. 进行device_info.hcs文件配置,可以参考vendor\hihope\rk3568\hdf_config\uhdf\device_info.hcs,重点关注
usb :: host {
hostName = "usb_host";
priority = 50;
caps = ["DAC_OVERRIDE"];
usb_pnp_manager_device :: device {
device0 :: deviceNode {
policy = 2;
priority = 70;
moduleName = "libusb_pnp_manager.z.so";
serviceName = "usb_pnp_manager";
}
}
usbfn_device :: device {
device0 :: deviceNode {
policy = 2;
priority = 80;
moduleName = "libusbfn_master.z.so";
serviceName = "usbfn_master";
deviceMatchAttr = "usbfn_master_driver";
}
}
ecm_device :: device {
device0 :: deviceNode {
policy = 2;
priority = 81;
moduleName = "libusbfn_cdcecm.z.so";
serviceName = "usbfn_cdcecm";
deviceMatchAttr = "usbfn_cdcecm_driver";
}
}
acm_device :: device {
device0 :: deviceNode {
policy = 2;
priority = 100;
moduleName = "libusbfn_cdcacm.z.so";
serviceName = "usbfn_cdcacm";
deviceMatchAttr = "usbfn_cdcacm_driver";
}
}
usb_device :: device {
device0 :: deviceNode {
policy = 2;
priority = 100;
moduleName = "libusb_driver.z.so";
serviceName = "usb_interface_service";
}
}
}
步骤三 增加芯片相关配置
1. 查看default_config.h中dwc3值是否正确,不正确则需要修改,此值可以通过驱动配置dts文件获取;RK3568中此值为fcc00000,在device\soc\rockchip\common\hal\usb\rk3568\include\default_config.h中设置
#define UDC_NAME "fcc00000.dwc3"
2. 参考device\soc\rockchip\rk3568\soc.gni中增加
usb_default_config_path = "//device/soc/rockchip/common/hal/usb/rk3568/include"
3. 参考RK3568检查drivers\peripheral\usb\BUILD.gn中是否有deps被注释掉
group("usb_entry") {
deps = [
"//drivers/peripheral/usb/cfg:usb_etc_files",
"//drivers/peripheral/usb/ddk:libusb_core",
"//drivers/peripheral/usb/gadget/function/acm:libusbfn_cdcacm",
"//drivers/peripheral/usb/gadget/function/ecm:libusbfn_cdcecm",
"//drivers/peripheral/usb/gadget/function/master:libusbfn_master",
"//drivers/peripheral/usb/hdi_service:hdi_usb_service",
"//drivers/peripheral/usb/net:libusbhost_ecm",
"//drivers/peripheral/usb/serial:libusbhost_acm",
"//drivers/peripheral/usb/serial:libusbhost_acm_rawapi",
]
}
4. 参考RK3568检查drivers\peripheral\usb\bundle.json中usb的配置项
"build": {
"sub_component": [
"//drivers/peripheral/usb:usb_entry"
],
"test": [
"//drivers/peripheral/usb/test:hdf_test_usb"
],
5. 参考RK3568检查drivers\peripheral\usb\usb.gni中usb路径是否存在
import("//vendor/${product_company}/${product_name}/product.gni")
default_config_path = usb_default_config_path
注意:USB适配完毕后,记得插拔一下USB设备,来触发notify方法。
二、USB切换acm、ecm等方法
备注:此模式切换以RK3568为例进行说明,同时提前需用zadig.exe安装libusb-win32 devices驱动
1. 修改base\usb\usb_manager\test\native\BUILD.gn代码,在把第19行代码修改如下
--deps = []
++deps = ["../tool/:usb_function_port_test"]
2. 编译工具
./build.sh --product-name rk3568 --build-target usb_unittest_test
3. 安装工具
工具输出目录为//out/rk3568/usb/usb_manager/ 下,使用hdc file send推进到单板中,如下命令
hdc file send C:\Users\xxx\Desktop\usb_function_port_test /data
4. 修改执行权限(在/data目录下)
chmod +x usb_function_port_test
5. 查看当前模式,执行以下命令,会显示 GetCurrentFunctionInfo:62 get current function: hdc,表明当前模式为HDC模式
./usb_function_port_test -f 0
6. 切换其他模式
其他模式的切换命令是一致的,如切换为acm 模式,命令如下,此时hdc会自动断开
./usb_function_port_test -f 1
7. 查看可使用的命令
./usb_function_port_test -h
2 args
-p 0: Query Port
-p 1: Switch to host
-p 2: Switch to device:
-f 0: Query function
-f 1: Switch to function:acm
-f 2: Switch to function:ecm
-f 3: Switch to function:acm&ecm
-f 4: Switch to function:hdc
-f 5: Switch to function:acm&hdc
-f 6: Switch to function:ecm&hdc
-f 32: Switch to function:rndis
-f 512: Switch to function:storage
-f 36: Switch to function:rndis&hdc
-f 516: Switch to function:storage&hdc