Closed detamend closed 1 year ago
This is a bug in 2.6.1 it has already been corrected for 2.6.2
Modern AVRs have three sections of flash: Bootloader: Code running in the bootloader section can write to flash anywhere on the flash except the bootloader and can write EEPROM and USERROW. Execution always starts at 0x0000 which is in the bootloader section. Upon leaving the bootloader section, if the BOOTRP bit was set (it can only be written from within the bootloader section), all reads from the bootloader section until the next reset will read 0x0000 (no-op), with the main consequence being that user code controlled by another party can't steal some proprietary bootloader (a big concern for many Microchip customers, our bootloader is open source so we DGAF about that). It also prevents leaving an entry point through which the application can rewrite itself (this is provided by both megaTinyCore and DxCore's bootloader - the one in megaTinyCore is relatively sophisticated, because the tinyAVR's check what section code is running from both when the page buffer is written and when the NVMCTRL.CTRLA register is written to fire the command that writes data (so even without BOOTRP, it would be quite challenging for an evil application to try to call the bootloader to modify itself). It's much more important on the Dx-series that only protects the SPM, or ST targeting the high half of the address space) against being run from the wrong section - without BOOTRP, someone could examine the bootloader from the application to locate the SPM or SPM Z+ instruction, then examine the following code to find a path to a "ret" (return) as soon as possible. Then they could write anywhere outside of the bootloader section, despite being in the application section. Since this is an open source platform and we specifically support this, that's all well and good, but the folks who are using this for "life safety critical applications" (the microchip development tools, used in combination with most modern AVRs, and in likely in accordance with some long list of rules that must be observed, are certified for use in life safety critical applications". You know, things like the antilock breaks in your car, or the fuel pump controllers on a jet airliner, the SCRAM system of a nuclear powerplant that it uses to shut down in the event of an emergency. Those obviously demand such protection features. Anyway, back to the sections. Application Code: Code running in the application section can write to flash located only within the Application Data section, and can write EEPROM and USERROW. It can read from anywhere (except, if BOOTRP is set, the bootloader section). It can still jump into the bootloader section in that case, but all it will read is NOOP instructions, until it gets to the end of the bootloader section, continuing to the start of the application code section - that's where the reset vector of the application is located) Application Data: If code is run from the application data section at all, it is minimally privileged - it can still read from the application section and jump back to it, but it can't write to the NVM, not flash, not eeprom, and not userrow.
The sizes of these can be configured by the fuses in units of 256 (tinyavr) or 512 (Dx) bytes. megaTinyCore uses only two configurations:
DxCore uses four configurations:
That's all well and good. Except that we follow the naming conventions that the datasheets use for the fuses that control the size of those sections aren't the same everywhere The tinies use BOOTEND, and APPEND (as in Application End) to potentially split the flash into the three sections. For obvious reasons, APPEND is a very bad name for that, since not only is "Append" a word, it's a word very commonly used in programming and rarely outside of it. Microchip quickly realized this (but not after it had released parts and thankfully they didn't try to change what it was called with find/replace in their docs and headers) The Dx-series uses BOOTSIZE (the size of the bootloader) and CODESIZE (the size of the bootloader and the application section, ie, exactly the same thing as APPEND).
Due to a bungled attempt to harmonize file formating between DxCore and megaTinyCore, the body of DxCore's platform.txt wound up in megaTinyCore's platform.txt during development. When found that and fixed it, I missed the bootloader recipe for DxCore.
So burn bootloader fails because wants to substitute in bootloader.CODESIZE and bootloader.BOOTSIZE. Those don't exist, so {bootloader.CODESIZE} is instead treated as literal text, and understandably the upload tool balks when told to set a fuse that can contain a numeric value from 0 to 255 to a string.
Hi Spence, thanks a bunch for the great explanation (my head is still spinning from all those under-the-hood information).
I indeed traced the error down to platform.txt (just by dumb searching for CODESIZE) and saw the differences between 2.5.11 and 2.6.1.
Any workaround I can do on my end?
change BOOTSIZE and CODESIZE to BOOTEND and APPEND.
Ohwait, no, other way around.
The damned fools at microchip have APPEND as fuse 7 and BOOTEND as fuse 8, but BOOTSIZE is 7 and CODESIZE is 8 on Dx: they swapped them. This is like a lot of the changes that have happened between tinyAVR and non-tinyAVR - changes to a slightly more sensible behavior but in the process muddies the water.
Thanks! I played a bit around with replacing stuff in platform.txt but had no luck with my experiments. Nevermind - I'll wait for 2.6.2.
Chip: ATTINY3226 IDE: Arduino 1.19 Lib Version: 2.6.1 (current)
Since Mouser had some of those '3226 available, I grabbed some of those fine chips.
First played around with them on V2.5.11 - worked fine, burning the bootloader worked like a charm.
Updated to 2.6.1 - trying to burn the bootloader fails with:
Error: cannot parse fuse, 'invalid literal for int() with base 0: '{booltloader.CODESIZE}'' Error while burning bootloader.
I didn't set anything fancy - just turned the clock down to 10MHz. Trying different UPDI programmers/speeds didn't change the error.
Flashing the chip with a program works fine - just the bootloader won't work for me.
And yeah: tried a fresh downloaded IDE, grabbed a fresh version of the lib - no luck there.
Update: just tried different chips - I can't flash any bootloader under 2.6.1 (again: 2.5.11 worked fine). I'm expecting there's a problem on my side...
Any help would be greatly appreciated - Spence, love your work!!