Implement dev option -c */[ASsrt] skeleton
Also changed usbdev, usbsn, usbvendor and usbproduct components from PROGRAMMER structure to be cached string pointers rather than fixed-size arrays. These will be initialised by pgm_new() with a pointer to nul;
This commit is contained in:
parent
81136688f6
commit
08049a40ea
|
@ -651,7 +651,7 @@ static int avrftdi_pin_setup(PROGRAMMER * pgm)
|
|||
static int avrftdi_open(PROGRAMMER * pgm, char *port)
|
||||
{
|
||||
int vid, pid, interface, index, err;
|
||||
char * serial, *desc;
|
||||
const char *serial, *desc;
|
||||
|
||||
avrftdi_t* pdata = to_pdata(pgm);
|
||||
|
||||
|
|
|
@ -672,6 +672,7 @@ void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p,
|
|||
AVRPART * avr_new_part(void)
|
||||
{
|
||||
AVRPART * p;
|
||||
char *nulp = cache_string("");
|
||||
|
||||
p = (AVRPART *)malloc(sizeof(AVRPART));
|
||||
if (p == NULL) {
|
||||
|
@ -686,8 +687,8 @@ AVRPART * avr_new_part(void)
|
|||
p->reset_disposition = RESET_DEDICATED;
|
||||
p->retry_pulse = PIN_AVR_SCK;
|
||||
p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK | AVRPART_ENABLEPAGEPROGRAMMING;
|
||||
p->parent_id = NULL;
|
||||
p->config_file = NULL;
|
||||
p->parent_id = nulp;
|
||||
p->config_file = nulp;
|
||||
p->lineno = 0;
|
||||
memset(p->signature, 0xFF, 3);
|
||||
p->ctl_stack_type = CTL_STACK_NONE;
|
||||
|
|
|
@ -101,8 +101,6 @@ void pyytext(void);
|
|||
|
||||
char * dup_string(const char * str);
|
||||
|
||||
char * cache_string(const char * file);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -532,8 +532,7 @@ prog_parm_conntype_id:
|
|||
prog_parm_usb:
|
||||
K_USBDEV TKN_EQUAL TKN_STRING {
|
||||
{
|
||||
strncpy(current_prog->usbdev, $3->value.string, PGM_USBSTRINGLEN);
|
||||
current_prog->usbdev[PGM_USBSTRINGLEN-1] = 0;
|
||||
current_prog->usbdev = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
}
|
||||
} |
|
||||
|
@ -546,22 +545,19 @@ prog_parm_usb:
|
|||
K_USBPID TKN_EQUAL usb_pid_list |
|
||||
K_USBSN TKN_EQUAL TKN_STRING {
|
||||
{
|
||||
strncpy(current_prog->usbsn, $3->value.string, PGM_USBSTRINGLEN);
|
||||
current_prog->usbsn[PGM_USBSTRINGLEN-1] = 0;
|
||||
current_prog->usbsn = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
}
|
||||
} |
|
||||
K_USBVENDOR TKN_EQUAL TKN_STRING {
|
||||
{
|
||||
strncpy(current_prog->usbvendor, $3->value.string, PGM_USBSTRINGLEN);
|
||||
current_prog->usbvendor[PGM_USBSTRINGLEN-1] = 0;
|
||||
current_prog->usbvendor = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
}
|
||||
} |
|
||||
K_USBPRODUCT TKN_EQUAL TKN_STRING {
|
||||
{
|
||||
strncpy(current_prog->usbproduct, $3->value.string, PGM_USBSTRINGLEN);
|
||||
current_prog->usbproduct[PGM_USBSTRINGLEN-1] = 0;
|
||||
current_prog->usbproduct = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -436,7 +436,7 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) {
|
|||
dev_info("#------------------------------------------------------------\n");
|
||||
dev_info("# %s\n", p->desc);
|
||||
dev_info("#------------------------------------------------------------\n");
|
||||
if(p->parent_id)
|
||||
if(p->parent_id && *p->parent_id)
|
||||
dev_info("\npart parent \"%s\"\n", p->parent_id);
|
||||
else
|
||||
dev_info("\npart\n");
|
||||
|
@ -597,9 +597,7 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// -p */[cdosw*]
|
||||
// -p */[dASsrcow*t]
|
||||
void dev_output_part_defs(char *partdesc) {
|
||||
bool cmdok, waits, opspi, descs, astrc, strct, cmpst, raw, all, tsv;
|
||||
char *flags;
|
||||
|
@ -693,7 +691,7 @@ void dev_output_part_defs(char *partdesc) {
|
|||
dev_part_strct(p, tsv,
|
||||
astrc? NULL:
|
||||
strct? nullpart:
|
||||
p->parent_id? locate_part(part_list, p->parent_id): nullpart);
|
||||
p->parent_id && *p->parent_id? locate_part(part_list, p->parent_id): nullpart);
|
||||
|
||||
if(raw)
|
||||
dev_part_raw(p);
|
||||
|
@ -891,3 +889,119 @@ void dev_output_part_defs(char *partdesc) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dev_pgm_raw(PROGRAMMER *pgm) {
|
||||
PROGRAMMER dp;
|
||||
|
||||
memcpy(&dp, pgm, sizeof dp);
|
||||
dev_raw_dump((unsigned char *) &dp, sizeof dp, pgm->desc, "pgm", 0);
|
||||
}
|
||||
|
||||
|
||||
static void dev_pgm_strct(PROGRAMMER *pgm, bool tsv, PROGRAMMER *base) {
|
||||
if(!tsv) {
|
||||
int firstid = 1;
|
||||
|
||||
dev_info("#------------------------------------------------------------\n");
|
||||
dev_info("# ");
|
||||
for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) {
|
||||
if(!firstid)
|
||||
dev_info("/");
|
||||
firstid = 0;
|
||||
dev_info("%s", ldata(ln));
|
||||
}
|
||||
dev_info("\n");
|
||||
dev_info("#------------------------------------------------------------\n");
|
||||
if(pgm->parent_id && *pgm->parent_id)
|
||||
dev_info("\nprogrammer parent \"%s\"\n", pgm->parent_id);
|
||||
else
|
||||
dev_info("\nprogrammer\n");
|
||||
}
|
||||
|
||||
if(!tsv)
|
||||
dev_info(";\n");
|
||||
}
|
||||
|
||||
|
||||
// -c */[ASsrt]
|
||||
void dev_output_pgm_defs(char *pgmid) {
|
||||
bool astrc, strct, cmpst, raw, tsv;
|
||||
char *flags;
|
||||
int nprinted;
|
||||
PROGRAMMER *nullpgm = pgm_new();
|
||||
|
||||
if((flags = strchr(pgmid, '/')))
|
||||
*flags++ = 0;
|
||||
|
||||
if(!flags && !strcmp(pgmid, "*")) // treat -c * as if it was -c */A
|
||||
flags = "A";
|
||||
|
||||
if(!*flags || !strchr("ASsrt", *flags)) {
|
||||
dev_info("%s: flags for developer option -c <wildcard>/<flags> not recognised\n", progname);
|
||||
dev_info(
|
||||
"Wildcard examples (these need protecting in the shell through quoting):\n"
|
||||
" * all known programmers\n"
|
||||
" avrftdi just this programmer\n"
|
||||
" jtag*pdi matches jtag2pdi, jtag3pdi, jtag3updi and jtag2updi\n"
|
||||
" jtag?pdi matches jtag2pdi and jtag3pdi\n"
|
||||
"Flags (one or more of the characters below):\n"
|
||||
" A show entries of avrdude.conf programmers with all values\n"
|
||||
" S show entries of avrdude.conf programmers with necessary values\n"
|
||||
" s show short entries of avrdude.conf programmers using parent\n"
|
||||
" r show entries of avrdude.conf programmers as raw dump\n"
|
||||
" t use tab separated values as much as possible\n"
|
||||
"Examples:\n"
|
||||
" $ avrdude -c usbasp/s\n"
|
||||
" $ avrdude -c */st | grep baudrate\n"
|
||||
" $ avrdude -c */r | sort\n"
|
||||
"Notes:\n"
|
||||
" -c * is the same as -c */A\n"
|
||||
" This help message is printed using any unrecognised flag, eg, -c/h\n"
|
||||
" Leaving no space after -c can be an OK substitute for quoting in shells\n"
|
||||
" /s, /S and /A outputs are designed to be used as input in avrdude.conf\n"
|
||||
" Sorted /r output should stay invariant when rearranging avrdude.conf\n"
|
||||
" These options are just to help development, so not further documented\n"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// redirect stderr to stdout
|
||||
fflush(stderr); fflush(stdout); dup2(1, 2);
|
||||
|
||||
astrc = !!strchr(flags, 'A');
|
||||
strct = !!strchr(flags, 'S');
|
||||
cmpst = !!strchr(flags, 's');
|
||||
raw = !!strchr(flags, 'r');
|
||||
tsv = !!strchr(flags, 't');
|
||||
|
||||
nprinted = dev_nprinted;
|
||||
|
||||
LNODEID ln1, ln2;
|
||||
for(ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) {
|
||||
PROGRAMMER *pgm = ldata(ln1);
|
||||
int matched = 0;
|
||||
for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2)) {
|
||||
if(part_match(pgmid, ldata(ln2))) {
|
||||
matched = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!matched)
|
||||
continue;
|
||||
|
||||
if(dev_nprinted > nprinted) {
|
||||
dev_info("\n");
|
||||
nprinted = dev_nprinted;
|
||||
}
|
||||
|
||||
if(astrc || strct || cmpst)
|
||||
dev_pgm_strct(pgm, tsv,
|
||||
astrc? NULL:
|
||||
strct? nullpgm:
|
||||
pgm->parent_id && *pgm->parent_id? locate_programmer(programmers, pgm->parent_id): nullpgm);
|
||||
|
||||
if(raw)
|
||||
dev_pgm_raw(pgm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,5 +20,6 @@
|
|||
#define developer_opts_h
|
||||
|
||||
void dev_output_part_defs(char *partdesc);
|
||||
void dev_output_pgm_defs(char *programmer);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -851,7 +851,7 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) {
|
|||
avrdude_message(MSG_NOTICE,
|
||||
"%s: ft245r_open(): no device identifier in portname, using default\n",
|
||||
progname);
|
||||
pgm->usbsn[0] = 0;
|
||||
pgm->usbsn = cache_string("");
|
||||
devnum = 0;
|
||||
} else {
|
||||
if (strlen(device) == 8 ){ // serial number
|
||||
|
@ -863,7 +863,7 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) {
|
|||
device);
|
||||
}
|
||||
// copy serial number to pgm struct
|
||||
strcpy(pgm->usbsn, device);
|
||||
pgm->usbsn = cache_string(device);
|
||||
// and use first device with matching serial (should be unique)
|
||||
devnum = 0;
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ typedef struct opcode {
|
|||
typedef struct avrpart {
|
||||
char desc[AVR_DESCLEN]; /* long part name */
|
||||
char id[AVR_IDLEN]; /* short part name */
|
||||
char * parent_id; /* parent id if set, for -p.../s */
|
||||
const char * parent_id; /* parent id if set, for -p.../s */
|
||||
char family_id[AVR_FAMILYIDLEN+1]; /* family id in the SIB (avr8x) */
|
||||
int hvupdi_variant; /* HV pulse on UPDI pin, no pin or RESET pin */
|
||||
int stk500_devcode; /* stk500 device code */
|
||||
|
@ -280,7 +280,7 @@ typedef struct avrpart {
|
|||
|
||||
LISTID mem; /* avr memory definitions */
|
||||
LISTID mem_alias; /* memory alias definitions */
|
||||
char *config_file; /* config file where defined */
|
||||
const char * config_file; /* config file where defined */
|
||||
int lineno; /* config file line number */
|
||||
} AVRPART;
|
||||
|
||||
|
@ -640,7 +640,6 @@ extern struct serial_device usbhid_serdev;
|
|||
#define PGM_DESCLEN 80
|
||||
#define PGM_PORTLEN PATH_MAX
|
||||
#define PGM_TYPELEN 32
|
||||
#define PGM_USBSTRINGLEN 256
|
||||
|
||||
typedef enum {
|
||||
EXIT_VCC_UNSPEC,
|
||||
|
@ -672,7 +671,7 @@ typedef struct programmer_t {
|
|||
char desc[PGM_DESCLEN];
|
||||
char type[PGM_TYPELEN];
|
||||
char port[PGM_PORTLEN];
|
||||
char *parent_id;
|
||||
const char *parent_id;
|
||||
void (*initpgm)(struct programmer_t * pgm);
|
||||
unsigned int pinno[N_PINS];
|
||||
struct pindef_t pin[N_PINS];
|
||||
|
@ -685,8 +684,7 @@ typedef struct programmer_t {
|
|||
int baudrate;
|
||||
int usbvid;
|
||||
LISTID usbpid;
|
||||
char usbdev[PGM_USBSTRINGLEN], usbsn[PGM_USBSTRINGLEN];
|
||||
char usbvendor[PGM_USBSTRINGLEN], usbproduct[PGM_USBSTRINGLEN];
|
||||
const char *usbdev, *usbsn, *usbvendor, *usbproduct;
|
||||
double bitclock; /* JTAG ICE clock period in microseconds */
|
||||
int ispdelay; /* ISP clock delay */
|
||||
union filedescriptor fd;
|
||||
|
@ -740,7 +738,7 @@ typedef struct programmer_t {
|
|||
int (*parseextparams) (struct programmer_t * pgm, LISTID xparams);
|
||||
void (*setup) (struct programmer_t * pgm);
|
||||
void (*teardown) (struct programmer_t * pgm);
|
||||
char *config_file; /* config file where defined */
|
||||
const char *config_file; /* config file where defined */
|
||||
int lineno; /* config file line number */
|
||||
void *cookie; /* for private use by the programmer */
|
||||
char flag; /* for private use of the programmer */
|
||||
|
@ -989,6 +987,8 @@ void cleanup_config(void);
|
|||
|
||||
int read_config(const char * file);
|
||||
|
||||
char *cache_string(const char *file);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -754,7 +754,7 @@ int main(int argc, char * argv [])
|
|||
|
||||
avrdude_message(MSG_NOTICE, "\n");
|
||||
|
||||
// developer option -p <wildcard>/[*codws] prints various aspects of part descriptions and exits
|
||||
// Developer option -p <wildcard>/[dASsrcow*t] prints part description(s) and exits
|
||||
if(partdesc && (strcmp(partdesc, "*") == 0 || strchr(partdesc, '/'))) {
|
||||
dev_output_part_defs(partdesc);
|
||||
exit(1);
|
||||
|
@ -770,6 +770,12 @@ int main(int argc, char * argv [])
|
|||
}
|
||||
}
|
||||
|
||||
// Developer option -c <wildcard>/[ASsrt] prints programmer description(s) and exits
|
||||
if(programmer && (strcmp(programmer, "*") == 0 || strchr(programmer, '/'))) {
|
||||
dev_output_pgm_defs(programmer);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (programmer) {
|
||||
if (strcmp(programmer, "?") == 0) {
|
||||
avrdude_message(MSG_INFO, "\n");
|
||||
|
|
12
src/pgm.c
12
src/pgm.c
|
@ -65,6 +65,7 @@ PROGRAMMER * pgm_new(void)
|
|||
{
|
||||
int i;
|
||||
PROGRAMMER * pgm;
|
||||
char *nulp = cache_string("");
|
||||
|
||||
pgm = (PROGRAMMER *)malloc(sizeof(*pgm));
|
||||
if (pgm == NULL) {
|
||||
|
@ -79,13 +80,18 @@ PROGRAMMER * pgm_new(void)
|
|||
pgm->usbpid = lcreat(NULL, 0);
|
||||
pgm->desc[0] = 0;
|
||||
pgm->type[0] = 0;
|
||||
pgm->parent_id = NULL;
|
||||
pgm->config_file = NULL;
|
||||
pgm->parent_id = nulp;
|
||||
pgm->config_file = nulp;
|
||||
pgm->lineno = 0;
|
||||
pgm->baudrate = 0;
|
||||
pgm->initpgm = NULL;
|
||||
pgm->hvupdi_support = lcreat(NULL, 0);
|
||||
|
||||
pgm->usbdev = nulp;
|
||||
pgm->usbsn = nulp;
|
||||
pgm->usbvendor = nulp;
|
||||
pgm->usbproduct = nulp;
|
||||
|
||||
for (i=0; i<N_PINS; i++) {
|
||||
pgm->pinno[i] = 0;
|
||||
pin_clear_all(&(pgm->pin[i]));
|
||||
|
@ -146,7 +152,7 @@ void pgm_free(PROGRAMMER * const p)
|
|||
ldestroy_cb(p->usbpid, free);
|
||||
p->id = NULL;
|
||||
p->usbpid = NULL;
|
||||
/* do not free p->parent_id nor p->config_file */
|
||||
/* do not free p->parent_id, p->config_file, p->usbdev, p->usbsn, p->usbvendor or p-> usbproduct */
|
||||
/* p->cookie is freed by pgm_teardown */
|
||||
free(p);
|
||||
}
|
||||
|
|
|
@ -65,8 +65,8 @@ static int avrdoperRxPosition = 0; /* amount of bytes already consu
|
|||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
|
||||
int product, char *productName, int doReportIDs)
|
||||
static int usbOpenDevice(union filedescriptor *fdp, int vendor, const char *vendorName,
|
||||
int product, const char *productName, int doReportIDs)
|
||||
{
|
||||
hid_device *dev;
|
||||
|
||||
|
|
|
@ -160,9 +160,9 @@ static int usbasp_transmit(PROGRAMMER * pgm, unsigned char receive,
|
|||
unsigned char functionid, const unsigned char *send,
|
||||
unsigned char *buffer, int buffersize);
|
||||
#ifdef USE_LIBUSB_1_0
|
||||
static int usbOpenDevice(libusb_device_handle **device, int vendor, char *vendorName, int product, char *productName);
|
||||
static int usbOpenDevice(libusb_device_handle **device, int vendor, const char *vendorName, int product, const char *productName);
|
||||
#else
|
||||
static int usbOpenDevice(usb_dev_handle **device, int vendor, char *vendorName, int product, char *productName);
|
||||
static int usbOpenDevice(usb_dev_handle **device, int vendor, const char *vendorName, int product, const char *productName);
|
||||
#endif
|
||||
// interface - prog.
|
||||
static int usbasp_open(PROGRAMMER * pgm, char * port);
|
||||
|
@ -337,7 +337,7 @@ static int usbasp_transmit(PROGRAMMER * pgm,
|
|||
*/
|
||||
#ifdef USE_LIBUSB_1_0
|
||||
static int usbOpenDevice(libusb_device_handle **device, int vendor,
|
||||
char *vendorName, int product, char *productName)
|
||||
const char *vendorName, int product, const char *productName)
|
||||
{
|
||||
libusb_device_handle *handle = NULL;
|
||||
int errorCode = USB_ERROR_NOTFOUND;
|
||||
|
@ -412,7 +412,7 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor,
|
|||
}
|
||||
#else
|
||||
static int usbOpenDevice(usb_dev_handle **device, int vendor,
|
||||
char *vendorName, int product, char *productName)
|
||||
const char *vendorName, int product, const char *productName)
|
||||
{
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
|
|
Loading…
Reference in New Issue