NUC980_Non-OS_BSP_v1.03.000 SDK中没有提供USB bulk传输的例程,基于USBD_HID_Mouse例程进行修改。大体思路参考这个文章,先修改设备、配置、接口、端点等描述符,再安装驱动,最后编写下位机和上位机程序进行验证。

USB Device Controller的框图如下:

特性:

  • USB Specification reversion 2.0 compliant
  • Supports 12 configurable endpoints in addition to Control Endpoint
  • Each of the endpoints can be Isochronous, Bulk or Interrupt and either IN or OUT direction
  • Three different operation modes of an in-endpoint - Auto Validation mode, Manual Validation mode, Fly mode
  • Supports DMA operation
  • 4096 Bytes Configurable RAM used as endpoint buffer
  • Supports Endpoint Maximum Packet Size up to 1024 bytes

1.修改描述符

关于描述符的详细说明参考博客。

各种描述符之间的关系:

修改descriptors.c中DeviceDescriptor:

uint8_t gu8DeviceDescriptor[] __attribute__((aligned(4))) =
{
#endifLEN_DEVICE,     /* bLength */DESC_DEVICE,    /* bDescriptorType */0x00, 0x02,     /* bcdUSB */                  //0x10,0x01->0x00,0x200xFF,           /* bDeviceClass */            //0x00->0xFF0x00,           /* bDeviceSubClass */0x00,           /* bDeviceProtocol */CEP_MAX_PKT_SIZE,   /* bMaxPacketSize0 *//* idVendor */USBD_VID & 0x00FF,((USBD_VID & 0xFF00) >> 8),/* idProduct */USBD_PID & 0x00FF,((USBD_PID & 0xFF00) >> 8),0x00, 0x00,     /* bcdDevice */0x01,           /* iManufacture */0x02,           /* iProduct */0x00,           /* iSerialNumber - no serial */0x01            /* bNumConfigurations */
};

修改hid_mouse.h中VID和PID的值(不是必须要修改的):

#define USBD_VID                0x303A                                       //0x0416->0x303A
#define USBD_PID                0x3002                                      //0x8249->0x3001

在hid_mouse.h中增加OUT节点的定义:

/* Define EP maximum packet size */
#define CEP_MAX_PKT_SIZE        64
#define CEP_OTHER_MAX_PKT_SIZE  64
#define EPA_MAX_PKT_SIZE        512               //修改,由64改为512
#define EPA_OTHER_MAX_PKT_SIZE  64
#define EPB_MAX_PKT_SIZE        512               //新增
#define EPB_OTHER_MAX_PKT_SIZE  64#define CEP_BUF_BASE    0
#define CEP_BUF_LEN     CEP_MAX_PKT_SIZE#define EPA_BUF_BASE    0x200                    //新增
#define EPA_BUF_LEN     EPA_MAX_PKT_SIZE       #define EPB_BUF_BASE    0x400                    //新增
#define EPB_BUF_LEN     EPB_MAX_PKT_SIZE         //新增/* Define the interrupt In EP number */
#define INT_IN_EP_NUM   0x01#define INT_OUT_EP_NUM   0x01                    //新增

修改descriptors.c中ConfigDescriptor :

