导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页

    V853做hid gadget小机排故笔记

    V Series
    2
    5
    2841
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • X
      xjy_5 LV 6 最后由 xjy_5 编辑

      报错排故笔记,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
      e2a22729-1262-4700-9780-50f44303ba1f-image.png
      而usb_ep_autoconfig用到的是 epautoconf.c -> usb_ep_autoconfig_ss,usb_gadget_ep_match_desc 没找着匹配的端点
      c3028035-bc5e-4333-9160-d915547f4e47-image.png
      最后是在gadget/udc/core.c的usb_gadget_ep_match_desc函数没通过if (!ep->caps.type_int)
      862ad065-899c-4dbf-ac42-c8812ea8d032-image.png

      原来是没通过支持中断传输的检查
      b4003a3f-a8e7-4283-9d0b-e2f90b1d3678-image.png

      1 条回复 最后回复 回复 引用 分享 0
      • X
        xjy_5 LV 6 最后由 xjy_5 编辑

        现在有点眉目了,看了一上午的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才能用,这个时候设备管理器就能看到新键盘了
        739ef800-ad1e-425a-8447-87935e5ae5d8-image.png
        app测试
        ecb44dbc-3f40-4c27-90b3-53d0eb6bccb6-image.png

        说一下其他问题,我用的adb上传文件,每次都要cat /sys/devices/platform/soc/usbc0/usb_host
        cat /sys/devices/platform/soc/usbc0/usb_device才能用,完了要是拔插usb口,虚拟机的usb就会卡死再也无法识别,电脑也关不了机,只能强制重启,这个问题很影响调试,有办法解决吗?

        1 条回复 最后回复 回复 引用 分享 0
        • X
          xjy_5 LV 6 最后由 编辑

          妈呀,突然发现这部分内容在v853系统开发手册里面有说,但我之前都不知道!不过里面没有给出文件路径,只说了可以修改这些定义,有点云里雾里

          S 1 条回复 最后回复 回复 引用 分享 0
          • S
            sofia LV 6 @xjy_5 最后由 编辑

            @xjy_5 _5 你好 能否把pc端的usb软件发我下 谢谢

            X 1 条回复 最后回复 回复 引用 分享 0
            • X
              xjy_5 LV 6 @sofia 最后由 编辑

              @sofia 测试USB的APP的源码已经放上来了。我在串口命令行运行app马上就会从开发板的usb发出‘a’,所以就打在命令行上了

              1 条回复 最后回复 回复 引用 分享 0
              • 1 / 1
              • First post
                Last post

              Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

              行为准则 | 用户协议 | 隐私权政策