-
Notifications
You must be signed in to change notification settings - Fork 137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Developer options to describe parts and extend avrdude.conf syntax #1040
Conversation
…on -p \* -p \*/c check address bits in SPI commands -p \*/d description of core part features -p \*/o opcodes for SPI programming parts and memories -p \*/s show avrdude.conf entries of parts -p \*/ss show full avrdude.conf entry as tab separated table -p \*/w wd_... constants for ISP parts -p \*/\* all of the above except -p \*/s -p \* same as -p\*/\*
When an SPI command has a lone 'a' the initialisation now is as would be expected by all commands that take an address. Atmel's opcodes for SPI programming are consistent in this respect. This commit makes specifying the bit number in avrdude.conf optional. Instead of read_lo = "0 0 1 0 0 0 0 0 0 0 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; one can now use read_lo = "0 0 1 0 0 0 0 0 0 0 a a a a a a a a a a a a a a o o o o o o o o";
This commit changes the philosophy whenever avrdude.conf encounters the same memory of a part for the second time or whenever a memory is described that, through inheritance, already existed: AVRDUDE no longer zaps the memory, it rather extends it. Therefore, avrdude.conf.in's entry for ATmega128RFA1, which inherits from the ATmega2561, needs a line `load_ext_addr = NULL;` in its flash memory description to zap the inherited load_ext_addr SPI command. Other than this, avrdude.conf.in needs no other change in order to effect the same internal representation proving earlier updates to the .conf.in file correct that manually ensured inheritance of memory contents.
As the address bit numbers in the SPI opcodes are highly systematic, they don't really need to be specified. Each bit can therefore be described as one of the characters 0 (always 0), 1 (always 1), x (don't care, but will be set as 0), a (a copy of the correct bit of the byte or word address of read, write, load, pagewrite or load extended address command of memories with more than one byte), i (input bit for a load/write) or o (output bit from a read). The bits therefore do not need to be individually separated. If a string in the list of strings that describe an SPI opcode does *not* contain a space *and* is longer than 7 characters, it is interpreted as a compact bit-pattern representation. The characters 0, 1, x, a, i and o will be recognised as the corresponding bit, whilst any of the characters ., -, _ or / can act as arbitrary visual separators, which are ignored. Examples: loadpage_lo = "0100.0000--000x.xxxx--xxaa.aaaa--iiii.iiii"; loadpage_lo = "0100.0000", "000x.xxxx", "xxaa.aaaa", "iiii.iiii"; loadpage_lo = "0100.0000", "000x.xxxx.xxaa.aaaa", "iiii.iiii"; loadpage_lo = "0100.0000-000x.xxxx--xxaa.aaaa-iiii.iiii"; loadpage_lo = "0100.0000/000x.xxxx/xxaa.aaaa/iiii.iiii"; The compact format is an extension of the current format, which remains valid. Both, the compact and the traditional specification can be mixed in different strings, albeit not in the same string: load_ext_addr = "0100.1101", "0000.0000.0000", "0 0 0 a16", "0000.0000";
…ndaries The function avr_set_addr_mem(AVRMEM *mem, int opnum, unsigned char *cmd, unsigned long addr) is meant to replace avr_set_addr(OPCODE *op, unsigned char *cmd, unsigned long addr) in future. avr_set_addr_mem() has more information about the context of the task in that it knows the memory size, memory page size, whether or not the memory is a flash memory (which gets words addressees supplied) and, crucially, knows which SPI operation it is meant to compute the address bits for. avr_set_addr_mem() first computes the interval of bit numbers that must be supplied for the SPI command to stand a chance to work. The function only sets those address bits that are needed. Once all avr_set_addr() function calls have been replaced by avr_set_addr_mem(), the SPI commands that need an address can afford to declare in avrdude.conf all 16 address bits in the middle two bytes of the SPI command. This over-declaration will be corrected during runtime by avr_set_addr_mem(). One consequence of this is that parts can inherit smaller or larger memories from parents without the need to use different SPI codes in avrdude.conf. Another consequence is that avr_set_addr_mem() can, and does, tell the caller whether vital address bits were not declared in the SPI opcode. During parsing of avrdude.conf this might be utilised to generate a corresponding warning. This will uncover problematic SPI codes in avrdude.conf that in the past went undetected.
There must be a way of quoting for that shell... Try compiling the following
... and see how you can execute it, so you get the argument |
Finally got this working. I need to use
|
@mcuee Yes, you need to somehow protect the wildcards for the part name to be evaluated by the shell that you use. Maybe leaving out the space does the trick in some of the shells: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except for the question library vs. main CLI only, the changes are fine with me.
src/CMakeLists.txt
Outdated
@@ -133,6 +133,9 @@ add_library(libavrdude | |||
confwin.c | |||
crc16.c | |||
crc16.h | |||
developer_opts.c |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder whether we want the developer opts files be part of the library or not.
If they are not going to be part of the library but only the standard CLI tool (my preference), they need to go into a different section in CMakeLists.txt and Makefile.am.
If they are going to be part of the library, public function declarations ought to be in libavrdude.h rather than in a separate header file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is good for the developer opts files to be part of the library.
Thanks. Indeed the trick works (both for MSYS2 shell and PowerShell under Windows Terminal).
|
Great shout: I hadn't thought of that. Generally this is CLI stuff, but some of the functions I have initially written for this section later turned out to be useful for parsing in config_gram.y, so could move to libavrdude. Some, eg, My proposal is to move the following functions to
I am at sixes and sevens over the following one
and am tempted to leave that one in @dl8dtl OK? |
@mcuee, @dl8dtl Following your reviews (thanks!) I have now
I also added a parent_id to parts (and programmers), so that -p*/s now can give a truly compact version of the current
This is the true significance of these developer options -p*/? for parts. I now consider this PR ready to be merged. What d'ya say? |
There is one thing, though: As the output of |
@stefanrueger and @dl8dtl The new avrdude.conf from this pull request is not backwards compatible. Shall we bump the version to 8.0 (and not 7.1 as planned)?
Or shall we merge the pull request without the change to avrdude.conf and leave that a bit later? In that case, we can still release 7.1 version first. The avrdude executable generated from this pull request is still backwards compatible with prior avrdude.conf file.
|
I'd vote for the latter. Keep avrdude.conf compatible with 7.0 and later bump the version number to 7.1 |
Just to help a bit here. Here are the original and formatted avrdude.conf (from git and from this pull request). It seems to be fine to me. One minor thing is that I like to have one empty line between two parts. |
@stefanrueger |
This is an extension to The only incompatibility here is that this PR makes AVRDUDE extend memories rather than zap them. Zapping memories has been considered an error, so the single one incompatibility is desired. Other than that the changes to the grammar are backward compatible. You can always use an old |
For formatting look at the output of
|
Correct. For testing, I edited |
No issue with the incompatibility. I am just saying it is better to up-rev avrdude to 8.0 in that case for next release as I consider it to be a major upgrade in that case. If it is named 7.1 then I kind of expect that the conf file for 7.1 version would be compatible with 7.0 version. But maybe that is a wrong expectation (as I can see 5.xx version exist for many years). |
Sorry, I thought "old" Avrdude 6.3 and 7.0 conf files would work with this PR. A new Avrdude version should support older conf files, but older Avrdude versions would obviously not support support new features added to Avrdude.conf. @dl8dtl would be the one to decide a version number for the next release, but I have no issues with this PR being merged 👍 |
And this PR does! Old .conf files work. The syntax is backwards compatible, as is the associated semantics albeit with a single exception: Opening a memory in a part now inherits/extends the properties rather than zap its contents. The previous behaviour was not well documented and less well known amongst users, which has led to a few errors as both users and maintainers seem to have expected inheritance. This PR brings expectation, documentation and reality in line. I wouldn't worry about version numbering at this point owing to that technicality. My recommendation is to merge the PR, so the new behaviour is available asap. The main goal of this PR is to provide memory inheritance and the tools (developer option -p */? ) to then restructure |
I agree to merge the pull request. Sorry for the versioning noise. I think what you have stated is correct. |
@stefanrueger I just realised that it has problems with the AVR-Dx/Ex series. Several memories are printed twice:
|
This (untested) PR
loadpage_lo = "0100.0000--000x.xxxx--xxaa.aaaa--iiii.iiii";
The syntax for the part description option is
avrdude -p <wildcard>/<flags>
The function
avr_set_addr_mem(AVRMEM *mem, int opnum, unsigned char *cmd, unsigned long addr)
is meant to replaceavr_set_addr(OPCODE *op, unsigned char *cmd, unsigned long addr)
in future. avr_set_addr_mem() has more information about the context of the task in that it knows the memory size, memory page size, whether or not the memory is a flash memory (which gets words addressees supplied) and, crucially, knows which SPI operation it is meant to compute the address bits for. avr_set_addr_mem() first computes the interval of bit numbers that must be supplied for the SPI command to stand a chance to work. The function only sets those address bits that are needed. Once all avr_set_addr() function calls have been replaced by avr_set_addr_mem(), the SPI commands that need an address can afford to declare inavrdude.conf
all 16 address bits in the middle two bytes of the SPI command. This over-declaration will be corrected during runtime by avr_set_addr_mem(). One consequence of this is that parts can inherit smaller or larger memories from parents without the need to use different SPI codes in avrdude.conf. Another consequence is that avr_set_addr_mem() can, and does, tell the caller whether vital address bits were not declared in the SPI opcode. During parsing of avrdude.conf this might be utilised to generate a corresponding warning. This will uncover problematic SPI codes in avrdude.conf that in the past went undetected.I still have to get the hang of a workflow with git rebase. Apologies for the non-linear history :(
@dl8dtl, could I ask for your review? This work relates to the Extend rather than reset memory entries in avrdude.conf that might be useful, and for hardening
avrdude.conf
entries against mistakes.For testing, I would suggest to run a few
avrdude -p ATmega328P/...
commands.Here one fun application: How much time does it roughly take for a bootloader on the ATtiny85 to emulate chip erase? Answer
This assumes
flash->num_pages * part->chip_erase_delay
is a reasonable estimate considering SPM page erase might take roughly ads long, but no longer than an SPI programming chip erase.Well, it won't be long that the world thinks What does Microchip know about their parts, when I can ask AVRDUDE about a part? :)