uint8_t gu8ConfigDescriptor[] __attribute__((aligned(4))) =
{
#endifLEN_CONFIG,     /* bLength */DESC_CONFIG,    /* bDescriptorType *//* wTotalLength */LEN_CONFIG_AND_SUBORDINATE & 0x00FF,((LEN_CONFIG_AND_SUBORDINATE & 0xFF00) >> 8),                   0x01,           /* bNumInterfaces */0x01,           /* bConfigurationValue */0x00,           /* iConfiguration */0x80 | (USBD_SELF_POWERED << 6) | (USBD_REMOTE_WAKEUP << 5),/* bmAttributes */USBD_MAX_POWER,         /* MaxPower *//* I/F descr: HID */LEN_INTERFACE,  /* bLength */DESC_INTERFACE, /* bDescriptorType */0x00,           /* bInterfaceNumber */0x00,           /* bAlternateSetting */0x02,           /* bNumEndpoints */                             //0x01->0x020xFF,           /* bInterfaceClass */                            //0x03->0xFF0x01,           /* bInterfaceSubClass */0x00,                /* bInterfaceProtocol */                    //HID_MOUSE->0x000x00,           /* iInterface *//* HID Descriptor */                                                            //不使用报告描述符,将此段配置注释。
//    LEN_HID,        /* Size of this descriptor in UINT8s. */
//    DESC_HID,       /* HID descriptor type. */
//    0x10, 0x01,     /* HID Class Spec. release number. */
//    0x00,           /* H/W target country. */
//    0x01,           /* Number of HID class descriptors to follow. */
//    DESC_HID_RPT,   /* Descriptor type. *//* Total length of report descriptor. */
//    sizeof(HID_MouseReportDescriptor) & 0x00FF,
//    ((sizeof(HID_MouseReportDescriptor) & 0xFF00) >> 8),/* EP Descriptor: bulk in. */LEN_ENDPOINT,   /* bLength */DESC_ENDPOINT,  /* bDescriptorType */(INT_IN_EP_NUM | EP_INPUT), /* bEndpointAddress */EP_BULK,         /* bmAttributes */                //EP_INT->EP_BULK/* wMaxPacketSize */EPA_MAX_PKT_SIZE & 0x00FF,((EPA_MAX_PKT_SIZE & 0xFF00) >> 8),0x00,                         /* bInterval */                //HID_DEFAULT_INT_IN_INTERVAL->0x00/* EP Descriptor: bulk out. */                                    //新增一个输出端点。LEN_ENDPOINT,   /* bLength */DESC_ENDPOINT,  /* bDescriptorType */(INT_OUT_EP_NUM | EP_OUTPUT), /* bEndpointAddress */EP_BULK,         /* bmAttributes */    /* wMaxPacketSize */EPB_MAX_PKT_SIZE & 0x00FF,((EPB_MAX_PKT_SIZE & 0xFF00) >> 8),0x00                      /* bInterval */
};

修改LEN_CONFIG_AND_SUBORDINATE的值(减去了一个REPORT,增加了一个END):

#define LEN_CONFIG_AND_SUBORDINATE      (LEN_CONFIG+LEN_INTERFACE+LEN_ENDPOINT+LEN_ENDPOINT)

修改hid_mouse.c中的HID_InitForHighSpeed()、HID_InitForFullSpeed(),增加OUT端点配置:

/*** @brief  USBD Endpoint Config.* @param  None.* @retval None.*/
void HID_InitForHighSpeed(void)
{/* EPA ==> Interrupt IN endpoint, address 1 */USBD_SetEpBufAddr(EPA, EPA_BUF_BASE, EPA_BUF_LEN);USBD_SET_MAX_PAYLOAD(EPA, EPA_MAX_PKT_SIZE);USBD_ConfigEp(EPA, INT_IN_EP_NUM, USB_EP_CFG_TYPE_BULK, USB_EP_CFG_DIR_IN);/* EPB ==> Interrupt OUT endpoint, address 1 */USBD_SetEpBufAddr(EPB, EPB_BUF_BASE, EPB_BUF_LEN);USBD_SET_MAX_PAYLOAD(EPB, EPA_MAX_PKT_SIZE);USBD_ConfigEp(EPB, INT_OUT_EP_NUM, USB_EP_CFG_TYPE_BULK, USB_EP_CFG_DIR_OUT);    USBD_ENABLE_EP_INT(EPB, USBD_EPINTEN_RXPKIEN_Msk);
}void HID_InitForFullSpeed(void)
{/* EPA ==> Interrupt IN endpoint, address 1 */USBD_SetEpBufAddr(EPA, EPA_BUF_BASE, EPA_BUF_LEN);USBD_SET_MAX_PAYLOAD(EPA, EPA_OTHER_MAX_PKT_SIZE);USBD_ConfigEp(EPA, INT_IN_EP_NUM, USB_EP_CFG_TYPE_BULK, USB_EP_CFG_DIR_IN);/* EPB ==> Interrupt OUT endpoint, address 1 */USBD_SetEpBufAddr(EPB, EPB_BUF_BASE, EPB_BUF_LEN);USBD_SET_MAX_PAYLOAD(EPB, EPB_OTHER_MAX_PKT_SIZE);USBD_ConfigEp(EPB, INT_OUT_EP_NUM, USB_EP_CFG_TYPE_BULK, USB_EP_CFG_DIR_IN); USBD_ENABLE_EP_INT(EPB, USBD_EPINTEN_RXPKIEN_Msk);
}

