⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c.svn-base

📁 openmoko host system dfu-util
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/* * dfu-util * * (C) 2007-2008 by OpenMoko, Inc. * Written by Harald Welte <laforge@openmoko.org> * * Based on existing code of dfu-programmer-0.4 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <stdio.h>#include <string.h>#include <getopt.h>#include <usb.h>#include <errno.h>#include "dfu.h"#include "usb_dfu.h"#include "sam7dfu.h"#include "dfu-version.h"#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef HAVE_USBPATH_H#include <usbpath.h>#endif/* define a portable function for reading a 16bit little-endian word */unsigned short get_int16_le(const void *p){    const unsigned char *cp = p;    return ( cp[0] ) | ( ((unsigned short)cp[1]) << 8 );}int debug;static int verbose = 0;#define DFU_IFF_DFU		0x0001	/* DFU Mode, (not Runtime) */#define DFU_IFF_VENDOR		0x0100#define DFU_IFF_PRODUCT		0x0200#define DFU_IFF_CONFIG		0x0400#define DFU_IFF_IFACE		0x0800#define DFU_IFF_ALT		0x1000#define DFU_IFF_DEVNUM		0x2000#define DFU_IFF_PATH		0x4000struct usb_vendprod {	u_int16_t vendor;	u_int16_t product;};struct dfu_if {	u_int16_t vendor;	u_int16_t product;	u_int8_t configuration;	u_int8_t interface;	u_int8_t altsetting;	int bus;	u_int8_t devnum;	const char *path;	unsigned int flags;	struct usb_device *dev;	struct usb_dev_handle *dev_handle;};static int _get_first_cb(struct dfu_if *dif, void *v){	struct dfu_if *v_dif = v;	memcpy(v_dif, dif, sizeof(*v_dif)-sizeof(struct usb_dev_handle *));	/* return a value that makes find_dfu_if return immediately */	return 1;}/* Find a DFU interface (and altsetting) in a given device */static int find_dfu_if(struct usb_device *dev, int (*handler)(struct dfu_if *, void *), void *v){	struct usb_config_descriptor *cfg;	struct usb_interface_descriptor *intf;	struct usb_interface *uif;	struct dfu_if _dif, *dfu_if = &_dif;	int cfg_idx, intf_idx, alt_idx;	int rc;	memset(dfu_if, 0, sizeof(*dfu_if));		for (cfg_idx = 0; cfg_idx < dev->descriptor.bNumConfigurations;	     cfg_idx++) {		cfg = &dev->config[cfg_idx];		/* in some cases, noticably FreeBSD if uid != 0,		 * the configuration descriptors are empty */		if (!cfg)			return 0;		for (intf_idx = 0; intf_idx < cfg->bNumInterfaces;		     intf_idx++) {			uif = &cfg->interface[intf_idx];			if (!uif)				return 0;			for (alt_idx = 0;			     alt_idx < uif->num_altsetting; alt_idx++) {				intf = &uif->altsetting[alt_idx];				if (!intf)					return 0;				if (intf->bInterfaceClass == 0xfe &&				    intf->bInterfaceSubClass == 1) {					dfu_if->dev = dev;					dfu_if->vendor =						dev->descriptor.idVendor;					dfu_if->product =						dev->descriptor.idProduct;					dfu_if->configuration = cfg_idx;					dfu_if->interface = 						intf->bInterfaceNumber;					dfu_if->altsetting = 						intf->bAlternateSetting;					if (intf->bInterfaceProtocol == 2)						dfu_if->flags |= 							DFU_IFF_DFU;					else						dfu_if->flags &=							~DFU_IFF_DFU;					if (!handler)						return 1;					rc = handler(dfu_if, v);					if (rc != 0)						return rc;				}			}		}	}	return 0;}static int get_first_dfu_if(struct dfu_if *dif){	return find_dfu_if(dif->dev, &_get_first_cb, (void *) dif);}#define MAX_STR_LEN 64static int print_dfu_if(struct dfu_if *dfu_if, void *v){	struct usb_device *dev = dfu_if->dev;	int if_name_str_idx;	char name[MAX_STR_LEN+1] = "UNDEFINED";	if_name_str_idx = dev->config[dfu_if->configuration]				.interface[dfu_if->interface]				.altsetting[dfu_if->altsetting].iInterface;	if (if_name_str_idx) {		if (!dfu_if->dev_handle)			dfu_if->dev_handle = usb_open(dfu_if->dev);		if (dfu_if->dev_handle)			usb_get_string_simple(dfu_if->dev_handle,					      if_name_str_idx, name,					      MAX_STR_LEN);	}	printf("Found %s: [0x%04x:0x%04x] devnum=%u, cfg=%u, intf=%u, "	       "alt=%u, name=\"%s\"\n", 	       dfu_if->flags & DFU_IFF_DFU ? "DFU" : "Runtime",	       dev->descriptor.idVendor, dev->descriptor.idProduct,	       dev->devnum, dfu_if->configuration, dfu_if->interface,	       dfu_if->altsetting, name);	return 0;}static int alt_by_name(struct dfu_if *dfu_if, void *v){	struct usb_device *dev = dfu_if->dev;	int if_name_str_idx;	char name[MAX_STR_LEN+1] = "UNDEFINED";	if_name_str_idx =	    dev->config[dfu_if->configuration].interface[dfu_if->interface].	    altsetting[dfu_if->altsetting].iInterface;	if (!if_name_str_idx)		return 0;	if (!dfu_if->dev_handle)		dfu_if->dev_handle = usb_open(dfu_if->dev);	if (!dfu_if->dev_handle)		return 0;	if (usb_get_string_simple(dfu_if->dev_handle, if_name_str_idx, name,	     MAX_STR_LEN) < 0)		return 0; /* should we return an error here ? */	if (strcmp(name, v))		return 0;	/*	 * Return altsetting+1 so that we can use return value 0 to indicate	 * "not found".	 */	return dfu_if->altsetting+1;}static int _count_cb(struct dfu_if *dif, void *v){	int *count = v;	(*count)++;	return 0;}/* Count DFU interfaces within a single device */static int count_dfu_interfaces(struct usb_device *dev){	int num_found = 0;	find_dfu_if(dev, &_count_cb, (void *) &num_found);	return num_found;}/* Iterate over all matching DFU capable devices within system */static int iterate_dfu_devices(struct dfu_if *dif,    int (*action)(struct usb_device *dev, void *user), void *user){	struct usb_bus *usb_bus;	struct usb_device *dev;	/* Walk the tree and find our device. */	for (usb_bus = usb_get_busses(); NULL != usb_bus;	     usb_bus = usb_bus->next) {		for (dev = usb_bus->devices; NULL != dev; dev = dev->next) {			int retval;			if (dif && (dif->flags &			    (DFU_IFF_VENDOR|DFU_IFF_PRODUCT)) &&		    	    (dev->descriptor.idVendor != dif->vendor ||		     	    dev->descriptor.idProduct != dif->product))				continue;			if (dif && (dif->flags & DFU_IFF_DEVNUM) &&		    	    (atoi(usb_bus->dirname) != dif->bus ||		     	    dev->devnum != dif->devnum))				continue;			if (!count_dfu_interfaces(dev))				continue;			retval = action(dev, user);			if (retval)				return retval;		}	}	return 0;}static int found_dfu_device(struct usb_device *dev, void *user){	struct dfu_if *dif = user;	dif->dev = dev;	return 1;}/* Find the first DFU-capable device, save it in dfu_if->dev */static int get_first_dfu_device(struct dfu_if *dif){	return iterate_dfu_devices(dif, found_dfu_device, dif);}static int count_one_dfu_device(struct usb_device *dev, void *user){	int *num = user;	(*num)++;	return 0;}/* Count DFU capable devices within system */static int count_dfu_devices(struct dfu_if *dif){	int num_found = 0;	iterate_dfu_devices(dif, count_one_dfu_device, &num_found);	return num_found;}static int list_dfu_interfaces(void){	struct usb_bus *usb_bus;	struct usb_device *dev;	/* Walk the tree and find our device. */	for (usb_bus = usb_get_busses(); NULL != usb_bus;	     usb_bus = usb_bus->next ) {		for (dev = usb_bus->devices; NULL != dev; dev = dev->next) {			find_dfu_if(dev, &print_dfu_if, NULL);		}	}	return 0;}static int parse_vendprod(struct usb_vendprod *vp, const char *str){	unsigned long vend, prod;	const char *colon;	colon = strchr(str, ':');	if (!colon || strlen(colon) < 2)		return -EINVAL;	vend = strtoul(str, NULL, 16);	prod = strtoul(colon+1, NULL, 16);	if (vend > 0xffff || prod > 0xffff)		return -EINVAL;	vp->vendor = vend;	vp->product = prod;	return 0;}#ifdef HAVE_USBPATH_Hstatic int resolve_device_path(struct dfu_if *dif){	int res;	res = usb_path2devnum(dif->path);	if (res < 0)		return -EINVAL;	if (!res)		return 0;	dif->bus = atoi(dif->path);	dif->devnum = res;	dif->flags |= DFU_IFF_DEVNUM;	return res;}#else /* HAVE_USBPATH_H */static int resolve_device_path(struct dfu_if *dif){	fprintf(stderr,	    "USB device paths are not supported by this dfu-util.\n");	exit(1);}#endif /* !HAVE_USBPATH_H */static void help(void){	printf("Usage: dfu-util [options] ...\n"		"  -h --help\t\t\tPrint this help message\n"		"  -V --version\t\t\tPrint the version number\n"		"  -l --list\t\t\tList the currently attached DFU capable USB devices\n"		"  -d --device vendor:product\tSpecify Vendor/Product ID of DFU device\n"		"  -p --path bus-port. ... .port\tSpecify path to DFU device\n"		"  -c --cfg config_nr\t\tSpecify the Configuration of DFU device\n"		"  -i --intf intf_nr\t\tSpecify the DFU Interface number\n"		"  -a --alt alt\t\t\tSpecify the Altsetting of the DFU Interface\n"		"\t\t\t\tby name or by number\n"		"  -t --transfer-size\t\tSpecify the number of bytes per USB Transfer\n"		"  -U --upload file\t\tRead firmware from device into <file>\n"		"  -D --download file\t\tWrite firmware from <file> into device\n"		"  -R --reset\t\t\tIssue USB Reset signalling once we're finished\n"		);}static void print_version(void){	printf("dfu-util version %s\n", VERSION "+svn" DFU_UTIL_VERSION);}static struct option opts[] = {	{ "help", 0, 0, 'h' },	{ "version", 0, 0, 'V' },	{ "verbose", 0, 0, 'v' },	{ "list", 0, 0, 'l' },	{ "device", 1, 0, 'd' },	{ "path", 1, 0, 'p' },	{ "configuration", 1, 0, 'c' },	{ "cfg", 1, 0, 'c' },	{ "interface", 1, 0, 'i' },	{ "intf", 1, 0, 'i' },	{ "altsetting", 1, 0, 'a' },	{ "alt", 1, 0, 'a' },	{ "transfer-size", 1, 0, 't' },	{ "upload", 1, 0, 'U' },	{ "download", 1, 0, 'D' },	{ "reset", 0, 0, 'R' },};enum mode {	MODE_NONE,	MODE_UPLOAD,	MODE_DOWNLOAD,};int main(int argc, char **argv)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -