Merge pull request #936 from stefanrueger/issue918
Fix Issue #918: Enable avrdude to send full input file incl trailing 0xff
This commit is contained in:
commit
09a95a3717
|
@ -130,4 +130,6 @@ void arduino_initpgm(PROGRAMMER * pgm)
|
||||||
pgm->read_sig_bytes = arduino_read_sig_bytes;
|
pgm->read_sig_bytes = arduino_read_sig_bytes;
|
||||||
pgm->open = arduino_open;
|
pgm->open = arduino_open;
|
||||||
pgm->close = arduino_close;
|
pgm->close = arduino_close;
|
||||||
|
|
||||||
|
disable_trailing_ff_removal(); /* so that arduino bootloader can ignore chip erase */
|
||||||
}
|
}
|
||||||
|
|
37
src/avr.c
37
src/avr.c
|
@ -278,10 +278,28 @@ int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||||
* value. This is useful for determining where to stop when dealing
|
* value. This is useful for determining where to stop when dealing
|
||||||
* with "flash" memory, since writing 0xff to flash is typically a
|
* with "flash" memory, since writing 0xff to flash is typically a
|
||||||
* no-op. Always return an even number since flash is word addressed.
|
* no-op. Always return an even number since flash is word addressed.
|
||||||
|
* Only apply this optimisation on flash-type memory.
|
||||||
*/
|
*/
|
||||||
int avr_mem_hiaddr(AVRMEM * mem)
|
int avr_mem_hiaddr(AVRMEM * mem)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
|
static int disableffopt;
|
||||||
|
|
||||||
|
/* calling once with NULL disables any future trailing-0xff optimisation */
|
||||||
|
if(!mem) {
|
||||||
|
disableffopt = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(disableffopt)
|
||||||
|
return mem->size;
|
||||||
|
|
||||||
|
/* if the memory is not a flash-type memory do not remove trailing 0xff */
|
||||||
|
if(strcasecmp(mem->desc, "flash") &&
|
||||||
|
strcasecmp(mem->desc, "application") &&
|
||||||
|
strcasecmp(mem->desc, "apptable") &&
|
||||||
|
strcasecmp(mem->desc, "boot"))
|
||||||
|
return mem->size;
|
||||||
|
|
||||||
/* return the highest non-0xff address regardless of how much
|
/* return the highest non-0xff address regardless of how much
|
||||||
memory was read */
|
memory was read */
|
||||||
|
@ -416,15 +434,8 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
|
||||||
nread++;
|
nread++;
|
||||||
report_progress(nread, npages, NULL);
|
report_progress(nread, npages, NULL);
|
||||||
}
|
}
|
||||||
if (!failure) {
|
if (!failure)
|
||||||
if (strcasecmp(mem->desc, "flash") == 0 ||
|
return avr_mem_hiaddr(mem);
|
||||||
strcasecmp(mem->desc, "application") == 0 ||
|
|
||||||
strcasecmp(mem->desc, "apptable") == 0 ||
|
|
||||||
strcasecmp(mem->desc, "boot") == 0)
|
|
||||||
return avr_mem_hiaddr(mem);
|
|
||||||
else
|
|
||||||
return mem->size;
|
|
||||||
}
|
|
||||||
/* else: fall back to byte-at-a-time write, for historical reasons */
|
/* else: fall back to byte-at-a-time write, for historical reasons */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,13 +465,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
|
||||||
report_progress(i, mem->size, NULL);
|
report_progress(i, mem->size, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(mem->desc, "flash") == 0 ||
|
return avr_mem_hiaddr(mem);
|
||||||
strcasecmp(mem->desc, "application") == 0 ||
|
|
||||||
strcasecmp(mem->desc, "apptable") == 0 ||
|
|
||||||
strcasecmp(mem->desc, "boot") == 0)
|
|
||||||
return avr_mem_hiaddr(mem);
|
|
||||||
else
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
.\"
|
.\"
|
||||||
.\" $Id$
|
.\" $Id$
|
||||||
.\"
|
.\"
|
||||||
.Dd November 22, 2021
|
.Dd July 12, 2022
|
||||||
.Os
|
.Os
|
||||||
.Dt AVRDUDE 1
|
.Dt AVRDUDE 1
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -31,6 +31,7 @@
|
||||||
.Op Fl B Ar bitclock
|
.Op Fl B Ar bitclock
|
||||||
.Op Fl c Ar programmer-id
|
.Op Fl c Ar programmer-id
|
||||||
.Op Fl C Ar config-file
|
.Op Fl C Ar config-file
|
||||||
|
.Op Fl A
|
||||||
.Op Fl D
|
.Op Fl D
|
||||||
.Op Fl e
|
.Op Fl e
|
||||||
.Oo Fl E Ar exitspec Ns
|
.Oo Fl E Ar exitspec Ns
|
||||||
|
@ -102,7 +103,7 @@ available (like almost all embedded Linux boards) you can do without
|
||||||
any additional hardware - just connect them to the MOSI, MISO, RESET
|
any additional hardware - just connect them to the MOSI, MISO, RESET
|
||||||
and SCK pins on the AVR and use the linuxgpio programmer type. It bitbangs
|
and SCK pins on the AVR and use the linuxgpio programmer type. It bitbangs
|
||||||
the lines using the Linux sysfs GPIO interface. Of course, care should
|
the lines using the Linux sysfs GPIO interface. Of course, care should
|
||||||
be taken about voltage level compatibility. Also, although not strictrly
|
be taken about voltage level compatibility. Also, although not strictly
|
||||||
required, it is strongly advisable to protect the GPIO pins from
|
required, it is strongly advisable to protect the GPIO pins from
|
||||||
overcurrent situations in some way. The simplest would be to just put
|
overcurrent situations in some way. The simplest would be to just put
|
||||||
some resistors in series or better yet use a 3-state buffer driver like
|
some resistors in series or better yet use a 3-state buffer driver like
|
||||||
|
@ -253,7 +254,7 @@ The Teensy bootloader is supported for all AVR boards.
|
||||||
As the bootloader does not support reading from flash memory,
|
As the bootloader does not support reading from flash memory,
|
||||||
use the
|
use the
|
||||||
.Fl V
|
.Fl V
|
||||||
option to prevent AVRDUDE from verifing the flash memory.
|
option to prevent AVRDUDE from verifying the flash memory.
|
||||||
See the section on
|
See the section on
|
||||||
.Em extended parameters
|
.Em extended parameters
|
||||||
for Teensy specific options.
|
for Teensy specific options.
|
||||||
|
@ -376,6 +377,20 @@ files. This can be used to add entries to the configuration
|
||||||
without patching your system wide configuration file. It can be used
|
without patching your system wide configuration file. It can be used
|
||||||
several times, the files are read in same order as given on the command
|
several times, the files are read in same order as given on the command
|
||||||
line.
|
line.
|
||||||
|
.It Fl A
|
||||||
|
Disable the automatic removal of trailing-0xFF sequences in file
|
||||||
|
input that is to be programmed to flash and in AVR reads from
|
||||||
|
flash memory. Normally, trailing 0xFFs can be discarded, as flash
|
||||||
|
programming requires the memory be erased to 0xFF beforehand.
|
||||||
|
.Fl A
|
||||||
|
should be used when the programmer hardware, or bootloader
|
||||||
|
software for that matter, does not carry out chip erase and
|
||||||
|
instead handles the memory erase on a page level. The popular
|
||||||
|
Arduino bootloader exhibits this behaviour; for this reason
|
||||||
|
.Fl A
|
||||||
|
is engaged by default when specifying
|
||||||
|
. Fl c
|
||||||
|
arduino.
|
||||||
.It Fl D
|
.It Fl D
|
||||||
Disable auto erase for flash. When the
|
Disable auto erase for flash. When the
|
||||||
.Fl U
|
.Fl U
|
||||||
|
@ -389,6 +404,10 @@ use page erase before writing each page so no explicit chip erase
|
||||||
is required.
|
is required.
|
||||||
Note however that any page not affected by the current operation
|
Note however that any page not affected by the current operation
|
||||||
will retain its previous contents.
|
will retain its previous contents.
|
||||||
|
Setting
|
||||||
|
.Fl D
|
||||||
|
implies
|
||||||
|
.Fl A.
|
||||||
.It Fl e
|
.It Fl e
|
||||||
Causes a chip erase to be executed. This will reset the contents of the
|
Causes a chip erase to be executed. This will reset the contents of the
|
||||||
flash ROM and EEPROM to the value
|
flash ROM and EEPROM to the value
|
||||||
|
|
|
@ -321,13 +321,13 @@ via a serial link (@url{https://github.com/ElTangas/jtag2updi}).
|
||||||
|
|
||||||
The Micronucleus bootloader is supported for both protocol version V1
|
The Micronucleus bootloader is supported for both protocol version V1
|
||||||
and V2. As the bootloader does not support reading from flash memory,
|
and V2. As the bootloader does not support reading from flash memory,
|
||||||
use the @code{-V} option to prevent AVRDUDE from verifing the flash memory.
|
use the @code{-V} option to prevent AVRDUDE from verifying the flash memory.
|
||||||
See the section on @emph{extended parameters}
|
See the section on @emph{extended parameters}
|
||||||
below for Micronucleus specific options.
|
below for Micronucleus specific options.
|
||||||
|
|
||||||
The Teensy bootloader is supported for all AVR boards.
|
The Teensy bootloader is supported for all AVR boards.
|
||||||
As the bootloader does not support reading from flash memory,
|
As the bootloader does not support reading from flash memory,
|
||||||
use the @code{-V} option to prevent AVRDUDE from verifing the flash memory.
|
use the @code{-V} option to prevent AVRDUDE from verifying the flash memory.
|
||||||
See the section on @emph{extended parameters}
|
See the section on @emph{extended parameters}
|
||||||
below for Teensy specific options.
|
below for Teensy specific options.
|
||||||
|
|
||||||
|
@ -495,6 +495,16 @@ without patching your system wide configuration file. It can be used
|
||||||
several times, the files are read in same order as given on the command
|
several times, the files are read in same order as given on the command
|
||||||
line.
|
line.
|
||||||
|
|
||||||
|
@item -A
|
||||||
|
Disable the automatic removal of trailing-0xFF sequences in file
|
||||||
|
input that is to be programmed to flash and in AVR reads from
|
||||||
|
flash memory. Normally, trailing 0xFFs can be discarded, as flash
|
||||||
|
programming requires the memory be erased to 0xFF beforehand. -A
|
||||||
|
should be used when the programmer hardware, or bootloader
|
||||||
|
software for that matter, does not carry out chip erase and
|
||||||
|
instead handles the memory erase on a page level. The popular
|
||||||
|
Arduino bootloader exhibits this behaviour; for this reason -A is
|
||||||
|
engaged by default when specifying -c arduino.
|
||||||
|
|
||||||
@item -D
|
@item -D
|
||||||
Disable auto erase for flash. When the -U option with flash memory is
|
Disable auto erase for flash. When the -U option with flash memory is
|
||||||
|
@ -506,6 +516,7 @@ use page erase before writing each page so no explicit chip erase
|
||||||
is required.
|
is required.
|
||||||
Note however that any page not affected by the current operation
|
Note however that any page not affected by the current operation
|
||||||
will retain its previous contents.
|
will retain its previous contents.
|
||||||
|
Setting -D implies -A.
|
||||||
|
|
||||||
@item -e
|
@item -e
|
||||||
Causes a chip erase to be executed. This will reset the contents of the
|
Causes a chip erase to be executed. This will reset the contents of the
|
||||||
|
|
23
src/fileio.c
23
src/fileio.c
|
@ -1446,16 +1446,17 @@ static int fmt_autodetect(char * fname)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int fileio(int op, char * filename, FILEFMT format,
|
int fileio(int oprwv, char * filename, FILEFMT format,
|
||||||
struct avrpart * p, char * memtype, int size)
|
struct avrpart * p, char * memtype, int size)
|
||||||
{
|
{
|
||||||
int rc;
|
int op, rc;
|
||||||
FILE * f;
|
FILE * f;
|
||||||
char * fname;
|
char * fname;
|
||||||
struct fioparms fio;
|
struct fioparms fio;
|
||||||
AVRMEM * mem;
|
AVRMEM * mem;
|
||||||
int using_stdio;
|
int using_stdio;
|
||||||
|
|
||||||
|
op = oprwv == FIO_READ_FOR_VERIFY? FIO_READ: oprwv;
|
||||||
mem = avr_locate_mem(p, memtype);
|
mem = avr_locate_mem(p, memtype);
|
||||||
if (mem == NULL) {
|
if (mem == NULL) {
|
||||||
avrdude_message(MSG_INFO, "fileio(): memory type \"%s\" not configured for device \"%s\"\n",
|
avrdude_message(MSG_INFO, "fileio(): memory type \"%s\" not configured for device \"%s\"\n",
|
||||||
|
@ -1585,18 +1586,14 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc > 0) {
|
/* on reading flash other than for verify set the size to location of highest non-0xff byte */
|
||||||
if ((op == FIO_READ) && (strcasecmp(mem->desc, "flash") == 0 ||
|
if (rc > 0 && oprwv == FIO_READ) {
|
||||||
strcasecmp(mem->desc, "application") == 0 ||
|
int hiaddr = avr_mem_hiaddr(mem);
|
||||||
strcasecmp(mem->desc, "apptable") == 0 ||
|
|
||||||
strcasecmp(mem->desc, "boot") == 0)) {
|
if(hiaddr < rc) /* if trailing-0xff not disabled */
|
||||||
/*
|
rc = hiaddr;
|
||||||
* if we are reading flash, just mark the size as being the
|
|
||||||
* highest non-0xff byte
|
|
||||||
*/
|
|
||||||
rc = avr_mem_hiaddr(mem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format != FMT_IMM && !using_stdio) {
|
if (format != FMT_IMM && !using_stdio) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -797,6 +797,7 @@ int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
|
||||||
|
|
||||||
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);
|
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);
|
||||||
|
|
||||||
|
#define disable_trailing_ff_removal() avr_mem_hiaddr(NULL)
|
||||||
int avr_mem_hiaddr(AVRMEM * mem);
|
int avr_mem_hiaddr(AVRMEM * mem);
|
||||||
|
|
||||||
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
|
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
|
||||||
|
@ -835,7 +836,8 @@ struct fioparms {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
FIO_READ,
|
FIO_READ,
|
||||||
FIO_WRITE
|
FIO_WRITE,
|
||||||
|
FIO_READ_FOR_VERIFY,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -844,7 +846,7 @@ extern "C" {
|
||||||
|
|
||||||
char * fmtstr(FILEFMT format);
|
char * fmtstr(FILEFMT format);
|
||||||
|
|
||||||
int fileio(int op, char * filename, FILEFMT format,
|
int fileio(int oprwv, char * filename, FILEFMT format,
|
||||||
struct avrpart * p, char * memtype, int size);
|
struct avrpart * p, char * memtype, int size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -110,7 +110,8 @@ static void usage(void)
|
||||||
" -B <bitclock> Specify JTAG/STK500v2 bit clock period (us).\n"
|
" -B <bitclock> Specify JTAG/STK500v2 bit clock period (us).\n"
|
||||||
" -C <config-file> Specify location of configuration file.\n"
|
" -C <config-file> Specify location of configuration file.\n"
|
||||||
" -c <programmer> Specify programmer type.\n"
|
" -c <programmer> Specify programmer type.\n"
|
||||||
" -D Disable auto erase for flash memory\n"
|
" -A Disable trailing-0xff removal from file and AVR read.\n"
|
||||||
|
" -D Disable auto erase for flash memory; implies -A.\n"
|
||||||
" -i <delay> ISP Clock Delay [in microseconds]\n"
|
" -i <delay> ISP Clock Delay [in microseconds]\n"
|
||||||
" -P <port> Specify connection port.\n"
|
" -P <port> Specify connection port.\n"
|
||||||
" -F Override invalid signature check.\n"
|
" -F Override invalid signature check.\n"
|
||||||
|
@ -442,7 +443,7 @@ int main(int argc, char * argv [])
|
||||||
/*
|
/*
|
||||||
* process command line arguments
|
* process command line arguments
|
||||||
*/
|
*/
|
||||||
while ((ch = getopt(argc,argv,"?b:B:c:C:DeE:Fi:l:np:OP:qstU:uvVx:yY:")) != -1) {
|
while ((ch = getopt(argc,argv,"?Ab:B:c:C:DeE:Fi:l:np:OP:qstU:uvVx:yY:")) != -1) {
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'b': /* override default programmer baud rate */
|
case 'b': /* override default programmer baud rate */
|
||||||
|
@ -528,6 +529,10 @@ int main(int argc, char * argv [])
|
||||||
|
|
||||||
case 'D': /* disable auto erase */
|
case 'D': /* disable auto erase */
|
||||||
uflags &= ~UF_AUTO_ERASE;
|
uflags &= ~UF_AUTO_ERASE;
|
||||||
|
/* fall through */
|
||||||
|
|
||||||
|
case 'A': /* explicit disabling of trailing-0xff removal */
|
||||||
|
disable_trailing_ff_removal();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e': /* perform a chip erase */
|
case 'e': /* perform a chip erase */
|
||||||
|
|
|
@ -341,7 +341,7 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
||||||
progname, mem->desc, alias_mem_desc, upd->filename);
|
progname, mem->desc, alias_mem_desc, upd->filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
|
rc = fileio(FIO_READ_FOR_VERIFY, upd->filename, upd->format, p, upd->memtype, -1);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
avrdude_message(MSG_INFO, "%s: read from file '%s' failed\n",
|
avrdude_message(MSG_INFO, "%s: read from file '%s' failed\n",
|
||||||
progname, upd->filename);
|
progname, upd->filename);
|
||||||
|
|
Loading…
Reference in New Issue