修改UsbString:

uint8_t gu8ProductStringDesc[] __attribute__((aligned(4))) =
{
#endif34,DESC_STRING,'B', 0, 'U', 0, 'L', 0, 'K', 0,' ', 0, 'T', 0, 'r', 0, 'a', 0, 'n', 0, 's', 0, 'a', 0, 'c', 0, 't', 0, 'i', 0, 'o', 0, 'n', 0
};

编译程序,重新烧录。电脑->设备管理器>其它设备 下多了一个名称为BULK Transaction的设备:

2.生成USB 驱动

运行inf-wizard.exe应用,点击 Next:

选择Vendor ID为0x303A、Product ID为0x3002的设备,点击Next:

Manufacturer Name、Device Name可修改为其它类容,点击Next:

选择一个路径存放驱动文件。

点击Done完成并退出。

3.安装驱动

右键 ->更新驱动程序->浏览我的电脑以查找驱动程序(R),选择刚才存放驱动的文件夹:

点击 下一页。

一般会遇到以上问题,这是因为驱动没有包含数字签名,解决办法。

驱动安装成功之后,设备管理器展示如下:

4.使用工具查看设备描述符

运行testlibusb-win.exe,设备描述符如下:

5.编写NUC980 bulk读写函数及测试程序

在hid_mouse.c中增加bulk读写函数:

/*** @brief  USBD Endpoint Write.* @param  None.* @retval None.*/
void BulkWriteData( uint8_t *Datas, uint16_t Len )
{uint16_t i;for ( i=0; i<Len; i++){USBD->EP[EPA].ep.EPDAT_BYTE = Datas[i];}USBD->EP[EPA].EPRSPCTL = USB_EP_RSPCTL_SHORTTXEN;USBD_ENABLE_EP_INT(EPA, USBD_EPINTEN_INTKIEN_Msk);
}
/*** @brief  USBD Endpoint Read.* @param  None.* @retval None.*/
uint16_t BulkReadData( uint8_t *Datas, uint16_t Len )
{uint16_t i;uint16_t DataCnt = USBD->EP[EPB].EPDATCNT;if( DataCnt > 0 ){for( i = 0; i < DataCnt; i++ ){Datas[i] = USBD->EP[EPB].ep.EPDAT_BYTE;}}return DataCnt;
}

main.c中增加接收和发送数据的逻辑,main()函数如下:

int32_t main (void)
{uint8_t i, Cnt = 0;uint8_t DataBuf[EPB_MAX_PKT_SIZE];uint16_t RxLen;sysDisableCache();sysFlushCache(I_D_CACHE);sysEnableCache(CACHE_WRITE_BACK);UART_Init();printf("\n");printf("=======================\n");printf("     USB HID Mouse     \n");printf("=======================\n");sysInstallISR(IRQ_LEVEL_1, IRQ_UDC, (PVOID)USBD_IRQHandler);/* enable CPSR I bit */sysSetLocalInterrupt(ENABLE_IRQ);sysEnableInterrupt(IRQ_UDC);USBD_Open(&gsInfo, HID_ClassRequest, NULL);/* Endpoint configuration */HID_Init();/* Start transaction */while(1){if (USBD_IS_ATTACHED()){USBD_Start();break;}}while(1){RxLen = BulkReadData(DataBuf, EPB_MAX_PKT_SIZE );if( RxLen > 0 ){BulkWriteData( DataBuf, EPA_MAX_PKT_SIZE );}}
}

编译之后烧写到NUC980。

6.编写windows应用程序测试数据通信

基于libusb.lib编写一个测试应用,进行简单的数据的发送和接收。代码如下:

