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:
Stefan Rueger 2022-08-07 14:05:54 +01:00
parent 81136688f6
commit 08049a40ea
No known key found for this signature in database
GPG Key ID: B0B4F1FD86B1EC55
12 changed files with 159 additions and 37 deletions

View File

@ -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);

View File

@ -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;

View File

@ -101,8 +101,6 @@ void pyytext(void);
char * dup_string(const char * str);
char * cache_string(const char * file);
#ifdef __cplusplus
}
#endif

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -20,5 +20,6 @@
#define developer_opts_h
void dev_output_part_defs(char *partdesc);
void dev_output_pgm_defs(char *programmer);
#endif

View File

@ -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;
}

View File

@ -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

View File

@ -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");

View File

@ -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);
}

View File

@ -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;

View File

@ -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;