V853做hid gadget小机排故笔记
-
报错排故笔记,USB新手,许多概念不清楚,可能最后也搞不定,梳理一下今天读代码知道的东西,当然也是希望有大佬指点迷津,那是莫大的帮助
V853自带setusbconfig脚本,可以很方便的配置gadget,我把D1-H的setusbconfig放到这儿,用setusbconfig hid,回复root@TinaLinux:/# setusbconfig hid [ 52.903876] configfs-gadget gadget: adding 'hid'/ddc84c70 to config 'c'/dde4b6a8 [ 52.912290] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 52.919176] configfs-gadget gadget: line:960 [ 52.924104] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 52.930835] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 52.937651] configfs-gadget gadget: line:960 [ 52.942433] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 52.949231] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 52.955992] configfs-gadget gadget: line:960 [ 52.960812] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 52.967572] configfs-gadget gadget: line:960 [ 52.972388] configfs-gadget gadget: line:967 [ 52.977350] configfs-gadget gadget: line:973 [ 52.982145] configfs-gadget gadget: fun:usb_ep_autoconfig_ss line:90 [ 52.989501] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 52.996313] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 53.003148] configfs-gadget gadget: line:960 [ 53.007959] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 53.014768] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 53.021498] configfs-gadget gadget: line:960 [ 53.026439] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 53.033213] configfs-gadget gadget: line:960 [ 53.038039] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 53.044804] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 53.051575] configfs-gadget gadget: fun:usb_gadget_ep_match_desc [ 53.058336] configfs-gadget gadget: line:960 [ 53.063177] configfs-gadget gadget: fun:usb_ep_autoconfig_ss line:94 [ 53.070297] configfs-gadget gadget: fail line:715 ep:0 [ 53.076112] configfs-gadget gadget: hidg_bind FAILED [ 53.081675] configfs-gadget gadget: adding 'hid'/ddc84c70 --> -19 [ 53.088582] configfs-gadget 4100000.udc-controller: failed to start g1: -19 sh: write error: No such device root@TinaLinux:/#
原本这里只回复
[ 68.343732] configfs-gadget gadget: hidg_bind FAILED [ 68.349296] configfs-gadget gadget: adding 'hid'/ddc84c70 --> -19 [ 68.356214] configfs-gadget 4100000.udc-controller: failed to start g1: -19 sh: write error: No such device
为了了解究竟发生了什么,在这三个文件里加了打印来确定哪个if没通过
linux-4.9/drivers/usb/gadget/function/f_hid.c linux-4.9/drivers/usb/gadget/epautoconf.c linux-4.9/drivers/usb/gadget/udc/core.c
出错的地方是 f_hid.c-> hidg_bind -> usb_ep_autoconfig
而usb_ep_autoconfig用到的是 epautoconf.c -> usb_ep_autoconfig_ss,usb_gadget_ep_match_desc 没找着匹配的端点
最后是在gadget/udc/core.c的usb_gadget_ep_match_desc函数没通过if (!ep->caps.type_int)
原来是没通过支持中断传输的检查
-
现在有点眉目了,看了一上午的gadget初始化流程,困得不行,现在V853已经可以做HID设备发出'a'了,但不确定这么改会不会出什么bug,主要是修改了sunxi_udc的默认配置
修改了 sunxi_usb\include\sunxi_udc.h 的ep2的相关内容,把bulk改成了int,把ep_fifo的偏移地址做了修改static const char ep0name[] = "ep0";
static const char ep1in_bulk_name[] = "ep1in-bulk";
static const char ep1out_bulk_name[] = "ep1out-bulk";
static const char ep2in_int_name[] = "ep2in-int";
static const char ep2out_int_name[] = "ep2out-int";
static const char ep3_iso_name[] = "ep3-iso";
static const char ep4_int_name[] = "ep4-int";
static const char ep5in_bulk_name[] = "ep5in-bulk";
static const char ep5out_bulk_name[] = "ep5out-bulk";static const struct sw_udc_fifo ep_fifo[] = {
{ep0name, 0, 512, 0},
{ep1in_bulk_name, 512, 1024, 1},
{ep1out_bulk_name, 1536, 1024, 1},
{ep2in_int_name, 2560, 512, 0},
{ep2out_int_name, 3584-512, 512, 0},
{ep3_iso_name, 4608-1024, 1024, 0},
{ep4_int_name, 5632-1024, 512, 0},
{ep5in_bulk_name, 6144-1024, 1024, 1},
{ep5out_bulk_name, 7168-1024, 1024, 1},
};sunxi_usb\udc\sunxi_udc.c 也是类似,对应的内容在sunxi_udc的 ep[3],ep[4]
.ep[3] = { .num = 2, .ep = { .name = ep2in_int_name, .ops = &sunxi_udc_ep_ops, .maxpacket = SW_UDC_EP_FIFO_SIZE, .maxpacket_limit = SW_UDC_EP_FIFO_SIZE, .caps = USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN), }, .dev = &sunxi_udc, .bEndpointAddress = (USB_DIR_IN | 2), .bmAttributes = USB_ENDPOINT_XFER_INT, }, .ep[4] = { .num = 2, .ep = { .name = ep2out_int_name, .ops = &sunxi_udc_ep_ops, .maxpacket = SW_UDC_EP_FIFO_SIZE, .maxpacket_limit = SW_UDC_EP_FIFO_SIZE, .caps = USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_OUT), }, .dev = &sunxi_udc, .bEndpointAddress = (USB_DIR_OUT | 2), .bmAttributes = USB_ENDPOINT_XFER_INT, },
这就完了,然后重新编译,打包,找个了hid gadget键盘的例程,简化了下,只发送‘a’
/*a~z,A~Z通过usb循环回显到host端*/ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <stdbool.h> #include <poll.h> #include <string.h> #include <time.h> #include <signal.h> #include <fcntl.h> #include <pthread.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> #include <sys/time.h> #define DevName "/dev/hidg0" static int key_fd = -1; static int g_bExit = 0; #define DELAY_WAIT_TIME(); usleep(100*1000); static int Hid_Send_OneGBKEnglish(const unsigned char charactor) { int offset = 0; static unsigned char charBase = 0x04; /* A or a */ unsigned char keyType = 0; unsigned char report[8] = {0}; if(charactor >= 'a' && charactor <= 'z') { keyType = 0; offset = charactor - 'a'; } else if(charactor >= 'A' && charactor <= 'Z') { keyType = 0x02; offset = charactor - 'A'; } else { printf("[fun:%s - Line:%d]unable to support charactor:0x%02x\n", __FUNCTION__, __LINE__, charactor); } memset(report, 0, 8); report[0] = 0x00; report[2] = 0x00; write(key_fd, report, 8); memset(report, 0, 8); report[0] = keyType; report[2] = charBase + offset; write(key_fd, report, 8); memset(report, 0, 8); report[0] = keyType; report[2] = 0x00; write(key_fd, report, 8); memset(report, 0, 8); report[0] = 0x00; report[2] = 0x00; write(key_fd, report, 8); DELAY_WAIT_TIME(); return 0; } static int Hid_Send_Enter() { unsigned char report[8] = {0}; memset(report, 0, 8); report[0] = 0x00; report[2] = 0x28; write(key_fd, report, 8); memset(report, 0, 8); report[0] = 0x00; report[2] = 0x00; write(key_fd, report, 8); DELAY_WAIT_TIME(); return 0; } static int Hid_Send_Space() { unsigned char report[8] = {0}; memset(report, 0, 8); report[0] = 0x00; report[2] = 0x2C; write(key_fd, report, 8); memset(report, 0, 8); report[0] = 0x00; report[2] = 0x00; write(key_fd, report, 8); DELAY_WAIT_TIME(); return 0; } void HandleSig(signed int signo) { if (signo == SIGINT) { printf("catch Ctrl + C, exit normally\n"); g_bExit = 1; } } extern void HandleSig(signed int signo); int main(int argc, char *argv[]) { unsigned char charactor; key_fd = open("/dev/hidg0", O_RDWR, 0666); if (key_fd<0) { printf("error\n"); return -1; } charactor = 'a'; Hid_Send_OneGBKEnglish(charactor++); Hid_Send_Space(); Hid_Send_Enter(); close(key_fd); return 0; }
上传上面的代码编译成app,chmod 给予运行权限,我这里是编译成了hidapp
chmod 777 ./hidapp
kernel/linux-4.9/Documentation/usb/gadget_hid.txt也有例程,但比较复杂全面,一时半会我也看不懂,
然后就是指令
killall adbd 2>/dev/null
setusbconfig hid
cat /sys/devices/platform/soc/usbc0/usb_host
cat /sys/devices/platform/soc/usbc0/usb_device
先关掉ADB程序,再开脚本设置hid键盘,现在就没报错了,但电脑还是没识别到键盘,需要转换usb口到host再转到device才能用,这个时候设备管理器就能看到新键盘了
app测试
说一下其他问题,我用的adb上传文件,每次都要cat /sys/devices/platform/soc/usbc0/usb_host
cat /sys/devices/platform/soc/usbc0/usb_device才能用,完了要是拔插usb口,虚拟机的usb就会卡死再也无法识别,电脑也关不了机,只能强制重启,这个问题很影响调试,有办法解决吗? -
妈呀,突然发现这部分内容在v853系统开发手册里面有说,但我之前都不知道!不过里面没有给出文件路径,只说了可以修改这些定义,有点云里雾里
-
@xjy_5 _5 你好 能否把pc端的usb软件发我下 谢谢
-
@sofia 测试USB的APP的源码已经放上来了。我在串口命令行运行app马上就会从开发板的usb发出‘a’,所以就打在命令行上了
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号