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;
The check for typos in -U memory names against a list of known memory names
now happens after the config files have been read, so newly declared memory
names can be considered. This commit also weakens the check against existence
of a known memory: it is now sufficent for a name to pass when it could be
the initial string of any known memory of any part. Any -U memory that cannot
possibly be matched up with a known memory is considered a typo and leads to
an exit before the programmer is opened.
This to protect users from typos that leave a device partially programmed.
When every -U memory name might be matching one of the known memories, the
programming is attempted. If the part to be programmed turns out not to have
a particular -U memory, AVRDUDE warns the user and skips this -U update.
This to support unifying interfaces that call AVRDUDE with potentially more
memories than the actual part has (eg, efuse on ATmega8).
Counting the number of bytes written to a memory and/or verified is not
trivial owing to potential holes in the input file and to potential trailing
0xff bytes in flash memory that are not written per default (but see -A). The
new function memstats(), which is best called just after an input file has
been read into mem->buf/mem->tags, computes the right number of bytes written
and allows easy computation of the number of bytes verified.
This commit also changes the strategy for the default verification after
writing to a chip memory, so that the input file only needs reading once thus
enabling successful verification of stdin input files.
Other, minor changes:
- Improving the grammar of AVRDUDE output, eg, 1 byte written instead of
1 bytes written
- Better description of the input file structure in terms of its sections,
the interval it spans, the number of pages, the number of padding bytes
in pages, and the number of actually cut off trailing 0xff bytes for flash
- Printing <stdin> or <stdout> instead of - in the -U routines
- Option -V no longer needs to be specified before option -U in order to work
As an aside this commit also provides useful helper functions for printing
plural(), inname(), outname() and interval() all of which return strings fit
for printing.
$ avrdude -qp ATmega2560 -c usbtiny -U blink-mega2560+lext-test.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e9801 (probably m2560)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: input file blink-mega2560+lext-test.hex auto detected as Intel Hex
avrdude: reading input file blink-mega2560+lext-test.hex for flash
with 1346 bytes in 4 sections within [0, 0x3106d]
using 7 pages and 446 pad bytes
avrdude: writing 1346 bytes flash ...
avrdude: 1346 bytes of flash written
avrdude: verifying flash memory against blink-mega2560+lext-test.hex
avrdude: 1346 bytes of flash verified
avrdude done. Thank you.
$ avrdude -qp ATmega328P -c usb-bub-ii -U sketch-ending-in-ff.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: input file sketch-ending-in-ff.hex auto detected as Intel Hex
avrdude: reading input file sketch-ending-in-ff.hex for flash
with 2160 bytes in 1 section within [0, 0x888]
using 17 pages and 16 pad bytes, cutting off 25 trailing 0xff bytes
avrdude: writing 2160 bytes flash ...
avrdude: 2160 bytes of flash written
avrdude: verifying flash memory against sketch-ending-in-ff.hex
avrdude: 2185 bytes of flash verified
avrdude done. Thank you.
$ echo "Hello, world..." | avrdude -qp ATmega328P -c ... -U eeprom:w:-:r
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file <stdin> for eeprom
avrdude: writing 16 bytes eeprom ...
avrdude: 16 bytes of eeprom written
avrdude: verifying eeprom memory against <stdin>
avrdude: 16 bytes of eeprom verified
avrdude done. Thank you.
Some 90% of the space of AVRPART and some 50% of PROGRAMMER is occupied by a
4 kB array config_file[] that contains the configuration file name. In
preparation of developer options that output a raw dump of the part
descriptions, this commit changes the config_file components from a large
array, which is duplicated in each part and programmer description, to a
cached string for each config file allowing for smaller raw dumps.
This commit also changes the config file name to its realpath(), eg, shortens
unwarranted `/bin/../etc/` file name components. It also changes the global
variable names `infile` and `fileno` to cfg_infile and cfg_fileno for an ever
so slight improvement of code clarity.
The new file type I is essentially Intel HEX that, on download, inserts
comments next to data records with the resolved effective address and an
ASCII dump of that same record. On upload the `I` format is permissive
with respect to check sum errors, eg, after manipulated an Intel HEX file
for debugging.
In certain situations (CRC failure, device locked), that JTAG3
read functions need to return an indication to the caller that
it is OK to proceed, and allow erasing the device anyway.
Historically, the JTAG3 code passed the respective protocol
errors directly (and unexplained) up to the caller, leaving
the decision to the caller how to handle the situation.
Replace that by a more common return value API. New code should
prefer this API instead of any hardcoded return values.
Implementation for an "alias" keyword.
By now, only applied inside memory descriptions.
* Make "mem_alias" a separate nonterminal.
The previous implementation attempt caused a syntax error in
yacc code, and separating mem_alias on the same level as
mem_spec appears to be the cleaner solution anyway.
* Maintain real memory aliases.
Instead of duplicating the aliased memory with a new name, maintain a
second list of memory aliases (per device) that contains a pointer to
the memory area it is aliased to. That way, a memory name can be
clearly distinguished between the canonical one and any aliases.
* Check p->mem_alias != NULL before touching it
* Add avr_find_memalias()
This takes a memory region as input, and searches whether an
alias can be found for it.
* We need to add a list structure for the mem_alias list, always.
By that means, mem_alias won't ever be NULL, so no need to check
later.
Also, in avr_dup_part(), duplicate the alias list.
* In a memory alias, actually remember the current name.
* In avr_dup_part(), adjust pointers of aliased memories
While walking the list of memories, for each entry, see if there is an
alias pointing to it. If so, allocate a duplicated one, and fix its
aliased_mem pointer to point to the duplicated memory region instead
of the original one.
* Add avr_locate_mem_noalias()
When looking whether any memory region has already been defined for
the current part while parsing the config file, only non-aliased names
must be considered. Otherwise, a newly defined alias would kick out
the memory definition it is being aliased to.
* When defining a mem_alias, drop any existing one of that name.
* Actually use avr_find_memalias() to find aliases
* Add declaration for avr_find_memalias()
* When defining a memory, also search for an existing alias
If the newly defined name has the same as an existing alias, the alias
can be removed.
Note that we do explicitly *not* remove any memory by the same name of
a later defined alias, as this might invalidate another alias'es
pointer. If someone defines that, the alias name just won't ever be
found by avr_locate_mem().
This feature has been designed with the sometimes quite flakey direct
(parallel or serial port attached) bitbang programming adapters in
mind that were quite common about two decades ago.
With parallel ports vanishing from modern PCs almost completely, and
the advent of various USB-attached low-cost programming devices,
this class of programmers disappeared almost completely.
Furthermore, the fuse combinations that were covered by the feature
are no longer around on all recent AVR devices, so for an ever
increasing number of devices, safemode already became meaningless and
was turned off anyway.
With the prospective version 7.x release, it's a good point in time to
introduce a major change like this one.