#include "lusb0_usb.h"
#include <stdio.h>
#include "stdint.h"
#include <iostream>
#include <sys/timeb.h>
#include "windows.h"using namespace std;// Enables this example to work with a device running the
// libusb-win32 PIC Benchmark Firmware.
//#define BENCHMARK_DEVICE//
// TEST SETUP (User configurable)// Issues a Set configuration request
#define TEST_SET_CONFIGURATION// Issues a claim interface request
#define TEST_CLAIM_INTERFACE// Use the libusb-win32 async transfer functions. see
// transfer_bulk_async() below.
#define TEST_ASYNC// Attempts one bulk read.
#define TEST_BULK_READ// Attempts one bulk write.#define TEST_BULK_WRITE// Device vendor and product id.
//#define MY_VID 0x05AC
//#define MY_PID 0x12A0#define MY_VID 0x303A
#define MY_PID 0x3002// Device configuration and interface id.
#define MY_CONFIG 1    //bConfigurationValue   --lwz
#define MY_INTF 0      //bInterfaceNumber     --lwz// Device endpoint(s)
#define EP_IN 0x81    //0x81
#define EP_OUT 0x01
// Device of bytes to transfer.
#define RX_BUF_SIZE 512
#define TX_BUF_SIZE 512#define TEST_BULK_SPEEDusb_dev_handle *dev = NULL; /* the device handle *///
usb_dev_handle *open_dev(void);
uint16_t usb_dev_read_sync( uint8_t *Buf, uint16_t bufsz );
bool usb_dev_write_async( uint8_t *Datas, uint16_t DataLen, int timeout );
int usb_dev_read_async( uint8_t *Buf, uint16_t bufsz, int timeout );static int transfer_bulk_async(usb_dev_handle *dev,int ep,char *bytes,int size,int timeout);usb_dev_handle *open_dev(void)
{struct usb_bus *bus;struct usb_device *dev;for (bus = usb_get_busses(); bus; bus = bus->next){for (dev = bus->devices; dev; dev = dev->next){if (dev->descriptor.idVendor == MY_VID&& dev->descriptor.idProduct == MY_PID){return usb_open(dev);}}}return NULL;
}//
//  usb_dev_init.
//
void usb_dev_init( void )
{usb_init(); /* initialize the library */
}
//
//  usb_dev_open.
//
bool usb_dev_open( void )
{usb_find_busses(); /* find all busses */usb_find_devices(); /* find all connected devices */if (!(dev = open_dev())){printf("error opening device: \n%s\n", usb_strerror());return false;}if (usb_set_configuration(dev, MY_CONFIG) < 0)           //MY_CONFIG是配置描述符中的bConfigurationValue{printf("error setting config #%d: %s\n", MY_CONFIG, usb_strerror());usb_close(dev);return false;}if (usb_claim_interface(dev, MY_INTF) < 0)     //注册与操作系统通信的接口 --lwz{printf("error claiming interface #%d:\n%s\n", MY_INTF, usb_strerror());usb_close(dev);return false;}return true;
}
//
//  usb_dev_close.
//
void usb_dev_close( void )
{if (dev){usb_release_interface(dev, MY_INTF);   //注销被usb_claim_interface函数调用后的接口,释放资源  --lwzusb_close(dev);}
}bool usb_dev_isopen( void )
{if( dev != NULL ){return true;}return false;
}void usb_dev_reset_epin( void )
{usb_clear_halt( dev, EP_IN );
}void usb_dev_reset_epout( void )
{usb_clear_halt( dev, EP_OUT );
}int main(char argc,char **argv)
{usb_dev_handle *dev = NULL; /* the device handle */char tmp[RX_BUF_SIZE];int ret;void* async_read_context = NULL;void* async_write_context = NULL;usb_init(); /* initialize the library */usb_find_busses(); /* find all busses */usb_find_devices(); /* find all connected devices */if (!(dev = open_dev())){printf("error opening device: \n%s\n", usb_strerror());return 0;}else{printf("success: device %04X:%04X opened\n", MY_VID, MY_PID);}#ifdef TEST_SET_CONFIGURATIONif (usb_set_configuration(dev, MY_CONFIG) < 0)           //MY_CONFIG是配置描述符中的bConfigurationValue{printf("error setting config #%d: %s\n", MY_CONFIG, usb_strerror());usb_close(dev);return 0;}else{printf("success: set configuration #%d\n", MY_CONFIG);}
#endif#ifdef TEST_CLAIM_INTERFACEif (usb_claim_interface(dev, 0) < 0)     //注册与操作系统通信的接口 --lwz{printf("error claiming interface #%d:\n%s\n", MY_INTF, usb_strerror());usb_close(dev);return 0;}else{printf("success: claim_interface #%d\n", MY_INTF);}
#endif#ifdef TEST_BULK_SPEEDchar tmpOut[TX_BUF_SIZE];char tmpIn[RX_BUF_SIZE];uint8_t Count = 0;uint64_t ComCnt = 0;uint64_t errCnt = 0;struct timeb rawtime;ftime(&rawtime);uint64_t StartTime =  rawtime.time;for( ;; ){for( uint16_t i = 0; i < sizeof(tmpOut); i++ ){tmpOut[i] = Count++;}ComCnt ++;ret = transfer_bulk_async(dev, EP_OUT, tmpOut, sizeof(tmpOut), 5000);if (ret < 0){
//          printf("error writing:\n%s\n", usb_strerror());}else{
//          printf("success: bulk write %d bytes\n", ret);}// Running an async read testret = transfer_bulk_async(dev, EP_IN, tmpIn, sizeof(tmpIn), 5000);if (ret < 0){printf("error reading:\n%s\n", usb_strerror());}else{printf("success: bulk read %d bytes\n", ret);}//if( memcmp( tmpOut, tmpIn, BUF_SIZE ) != 0 )//{//    errCnt ++;//}for( int j = 0; j < TX_BUF_SIZE; j++ ){if( tmpOut[j] != tmpIn[j] ){errCnt ++;break;}}if( (ComCnt % 2000) == 0 ){printf("ComCnt:%d  ",ComCnt );printf("errCnt:%d \n",errCnt );struct timeb rawtime1;ftime(&rawtime1);uint64_t endTime = rawtime1.time;printf("transfer speed:%0.2f bps\n", ((float)(ComCnt * TX_BUF_SIZE * 2 * 8) / (endTime - StartTime)) );}//        Sleep(3);}
#endif#ifdef TEST_BULK_WRITE#ifdef BENCHMARK_DEVICE      ret = usb_control_msg(dev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,14, /* set/get test */2,  /* test type    */MY_INTF,  /* interface id */tmp, 1, 1000);     //从默认的管道发送和接受控制数据--lwz#endif#ifdef TEST_ASYNC// Running an async write testfor( int i = 0; i < sizeof(tmp); i++ ){tmp[i] = i;}ret = transfer_bulk_async(dev, EP_OUT, tmp, sizeof(tmp), 5000);#else// Running a sync write testret = usb_bulk_write(dev, EP_OUT, tmp, sizeof(tmp), 5000);#endifif (ret < 0){printf("error writing:\n%s\n", usb_strerror());}else{printf("success: bulk write %d bytes\n", ret);}
#endifmemset(tmp, 0 , TX_BUF_SIZE );
#ifdef TEST_BULK_READ#ifdef BENCHMARK_DEVICEret = usb_control_msg(dev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,14, /* set/get test */1,  /* test type    */MY_INTF,  /* interface id */tmp, 1, 1000);#endif#ifdef TEST_ASYNC      //有声明--lwz// Running an async read testret = transfer_bulk_async(dev, EP_IN, tmp, sizeof(tmp), 5000);#else// Running a sync read testret = usb_bulk_read(dev, EP_IN, tmp, sizeof(tmp), 5000);#endifif (ret < 0){printf("error reading:\n%s\n", usb_strerror());}else{printf("success: bulk read %d bytes\n", ret);for(int i = 0; i < ret; i++ ){printf( "%02X ", tmp[i]);}printf("\n");}
#endif#ifdef TEST_BULK_READ#ifdef BENCHMARK_DEVICEret = usb_control_msg(dev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,14, /* set/get test */1,  /* test type    */MY_INTF,  /* interface id */tmp, 1, 1000);#endif#ifdef TEST_ASYNC// Running an async read testret = transfer_bulk_async(dev, EP_IN, tmp, sizeof(tmp), 5000);#else// Running a sync read testret = usb_bulk_read(dev, EP_IN, tmp, sizeof(tmp), 5000);#endifif (ret < 0){printf("error reading:\n%s\n", usb_strerror());}else{printf("success: bulk read %d bytes\n", ret);}
#endif#ifdef TEST_CLAIM_INTERFACEusb_release_interface(dev, 0);   //注销被usb_claim_interface函数调用后的接口,释放资源  --lwz
#endifif (dev){usb_close(dev);}printf("Done.\n");return 0;    }/*
* Read/Write using async transfer functions.
*
* NOTE: This function waits for the transfer to complete essentially making
* it a sync transfer function so it only serves as an example of how one might
* implement async transfers into thier own code.
*/
static int transfer_bulk_async(usb_dev_handle *dev,int ep,char *bytes,int size,int timeout)
{// Each async transfer requires it's own context. A transfer// context can be re-used.  When no longer needed they must be// freed with usb_free_async().//void* async_context = NULL;int ret;// Setup the async transfer.  This only needs to be done once// for multiple submit/reaps. (more below)//ret = usb_bulk_setup_async(dev, &async_context, ep);if (ret < 0){printf("error usb_bulk_setup_async:\n%s\n", usb_strerror());goto Done;}// Submit this transfer.  This function returns immediately and the// transfer is on it's way to the device.//ret = usb_submit_async(async_context, bytes, size);if (ret < 0){printf("error usb_submit_async:\n%s\n", usb_strerror());usb_free_async(&async_context);goto Done;}// Wait for the transfer to complete.  If it doesn't complete in the// specified time it is cancelled.  see also usb_reap_async_nocancel().//ret = usb_reap_async(async_context, timeout);// Free the context.usb_free_async(&async_context);Done:return ret;
}//
//  usb_dev_read_async.
//
int usb_dev_read_async( uint8_t *Buf, uint16_t bufsz, int timeout )
{if( dev == NULL ){return 0;}int ret;char tmp[RX_BUF_SIZE];ret = transfer_bulk_async(dev, EP_IN, tmp, RX_BUF_SIZE, timeout );if( ret > 0 ){if( bufsz >= ret ){memcpy(Buf, tmp, ret );}}return ret;
}
//
//  usb_dev_write_async.
//
bool usb_dev_write_async( uint8_t *Datas, uint16_t DataLen, int timeout )
{if( dev == NULL ){return false;}int ret;ret = transfer_bulk_async(dev, EP_OUT, (char *)Datas, DataLen , timeout);if( ret < 0 ){return false;}return true;
}
//
//  usb_dev_read_sync.
//
uint16_t usb_dev_read_sync( uint8_t *Buf, uint16_t bufsz )
{if( dev == NULL ){return 0;}int ret;char tmp[RX_BUF_SIZE];ret = usb_bulk_read(dev, EP_IN, tmp, RX_BUF_SIZE,5000);if( ret > 0 ){if( bufsz >= ret ){memcpy(Buf, tmp, ret );}}return ret;
}

上位机运行日志如下:

计算出的速率大约2.7MB/s,比全速高一点,这个速度还有待提升。

NUC980技术交流QQ群:912184327

NK-RTU980 USB bulk传输相关推荐

  1. STM32F105 实现USB BULK传输

    基于STM32F105 实现USB-BULK传输 由于项目需要,需要USB来传输,之前试的HID模式是已经调通,HID基于中断传输,一毫秒侦测一次,每次的传输量为64字节,一般传输量小的可以采用这种模 ...

  2. 自定义USB BULK设计(一)——固件程序,LPC2378

    前段时间买了块D12+51的开发板来玩,现在公司要求用ARM来做一个USB项目.原来用D12也就做了个LED流水灯,还是HID设备的,现在不能满足要求,你总不能显示公司的设备时,还搞个"人体 ...

  3. usb音频传输的优劣

    这是在网络上找到比较好关于usb音频传输的文章,本人只是整理!!原作者:我代表广大人民 首先,为什么要去找和整理这篇文章!?起源是在一个qq群里面想和一位q友交流.. 不想特别针对人,只想对事,所以, ...

  4. 基于WinUSB的异步方式bulk传输的稳定性问题

    某项目中,设备与PC之间通过USB Bulk模式进行数据传输,PC端的APP跑在Win10上,跟设备通信这部分原本是基于libusb开发的,运行稳定.后来考虑到PC端APP只有for Windows一 ...

  5. Android使用usb线传输大文件笔记

    使用usb线传输大文件 参考资料: 使用USB数据线连接PC端和Android端进行数据的交互 安卓设备通过USB接口实现与pc端的简单数据通信 Socket TCP/IP协议数据传输过程中的粘包和分 ...

  6. linux usb 批量传输文件,一种Linux系统下提升usb批量传输速度的方法及系统与流程...

    本发明涉及通信传输技术领域,具体地说是一种linux系统下提升usb批量传输速度的方法及系统. 背景技术: linux系统访问usb设备有两种方式:编写内核驱动模块ko和在用户空间编写程序,通过内核提 ...

  7. MS2109 HDMI转USB 高清视频传输方案

    MS2109  HDMI转USB 高清视频传输方案 MS2109是一款高清视频传采集晶片,内部集成USB2.0控制器和数据收发模块,HDMIRX模块和音视频处理模块.MS2109可以将HDMI接口输出 ...

  8. 【安富莱专题教程第8期】基于emWin模拟器的USB BULK上位机开发,仅需C即可,简单易实现...

    说明: 1.如果你会emWin话的,就可以轻松制作上位机.做些通信和控制类上位机,比使用C#之类的方便程度一点不差,而且你仅会C语言就可以. 2.并且成功将emWin人性化,可以做些Windows系统 ...

  9. 关于USB bulk设备中的CBW和CSW

    网上关于USB的讲解很多,讲的好的大家可以参见<linux那些事儿之我是USB>,非常具有趣味性.此处恕我才疏学浅只能记录一些皮毛.因为在做烧写工具,所以涉及到这部分的知识.在之前的经验教 ...

  10. Android usb 控制传输,【android之USB通信】android之USB数据传输-Go语言中文社区

    因为老板认为wifi连接的方式传输数据太慢,想通过USB传输来实现与硬件的连接,所以通过android客户端作为主设备,终端硬件作为从设备.其中收到数据的处理和 下发设置帧的生成与wifi连接的方式都 ...

最新文章

  1. 小米Max怎么刷入开发版获得root超级权限
  2. ajax查询数据返回结果不变
  3. 二叉树的二叉链表存储结构构建以及先序遍历
  4. 16.1116 NOIP 考前模拟(信心题)
  5. WAMPSerrver集成环境的下载安装
  6. 小知识—PRINCE2的七大原则之剪裁
  7. Numpy 数组操作
  8. js 自动分配金额_(2.4w字,建议收藏)??原生JS灵魂之问(下), 冲刺??进阶最后一公里(附个人成长经验分享)
  9. 为什么鲍尔默时代的微软会一败再败?
  10. java jdbc 占位符_java-jdbc
  11. Unity UGUI——Text组件(Character)
  12. JAVA-Servlet操纵方法
  13. ID3、C4.5、CART决策树算法解析(关键内容讲解)
  14. 步进电机正反转实验_电机正反转电路图讲解
  15. The current branch master has no upstream branch.的解决
  16. 引用生产任务单下推进行生产领料,金蝶KIS旗舰版盘点机PDA进销存,车间生产领料防止出错,生产领料流程,根据BOM物料清单自动计算领料数量
  17. 如何培养孩子的阅读兴趣
  18. python中argument什么意思_Python中parameters与argument区别
  19. AI笔记: 数学基础之二项分布与二项式定理
  20. squeeze 、unsequeeze

热门文章

  1. 请你来说一下数字证书是什么,里面都包含那些内容
  2. 游戏策划一类的,非常好
  3. 土地资源管理考研资料分享
  4. oracle统计每个员工数,oracle按部门统计员工人数
  5. 测试用例管理工具~JIRA
  6. 碰撞触发器Trigger
  7. BLE安全之SM剖析(3)
  8. linux命令vi编辑文件注释掉某一行,请问linux的vi命令进入文本编辑后怎么去删除一行?...
  9. A. 拼音魔法 大学生程序设计邀请赛(华东师范大学)
  10. 程序员相亲被大三岁的富婆姐姐看上,让他当《杭州赘婿》