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

📄 ezusb_loader.cpp

📁 linux下的jtag调试软件
💻 CPP
字号:
/* * Copyright (C) 1999 Dirk-Willem van Gulik, dirkx@webweaving.org *	WebWeaving Consultancy, All rights reserved. * * Original version for FreeBSD; Changes for Linux by Brad Hards, * brad.hards@dao.defence.gov.au. See '#ifdef BSD'. * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY WEBWEAVING AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL WEBWEAVING OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ * * This downloader should work with all with all USB-EZ Anchorchips which * have on board ram; i.e. the AN21y1, AN21y5 and AN21y6QC series. Where y * is the log2 of the internal memory size (i.e. aAN2146QC has 2^64=16kByte * of ram.) * * It has however only been tested; and written specifically for the * ActiveWire Inc. USB board. See *	http://www.activewireinc.com * * Anchorchips has excelent documentation on line at *	http://www.anchorchips.com *//*	This file is part of PXA250 USB JTAG controller.	It has been heavily modified by Jean-Marc Koller	and then by Julien Pilet <julien.pilet@epfl.ch> and	Stephane Magnenat <stephane.magnenat@epfl.ch>*//*! This is the implementation of the EzUSB loader * * \author Dirk-Willem van Gulik <dirkx@webweaving.org> (FreeBSD original version) * \author Brad Hards <brad.hards@dao.defence.gov.au> (Linux version) * \author Jean-Marc Koller <jean-marc.koller@csem.ch> (fix and enhancement) * \author Julien Pilet <julien.pilet@epfl.ch> (C++ version) * \author Stephane Magnenat <stephane.magnenat@epfl.ch> (C++ version) */#include <string.h>#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <errno.h>#ifdef HAVE_GETOPT_LONG#include <getopt.h>#endif#include "ezusb_loader.h"#include "jtag_order.h"#include "jtag.h"#include "filemanager.h"EzUSB::EzUSB(const char *filename){	idVendor=0x547;	idProduct=0x2131;	if (filename)	{		strncpy(this->filename, filename, 1024);		this->filename[sizeof(this->filename)-1]=0;	}	else		this->filename[0]=0;	devHandle=NULL;};EzUSB::~EzUSB(void){	forceClose();}void EzUSB::forceClose(void){	if (devHandle)	{		//usb_release_interface(devHandle, 0);		//usb_close(devHandle);		//printf("Closing device\n");		printf("USB : Reseting device\n");		usb_reset(devHandle);	}}void EzUSB::parseCmdLine(int argc, char *argv[]){#ifdef HAVE_GETOPT_LONG	int ch;	struct option longOptions[] =	{		{"idvendor", 1, 0, 'v'},		{"idproduct", 1, 0, 'p'},		{"filaname", 1, 0, 'f'},		{0, 0, 0, 0}	};	// handle the arguments	while((ch = getopt_long(argc, argv, "vpf", longOptions, NULL)) != -1)	{		switch (ch)		{			case 'v':				idVendor=atoi(optarg);				break;			case 'p':				idProduct=atoi(optarg);				break;			case 'f':				if (optarg)				{					strncpy(filename, optarg, 1024);					filename[sizeof(filename)-1]=0;				}				break;			default:				break;		};	}#else	if (argc>1)		fprintf(stderr, "WARNING ignoring arguments for EzUSB"				" initialisation: getopt_long is not available !\n");#endif}bool EzUSB::findDevice(void){	struct usb_bus* bus;	struct usb_device* device;	if (devHandle)	{		// TODO : libusb doesn't seems to work here, check on other plateform		/*printf("USB : Device already exists, reloading...\n");		usb_resetep(devHandle, 2);		usb_release_interface( devHandle, 0);		//return true;*/		//usb_reset(devHandle);	}	usb_init();	usb_find_busses();	usb_find_devices();	printf("USB : Enumerating USB\n");	for( bus=usb_busses; bus; bus=bus->next )	{		for( device=bus->devices; device; device=device->next )		{			printf(" Device found : Vendor=0x%x Product=0x%x\n", device->descriptor.idVendor, device->descriptor.idProduct );			if (device->descriptor.idVendor==idVendor && device->descriptor.idProduct==idProduct)			{				printf(" Correct device found :-)\n");				devHandle = usb_open( device );				if (devHandle)				{					printf(" Device has been opened\n");					return true;				}				else				{					fprintf(stderr, " Can't open device handle : %s\n", usb_strerror());					return false;				}			}		}	}	fprintf(stderr, "USB : Device %x, %x can't be found\n", idVendor, idProduct);	return false;}bool EzUSB::downloadFirmware(const char *fn){	/* See http://www.anchorchips.com for the	 * EZ-USB Technical Reference Manual (EZUSB_TRM.pdf).	 */	#define CPUCS 0x7f92	#define USBSC 0x7fd6	FILE *f=NULL;	struct intels *hx, *d;	char b[2];	int count;	if (!devHandle)		return false;//	usb_set_configuration(devHandle, 1);	// Claim the interface	if (usb_claim_interface(devHandle, 0)<0)	{		fprintf(stderr, "USB : Can't claim interface : %s\n", usb_strerror());		return false;	}	// Set alternate interface	if (usb_set_altinterface(devHandle,0) < 0 )	{		fprintf(stderr, "USB : Can't set alternate interface : %s\n", usb_strerror());		return false;	}	// Open hex file	const char *firmware = fn;	if (filename && filename[0] != 0) // if the option -f <file> was provided		firmware = filename;	// use it.	if (!(f=fileManagerPtr->openFP(firmware, "r")))	{		fprintf(stderr, "USB : Can't open HEX file '%s' : %s\n", firmware, strerror(errno));		return false;	}	// Read hex file	hx = NULL;	if (!read_head(f, &hx))	{		fprintf(stderr, "USB : Can't read HEX file\n");		fclose(f);		return false;	}	fclose(f);	// Sent reset	b[0] = 1;	if (shunt(devHandle, CPUCS, (void *) b, 1)<0)	{		fprintf(stderr, "USB : Could not send command to bring device in reset: %s\n", usb_strerror());		return false;	}	else	{		printf("USB : Command to bring 8051 to reset sent.\n");	}	// Send data	usleep(250000);	printf("USB : Downloading ");	count=0;	for( d = hx; d; d = d->nxt)	{#if 0		if ((d->len == 1) && (plen == 64) && (d->nxt == NULL))			fprintf(stderr,"Warning - Some chips cannot cope with 64*n+1 downloads\n"					"See the erratum on the anchorchip.com site\n");#endif		if (shunt(devHandle, d->addr, (void *) (d->data), d->len)<0)		{			fprintf(stderr, "USB : Download failed : %s\n", usb_strerror());			return false;		}	 	printf(".");		fflush(stdout);		count++;	}	printf("\nUSB : All %d packets downloaded.\n", count);	usleep(250000);	b[0] = 0;	if (shunt(devHandle, CPUCS, (void *) b, 1)<0)	{		fprintf(stderr, "USB : Warning: Could not send command to get the device out of reset: %s\n", usb_strerror());		return false;	}	else		printf("USB : Command to bring 8051 out of reset sent.\n");	usleep(100000);	//usb_reset(devHandle);	//findDevice();	return true;}/* This whole reading routine sucks. you could do it in * about 12 lines with scanf(). But this is the result * from testing it on too many hex files which went through * mac/pc/unic/mail conversion loops. * * Conceptually the format is simple, just a hex * string prefixed by a colon and terminated by your * local flavour of a line break. * * ':' <len> <addr> <type> <len-data> <crc> '\r' * Where len, type and crc are two char hex, addr * is a 4 char hex value and len data is 2*len * hex chars. */int EzUSB::read_head(FILE * fh, struct intels * * doutp ){	unsigned char crc;	unsigned char buff[256*2 + 9 + 2 + 1];	/* read buffer */	unsigned char tmp[5];		/* temp buf for conversions */	unsigned char data[256];	char *last;			/* last character processed */	int len, type, c, i;	int line = 1;			/* current line number */	int comment = 0;		/* are we in a comment? */	int addr; // quat_t :-)#define WHITESPACE	" \t_-\a"#define LFCR		"\r\n"#define COMMENT		"#;/*"	/* macro for error printing */#define BAIL(x) \	do { \		fprintf(stderr, "USB : %s at line %d\n", x, line); \		return 0; \	} while(0)	/* XXX silly way of doing it. Should add a cyclic	 * buffer of course. And you could use fscanf if	 * you are not worried about broken lines. But	 * unfortunately we are.	 */	while(!feof(fh))	{		/*		 * read in the first 9 bytes:	         * : <len> <addr> <type>  -> 1+2+4+2 = 9		 */		for(i = 0; i < 9 && (c = fgetc(fh)) != EOF; /* noop */) {			if (index(LFCR, c)) {				line++;				comment = 0;				continue;			} else if (index(WHITESPACE, c)) {				continue;			} else if (index(COMMENT, c)) {				comment = 1;			}			if (comment)				continue;			buff[i] = c;			i++;		}		if (ferror(fh)) {			BAIL(strerror(errno));		} else if (feof(fh)) {			if (i)				BAIL("HDR Truncated");			else				BAIL("EOF before a type 1 line");		}		/* the colon at the begginning of the line */		if (buff[0] != ':')			BAIL("Colon expected");		/* the len field */		if (!isxdigit(buff[1]) || !isxdigit(buff[2]))			BAIL("Len malformed");		memcpy(tmp, buff+1, 2);		tmp[2]='\0';		len = strtol((const char *)tmp, &last, 16);		if (last[0] != '\0')		/* up to end of string? */			BAIL("Could not convert len");		if (len < 0 || len > 255)			BAIL("Bad len (>255)");		/* the addr field */		if (!isxdigit(buff[3]) || !isxdigit(buff[4]) ||	            !isxdigit(buff[5]) || !isxdigit(buff[6]) )			BAIL("Addr malformed");		memcpy(tmp, buff+3, 4);		tmp[4]='\0';		addr = strtol((const char *)tmp, &last, 16);		if (last[0])			/* up to end of string? */			BAIL("Could not convert addr");		/* the type field */		if (!isxdigit(buff[7]) || !isxdigit(buff[8]))			BAIL("Type malformed");		memcpy(tmp, buff+7, 2);		tmp[2]='\0';		type = strtol((const char *)tmp, &last, 16);		if (last[0] != '\0')		/* up to end of string? */			BAIL("Could not convert type");		if (type < 0 || type > 1)			BAIL("Unkown type (not one of 00, 01)");		/* read 2 * len pairs and a CRC.. */		for(i = 0; i < 2*(len)+2 && (c = fgetc(fh)) != EOF;) {			if (index(LFCR, c)) {				line++;				continue;			} else if (index(WHITESPACE, c)) {				continue;			}			if (!isxdigit(c))				BAIL("Malformed hex data");			buff[9+i] = c;			i++;		}		if (ferror(fh)) {			BAIL(strerror(errno));		} else if (i != 2*(len)+2) {			BAIL("data or CRC block Truncated");		}		for(i = 0; i < len+1+4; i++) {			memcpy(tmp, buff+1+i*2, 2);			tmp[2]='\0';			data[i] = strtol((const char *)tmp, &last, 16);			if (last[0] != '\0')	/* up to end of string? */				BAIL("Could not convert data or crc pair");		}		for(crc = 0, i = 0; i < 4+len;i++)			crc += data[i];		crc = ~crc + 1;		if (crc != data[len+4])			BAIL("Checksum mismatch");		if (len && type == 0) {			*doutp = (struct intels *)malloc(sizeof(intels));			(*doutp)->addr = addr;			(*doutp)->len = len;			(*doutp)->data = (unsigned char *)malloc(len);			memcpy((*doutp)->data, data+4, len);			doutp = &( (*doutp)->nxt );		} else if (type == 1) {			break;		} else {			BAIL("Unkown intel type");		}	}	return 1;}int EzUSB::shunt(usb_dev_handle *pdev, int at, void *d, int len){	int err;	err = usb_control_msg( pdev, 0x40,0xA0, at, 0, (char*)d, len, 1000 );	return err;}

⌨️ 快捷键说明

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