libusb in windows
最早接触 libusb 当然是在linux下面。 原来玩2440开发板的时候,网上有人写了一个基于libusb的工具,2440工作在device 模式下,我记得命令是usb slave.
然后通过这个工具将电脑上的镜像传到板子上,非常方便。
公司的项目正好有usb boot mode.这对裸机来说非常有帮助。 于是把握手机制加入以后,居然能够成功的上传镜像。
后来,我发现libusb有windows的版本,于是就把这个工具稍作修改,并且在vs2010上编译通过,并且也能够工作。
下面是代码:
#include <stdio.h>
#include <string.h>
#include <conio.h>
//#include <usb.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
//#include "dbt.h"
#include "lusb0_usb.h"
#define DEVICE_SECBULK_IDVENDOR 0x3252
#define DEVICE_SECBULK_IDPRODUCT 0x0004
struct usb_device_a6
{
usb_dev_handle *hdev;
struct usb_device *dev;
char *filebuf;
int filelen;
char usb_name[MAX_PATH];
};
struct usb_device_a6 a6_usb;
char buf_pr[512];
int usb_init_search()
{
struct usb_bus *busses, *bus;
struct usb_device *dev;
usb_init();
usb_find_busses();
usb_find_devices();
for (bus = usb_get_busses(); bus; bus = bus->next)
{
for (dev = bus->devices; dev; dev = dev->next)
{
printf("idVendor:0x%x\t,ipProduct:0x%x\n",
dev->descriptor.idVendor, dev->descriptor.idProduct);
if (
((DEVICE_SECBULK_IDVENDOR == dev->descriptor.idVendor
&& DEVICE_SECBULK_IDPRODUCT == dev->descriptor.idProduct) )
)
{
a6_usb.dev = dev;
printf("Target usb device found!\n");
return 0;
}
}
}
printf("Target usb device not found!\n");
return -1;
}
int usb_open_port()
{
a6_usb.hdev = usb_open(a6_usb.dev);
if (!a6_usb.hdev)
{
return -1;
}
else
{
if (0 != usb_claim_interface(a6_usb.hdev, 0))
{
perror("Cannot claim interface");
usb_close(a6_usb.hdev);
a6_usb.hdev = NULL;
return -1;
}
}
return 0;
}
char* prepare_write_buf(char *filename, unsigned int *len) {
char *write_buf = NULL;
int ret, ret2=0;
FILE *pfile;
int sz;
pfile=fopen(filename,"rb");
if(!pfile) {
printf("open file err\n");
return NULL;
}
fseek(pfile, 0L, SEEK_END);
sz = ftell(pfile);
fseek(pfile, 0L, SEEK_SET);
write_buf = (char*) malloc(sz);
if (NULL == write_buf) {
perror("malloc failed");
goto error;
}
ret = fread(write_buf, 1, sz, pfile);
printf("---Reading file %d\n", ret);
while(ret > 0) {
ret2 += ret;
ret=fread(write_buf+ret2,1, sz, pfile);
printf("---Reading file %d %d\n", ret,ret2);
}
if (sz != ret2) {
printf("---Reading file failed %d %d\n", sz, ret2);
goto error;
}
printf("Filename : %s\n", filename);
printf("Filesize : %d bytes\n", (int)sz);
*len = sz;
return write_buf;
error:
fclose(pfile);
if (NULL != write_buf)
free(write_buf);
sz = 0;
return NULL;
}
int usb_read_device(int *len)
{
char readbuf[32];
unsigned int *magic=(unsigned int *)readbuf;
int i;
int wantread;
memset(readbuf, 0 , sizeof(readbuf));
wantread = usb_bulk_read(a6_usb.hdev, 0x82, readbuf, 16, 5000);
for(i=0;i<16;i++)
printf("%02x ", readbuf[i]);
printf("\n0x%04x\n",*magic);
if(*magic == 0x22c3b2a1) {
*len=*(magic+2);
printf("\n0x%04x\n",*(magic+2));
return 0;
}
else
return -1;
}
int usb_write_device(unsigned int writelen, char* buf )
{
unsigned int remain = writelen;
unsigned int towrite;
while (remain)
{
towrite = remain > 256 ? 256 : remain;
if (towrite != usb_bulk_write(a6_usb.hdev, 0x2, buf + (writelen - remain),
towrite, 3000)) {
perror("usb_bulk_write failed");
break;
}
remain -= towrite;
printf("\r%d%\t %d bytes ", (writelen - remain) * 100 / writelen, writelen-remain);
fflush(stdout);
}
return remain;
}
int loadfile_A6(char *f)
{
unsigned int remain;
unsigned int writed=0;
unsigned int retwrite;
int asklen = 0;
unsigned int len;
char *buf;
//todo: add the logic here for getting file path and name
a6_usb.filebuf = prepare_write_buf(f, &len);
a6_usb.filelen = len;
if(!a6_usb.filebuf)
{
return -1;
}
buf = a6_usb.filebuf;
remain = a6_usb.filelen;
for(;;) {
Sleep(200);
if(writed == a6_usb.filelen)
{
printf("Done!\n");
return 0;
}
if(usb_read_device(&asklen) == 0) {
if(asklen > 0) {
retwrite=usb_write_device(asklen, a6_usb.filebuf+writed);
if(retwrite > 0)
break;
writed += asklen;
}
}
}
return -1;
}
int scan_enable_a6()
{
if(usb_init_search() < 0)
return -1;
if(usb_open_port() < 0)
return -1;
return 0;
}
int main(int argc, char *argv[])
{
if(scan_enable_a6() == 0)
loadfile_A6(argv[1]);
}