文紧接上一篇日志:基于libUSB-Win32的USB设备固件更新程序(前言),相关背景以及起因等,此处不再赘述,如感兴趣请移步。
libUSB-Win32给出的example里面,有一个bulk.c文件,分析其关键代码,结合libusb官方文档,摘出其关键代码如下:
1
2 3 4 5 6 7 |
int main
(
void
)
{ usb_dev_handle *dev = NULL ; /* the device handle */ usb_init ( ) ; /* initialize the library */ usb_find_busses ( ) ; /* find all busses */ usb_find_devices ( ) ; /* find all connected devices */ |
分析其工作流程:
首先,调用usb_init();
初始化libUSB程序库;
然后,使用usb_find_busses();
扫描机器上所有总线信息,为下一步操作提供基础信息;
接着,调用usb_find_busses();
扫描所有连接的USB设备。
以上步骤是libUSB进行操作之前所必须的步骤(根据官方文档)。
接下来,轮询总线数据,查找指定VID&PID的设备:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
//此处VID、PID为测试用,工业生产请勿使用,如有冒犯贵公司,请及时指出以便我们修改
#define MY_VID 0x0666 #define MY_PID 0x0001 //…… …… 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 ; } //…… …… 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 ) ; } |
此操作结束后,就是按照USB协议规范,按部就班的和USB Device,完成枚举的过程,以建立符合USB协议的通信:
1
2 |
usb_set_configuration
(dev, MY_CONFIG
)
;
usb_claim_interface (dev, 0 ) ; |
需要注意的是,以上函数的返回值为int型,如果该返回值>0,表示一切正常完成;该返回值<0,则表示操作失败,此时,可以调用usb_strerror();
获得详细的错误信息(注:usb_strerror();
的原型为char *usb_strerror(void);
)。
至此,与USB设备的最基本的通信(符合最基本的USB标准设备通信)已经建立。
接下来就是配合下位机发送或者接受命令和数据了:
例如:
1
2 3 4 5 6 7 8 9 10 11 12 |
//发送下载控制命令
// ret = usb_bulk_write(dev, EP_OUT, dl, sizeof(dlcmd), 5000); ret = usb_interrupt_write (dev, EP_OUT, dlcmd, sizeof (dlcmd ), 5000 ) ; printf ( "Waiting for device ready...... \n" ) ; //等待接收下位机反馈 // ret = usb_bulk_read(dev, EP_IN, get, sizeof(get), 5000); ret = usb_interrupt_read (dev, EP_IN, get, sizeof (get ), 5000 ) ; //开始发送数据,循环发送总共16KB,将整个24c128填充满 // ret = usb_bulk_write(dev, EP_IN, dldata, sizeof(dldata), 5000); ret = usb_interrupt_write (dev, EP_IN, dldata, sizeof (dldata ), 5000 ) ; |
两次发送下载数据之间,还是需要一点点延时等待的,因为8bit的MCU处理速度肯定比不上上位机。
下载完数据之后,不要忘记关闭USB设备。
if(dev)usb_close(dev);
至此,USB下载的过程已经全部完毕。由于本人编写的代码中包含有公司的PID、VID等识别信息,所以就不便放出来当测试代码了,有需要的童鞋,请自行参照libusb-Win32里面的示例代码,修改、研究、学习。
版权信息:根据libUSB的GNU/LGPL(GNU Lesser General Public License)协议许可,可以自由使用其开发私有软件。