LinuxUSB驱动程序调试--009:编写应用程序---验证协议【转】

转自:http://biancheng.dnbcw.info/linux/257411.html 

【1】 如何编译X86下的 uBuntu APP---非常简单:
            gcc -o testusb testusb.c
         编译完成后即可生成 testusb  ,这就是可执行文件。
         
   【2】下面制作一个APP,目的是读取4740的内存。只要能实现这个目标,测试基本就算完成。
        #include <stdio.h>
        #include <string.h>
        #include <ftw.h>
        #include <stdlib.h>
        #include <pthread.h>
        #include <unistd.h>
        #include <errno.h>
        
        #include <sys/types.h>
        #include <sys/stat.h>
        #include <fcntl.h>
        
        #include <sys/ioctl.h>
        #include <linux/usbdevice_fs.h>
        
        int usb_boot_fd;
        #define USBTEST_REQUEST _IOWR('U', 100, struct usbtest_param)
           
        int read_from_4740()
        {
                unsigned char Buffer0[256];
                unsigned char Buffer1[512];
                int res,i;
           
         if ((usb_boot_fd = open ("/dev/usb_boot",  O_RDWR)) < 0) {
          perror ("can't open dev file r/w");
          return -1;
         }
        
         Buffer0[0]=0x40;
         Buffer0[1]=0x01;  //Reqest    01===>SET DATA ADDRESS
        
         Buffer0[2]=0xC0; //Byte2
         Buffer0[3]=0xBF; //Byte3
        
         Buffer0[4]=0x00; //Byte0
         Buffer0[5]=0x00; //Byte1
        
         Buffer0[6]=0x00;
         Buffer0[7]=0x00;
         res=ioctl (usb_boot_fd, USBDEVFS_IOCTL, Buffer0);
        
         //========== 
         Buffer1[0]=0x40;
         Buffer1[1]=0x02;  //Reqest    02===>SET DATA LENGTH
        
         Buffer1[2]=0x00; //Byte2
         Buffer1[3]=0x00; //Byte3
        
         Buffer1[4]=0x00; //Byte0
         Buffer1[5]=0x02; //Byte1
        
         Buffer1[6]=0x00;
         Buffer1[7]=0x00;
        
         res=ioctl (usb_boot_fd, USBDEVFS_IOCTL, Buffer1);
        
         memset(Buffer1,0x00,0x200);
         res=read(usb_boot_fd,Buffer1,0x20);

      //注意这里的0x20,我当时测试时,是想少读些,就够了@谁知,害惨了我自己!应该写成 0x200 !
        
         printf(" Read Buffer 0xBFC00000: res=%d ",res);
         for(i=0;i<0x20;i++)
         {
          if (0==(i%16)) printf(" ");
          printf(" %2.2X",Buffer1[i]);
         }
         printf(" =========== ");
         close (usb_boot_fd);
        }
        上述程序非常简单,本来一天就可以调试成功,谁知,测试失败!每次都是读取失败!
       
        我的USB MON 输出:
         f440df80 3225088196 S Co:019:00 s 40 01 80c0 0000 0000 0
         f440df80 3225374404 C Co:019:00 0 0
         f440df80 3225374785 S Co:019:00 s 40 02 0000 0200 0000 0
         f440df80 3225499216 C Co:019:00 0 0
         f440df80 3225499692 S Bi:019:01 -115 32 <
         f440df80 3225515295 C Bi:019:01 -75 32 = 00000000 ....00000000 00000000
             
        U盘,正确的输出:
         f446e580 2935176097 S Bo:018:01 -115 31 = 55534243 04000000 ....00000
         f446e580 2935188508 C Bo:018:01 0 31 >
         f446e580 2935188925 S Bi:018:01 -115 13 <
         f446e580 2935203774 C Bi:018:01 0 13 = 55534253 04000000 00000000 00
 
        错误码:kernelincludeasm-genericerrno.h    其中:
          #define EINPROGRESS 115 /* Operation now in progress */
          #define EOVERFLOW 75 /* Value too large for defined data type */
        总是出现错误码: -75,也就是说,EOVERFLOW,
我 google: URB EOVERFLOW 很久其中有一条搜索给了我提醒: 设备发送的数据过多!
终于让我悟到:我在协议配置时,要求读取 0x200字节,在APP中,却读取了0x20字节!当然是设备给的多,我要的少!
   其实这个问题以前在windows下调试也遇到过,只是当时印象不深啊,这次恐怕印象深刻了!付出了2天的代价啊!
   验证一下,读取0x200字节,一切OK!
 
500)this.width=500;">          

   实际驱动本身任何问题,是APP在调用时,协议没搞好而已!
       
原文地址:https://www.cnblogs.com/sky-heaven/p/5066492.html