mirror of
https://github.com/mariusgreuel/avrdude.git
synced 2025-09-28 15:05:27 +00:00
Provide cached byte-wise read/write API (#1106)
* Provide cached byte-wise read/write API int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char *value); int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data); int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p); int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p); int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p); avr_read_byte_cached() and avr_write_byte_cached() use a cache if paged routines are available and if the device memory is EEPROM or flash, otherwise they fall back to pgm->read_byte() and pgm->write_byte(), respectively. Byte-wise cached read always gets its data from the cache, possibly after reading a page from the device memory. Byte-wise cached write with an address in memory range only ever modifies the cache. Any modifications are written to the device after calling avr_flush_cache() or when attempting to read or write from a location outside the address range of the device memory. avr_flush_cache() synchronises pending writes to EEPROM and flash with the device. With some programmer and part combinations, flash (and sometimes EEPROM, too) looks like a NOR memory, ie, one can only write 0 bits, not 1 bits. When this is detected, either page erase is deployed (eg, with parts that have PDI/UPDI interfaces), or if that is not available, both EEPROM and flash caches are fully read in, a pgm->chip_erase() command is issued and both EEPROM and flash are written back to the device. Hence, it can take minutes to ensure that a single previously cleared bit is set and, therefore, this routine should be called sparingly. avr_chip_erase_cached() erases the chip and discards pending writes() to flash or EEPROM. It presets the flash cache to all 0xff alleviating the need to read from the device flash. However, if the programmer serves bootloaders (pgm->prog_modes & PM_SPM) then the flash cache is reset instead, necessitating flash memory be fetched from the device on first read; the reason for this is that bootloaders emulate chip erase and they won't overwrite themselves (some bootloaders, eg, optiboot ignore chip erase commands altogether) making it truly unknowable what the flash contents on device is after a chip erase. For EEPROM avr_chip_erase_cached() concludes that it has been deleted if a previously cached EEPROM page that contained cleared bits now no longer has these clear bits on the device. Only with this evidence is the EEPROM cache preset to all 0xff otherwise the cache discards all pending writes to EEPROM and is left unchanged otherwise. Finally, avr_reset_cache() resets the cache without synchronising pending writes() to the device.
This commit is contained in:
@@ -1333,91 +1333,139 @@ The following commands are implemented:
|
||||
|
||||
@table @code
|
||||
|
||||
@item dump @var{memtype} [@var{start_addr} [@var{nbytes}]]
|
||||
@item dump @var{memtype} @var{addr} @var{nbytes}
|
||||
Read @var{nbytes} from the specified memory area, and display them in
|
||||
the usual hexadecimal and ASCII form.
|
||||
|
||||
@item dump @var{memtype} [@var{start_addr}] @dots{}
|
||||
Start reading from @var{start_addr}, all the way to the last memory address.
|
||||
@item dump @var{memtype} @var{addr} @dots{}
|
||||
Start reading from @var{addr}, all the way to the last memory address.
|
||||
|
||||
@item dump @var{memtype} @var{addr}
|
||||
Read 256 bytes from the specified memory area, and display them.
|
||||
|
||||
@item dump @var{memtype} @dots{}
|
||||
Read all bytes from the specified memory, and display them.
|
||||
|
||||
@item dump @var{memtype}
|
||||
Continue dumping the memory contents for another @var{nbytes} where the
|
||||
previous dump command left off.
|
||||
|
||||
@item write @var{memtype} @var{start_addr} @var{data1} @var{data2} @dots{} @var{dataN}
|
||||
Manually program the respective memory cells, starting at address @var{start_addr},
|
||||
using the values @var{data1} through @var{dataN}. This feature is not
|
||||
implemented for bank-addressed memories such as the flash memory of
|
||||
ATMega devices.
|
||||
@item write @var{memtype} @var{addr} @var{data[,]} @{@var{data[,]}@}
|
||||
Manually program the respective memory cells, starting at address
|
||||
@var{addr}, using the data items provided. The terminal implements
|
||||
reading from and writing to flash and EEPROM type memories normally
|
||||
through a cache and paged access functions. All other memories are
|
||||
directly written to without use of a cache. Some older parts without paged
|
||||
access will also have flash and EEPROM directly accessed without cache.
|
||||
|
||||
Items @var{dataN} can have the following formats:
|
||||
Items @var{data} can have the following formats:
|
||||
|
||||
@multitable @columnfractions .3 .4 .3
|
||||
@item @strong{Type}
|
||||
@tab @strong{Example}
|
||||
@tab @strong{Size (bytes)}
|
||||
|
||||
@item String
|
||||
@tab @code{"Hello, world\n"}
|
||||
@tab varying
|
||||
|
||||
@item Character
|
||||
@tab @code{'A'}
|
||||
@tab 1
|
||||
|
||||
@item Decimal integer
|
||||
@tab 12345
|
||||
@tab 1, 2, 4, or 8 (see below)
|
||||
@tab 1, 2, 4, or 8
|
||||
|
||||
@item Octal integer
|
||||
@tab 012345
|
||||
@tab 1, 2, 4, or 8 (see below)
|
||||
@tab 1, 2, 4, or 8
|
||||
|
||||
@item Hexadecimal integer
|
||||
@tab 0x12345
|
||||
@tab 1, 2, 4, or 8 (see below)
|
||||
@tab 1, 2, 4, or 8
|
||||
|
||||
@item Float
|
||||
@tab 3.1415926
|
||||
@tab 4
|
||||
|
||||
@item Double
|
||||
@tab 3.141592653589793D
|
||||
@tab 8
|
||||
|
||||
@end multitable
|
||||
|
||||
Integer constants can be 1, 2, 4, or 8 bytes long.
|
||||
By default, the smallest possible size will be used where
|
||||
the specified number just fits into.
|
||||
A specific size can be denoted by appending one of these suffixes:
|
||||
|
||||
@var{data}
|
||||
can be hexadecimal, octal or decimal integers, floating point numbers
|
||||
or C-style strings and characters. For integers, an optional case-insensitive
|
||||
suffix specifies the data size as in the table below:
|
||||
@table @code
|
||||
@item LL
|
||||
@itemx ll
|
||||
8 bytes / 64 bits
|
||||
@item L
|
||||
@itemx l
|
||||
4 bytes / 32 bits
|
||||
@item H
|
||||
@itemx h
|
||||
@itemx S
|
||||
@itemx s
|
||||
@item H or S
|
||||
2 bytes / 16 bits
|
||||
@item HH
|
||||
@itemx hh
|
||||
1 byte / 8 bits
|
||||
@end table
|
||||
|
||||
Similarly, floating-point constants can have an @code{F} or @code{f}
|
||||
appended, but only 32-bit floating-point values are supported.
|
||||
Suffix @code{D} indicates a 64-bit double, @code{F} a 32-bit float, whilst a
|
||||
floating point number without suffix defaults to 32-bit float. Hexadecimal
|
||||
floating point notation is supported. An ambiguous trailing suffix, eg,
|
||||
@code{0x1.8D}, is read as no-suffix float where @code{D} is part of the
|
||||
mantissa; use a zero exponent @code{0x1.8p0D} to clarify.
|
||||
|
||||
@item write @var{memtype} @var{start_addr} @var{length} @var{data1} @var{data2} @var{dataN} @dots{}
|
||||
An optional @code{U} suffix makes integers unsigned. Ordinary @code{0x} hex
|
||||
integers are always treated as unsigned. @code{+0x} or @code{-0x} hex
|
||||
numbers are treated as signed unless they have a @code{U} suffix. Unsigned
|
||||
integers cannot be larger than 2^64-1. If @var{n} is an unsigned integer then @var{-n}
|
||||
is also a valid unsigned integer as in C. Signed integers must fall into
|
||||
the [-2^63, 2^63-1] range or a correspondingly smaller range when a suffix
|
||||
specifies a smaller type. Out of range signed numbers trigger a warning.
|
||||
|
||||
Similar to the above, but @var{length} byte of the memory are written.
|
||||
For that purpose, after writing the initial items, @var{dataN} is
|
||||
replicated as many times as needed.
|
||||
Ordinary @code{0x} hex integers with @var{n} hex digits (counting leading
|
||||
zeros) use the smallest size of 1, 2, 4 and 8 bytes that can accommodate
|
||||
any n-digit hex integer. If an integer suffix specifies a size explicitly
|
||||
the corresponding number of least significant bytes are written.
|
||||
Otherwise, signed and unsigned integers alike occupy the smallest of 1, 2,
|
||||
4, or 8 bytes needed to accommodate them in their respective
|
||||
representation.
|
||||
|
||||
One trailing comma at the end of data items is ignored to facilitate copy
|
||||
and paste of lists.
|
||||
|
||||
@item write @var{memtype} @var{addr} @var{length} @var{data[,]} @{@var{data[,]}@} @dots{}
|
||||
The ellipses form @dots{} of write is similar to above, but @var{length}
|
||||
byte of the memory are written. For that purpose, after writing the
|
||||
initial items, the last @var{data} item is replicated as many times as
|
||||
needed.
|
||||
|
||||
@item flush
|
||||
Synchronise with the device all pending cached writes to EEPROM or flash.
|
||||
With some programmer and part combinations, flash (and sometimes EEPROM,
|
||||
too) looks like a NOR memory, ie, one can only write 0 bits, not 1 bits.
|
||||
When this is detected, either page erase is deployed (eg, with parts that
|
||||
have PDI/UPDI interfaces), or if that is not available, both EEPROM and
|
||||
flash caches are fully read in, a chip erase command is issued and both
|
||||
EEPROM and flash are written back to the device. Hence, it can take
|
||||
minutes to ensure that a single previously cleared bit is set and,
|
||||
therefore, this command should be used sparingly.
|
||||
|
||||
@item abort
|
||||
Normally, caches are only ever actually written to the device when using
|
||||
@code{flush}, at the end of the terminal session after typing @code{quit},
|
||||
or after EOF on input is encountered. The @code{abort} command resets the
|
||||
cache discarding all previous writes to the flash and EEPROM cache.
|
||||
|
||||
@item erase
|
||||
Perform a chip erase.
|
||||
Perform a chip erase and discard all pending writes to EEPROM and flash.
|
||||
|
||||
@item send @var{b1} @var{b2} @var{b3} @var{b4}
|
||||
Send raw instruction codes to the AVR device. If you need access to a
|
||||
Send raw instruction codes to the AVR device. If you need access to a
|
||||
feature of an AVR part that is not directly supported by AVRDUDE, this
|
||||
command allows you to use it, even though AVRDUDE does not implement the
|
||||
command. When using direct SPI mode, up to 3 bytes
|
||||
command. When using direct SPI mode, up to 3 bytes
|
||||
can be omitted.
|
||||
|
||||
@item sig
|
||||
|
Reference in New Issue
Block a user