Closed tglaria closed 8 months ago
Same fuses.
This will be the problem. If it's the first bootloader from this page (see screenshot below) with 256 bytes then the fuses need to be different: the MCU does not have provisions for hardware support of such a small bootloader, so fuses need to be set for the vector bootloading technique. The usage section of the urboot readme has details. LMK how you get on.
Out of curiosity: I do not recognise the reported warning WARNING: Unable to detect MCU
, which avrdude version do you use? avrdude.exe -v
BTW, the urboot bootloader tells AVRDUDE's -c urclock
that it has been compiled for the ATmega128RFA1, so no need to specify -p
and no need to pretend a different MCU (m8
).
Hi, thanks for answering so quickly.
About the fuses, I tried different possibles fuse configurations with no success (different bootloader size nad "boot restet fuse" enabled and disabled). I also tried another bootloader, the fifth one (512 bytes of usage) and still no connection. I'll recheck and try again.
About the avrdude version, I'm using AVRDUDESS GUI v2.15 which says it's using avrdude v7.2. There's a 'detect' button which tries to identify which microcontroller it's being used (it just sends a command through avrdude as far as I can tell).
I guess I'll just skip the GUI for now.
I'll just skip the GUI for now
Good move :smile:
There's a 'detect' button which tries to identify which microcontroller it's being used
I wondered where you got the Optiboot bootloader for the Atmega128RFA1 from. Looks like the (working) optiboot was compiled for the ATmega8. Can you look at the board to see which MCU is on? Is it a board with two MCUs? One for providing the comms and another one? If so which MCU will the bootloader (optiboot/urboot) be burned on?
I guess the AVRDUDESS technique will be to enquire the signature, which fortunately is unique for the ATmega128RFA1 and almost unique the ATmega8:
$ avrdude -p*/At | grep ATmega128RFA1.signature.0x
.pt ATmega128RFA1 signature 0x1e 0xa7 0x01
$ avrdude -p*/At | grep 0x1e.0xa7.0x01
.pt ATmega128RFA1 signature 0x1e 0xa7 0x01
$ avrdude -p*/At | grep ATmega8.signature.0x
.pt ATmega8 signature 0x1e 0x93 0x07
$ avrdude -p*/At | grep 0x1e.0x93.0x07
.pt ATmega8 signature 0x1e 0x93 0x07
.pt ATmega8A signature 0x1e 0x93 0x07
Optiboot does not ask the MCU what the real signature is, it just replies with the signature it was compiled for. Looks like the (working) optiboot was compiled for the ATmega8. So, if that works, why not try an urboot bootloader for the ATmega8?
I wondered where you got the Optiboot bootloader for the Atmega128RFA1 from. Looks like the (working) optiboot was compiled for the ATmega8.
I compiled some time ago. (I believe I compiled it for ATmega1281 since the ATmega128RFA is derived from it (according to the datasheet, section 3.4))
Can you look at the board to see which MCU is on? Is it a board with two MCUs? One for providing the comms and another one? If so which MCU will the bootloader (optiboot/urboot) be burned on?
It's a custom board with a single ATega128RFA1 microcontroller. Logically, it's installed on that one.
I guess the AVRDUDESS technique will be to enquire the signature, which fortunately is unique for the ATmega128RFA1 and almost unique the ATmega8:
$ avrdude -p*/At | grep ATmega128RFA1.signature.0x .pt ATmega128RFA1 signature 0x1e 0xa7 0x01 $ avrdude -p*/At | grep 0x1e.0xa7.0x01 .pt ATmega128RFA1 signature 0x1e 0xa7 0x01 $ avrdude -p*/At | grep ATmega8.signature.0x .pt ATmega8 signature 0x1e 0x93 0x07 $ avrdude -p*/At | grep 0x1e.0x93.0x07 .pt ATmega8 signature 0x1e 0x93 0x07 .pt ATmega8A signature 0x1e 0x93 0x07
Optiboot does not ask the MCU what the real signature is, it just replies with the signature it was compiled for. Looks like the (working) optiboot was compiled for the ATmega8. So, if that works, why not try an urboot bootloader for the ATmega8?
For the times I've used it, it did inform the correct signature (0x1E A7 01), I'll have to recheck how did I compiled the bootloader.
(can't make any further tests now, I'm on a linux computer and it doesn't work with non-standard baudrates ... )
I also tried another bootloader, the fifth one (512 bytes of usage) and still no connection.
You could try the sixth or seventh bootloader (1024 bytes, h
in the features for hardware-supported bootloader) and set the fuse for bootloader size to 512 words and jump to bootloader on reset. The fuse setting here should be the same as for optiboot. If it's a shorter bootloader with j
in the features, you need to change the fuses as described in earlier posts.
You can use -T config
to show the fuse configuration like so
$ avrdude -qq -c dryrun -p m128rfa1 -T config
config sut_cksel=intrcosc_6ck_65ms # 34
config ckout=co_disabled # 1
config ckdiv8=by_8 # 0
config bootrst=application # 1
config bootsz=bs_4096w # 0
config eesave=ee_erased # 1
config wdton=wdt_programmable # 1
config spien=isp_enabled # 0
config jtagen=jtag_enabled # 0
config ocden=ocd_disabled # 1
config bodlevel=bod_disabled # 7
config lb=no_lock # 3
config blb0=no_lock_in_app # 3
config blb1=no_lock_in_boot # 3
You just need to replace dryrun
with the name of the programmer that you use to upload the bootloader sketch onto your custom board. Pay attention to the lock bits lb
, blb0
and blb1
, too. Above example shows factory reset values.
Update 2: OK, yes, it's a hardware problem. The board is not being reset.
I burned the bootloader again, the first one, the smallest one, and works when I manually reset the board. Using fuse for bootloader size of 512 words, and works.
So ... yep, sorry for wasting the time. I'll keep testing it now.
Thanks for the quick answers an sorry for wasting your time.
PD: Optiboot worked the first time, since the flash was erased. Why didn't urboot work? Shouldn't the 'program counter' go all the way until it found the bootloader?
Update: After further testing, it looks like I have a hardware problem. The board I'm testing isn't receiving the reset pulse.
I'll check this before further questions.
Ok, tried again, no luck.
Burnning Bootloader:
Description of board:
Fuses (for easier display):
LOW: 0xE0
HIGH: 0x98 (boot flash size=4046 words) or 0x9E (boot flash size=512 words)
Extended: 0xF6
avrdude command
So this is the command I tried: .\avrdude.exe -c urclock -P COM5 -p m128rfa1 -b 115200 -v
and here's the output
avrdude: Version 7.2
Copyright the AVRDUDE authors;
see https://github.com/avrdudes/avrdude/blob/main/AUTHORS
System wide configuration file is .\avrdude-v7.2-windows-x64\avrdude.conf
Using Port : COM5
Using Programmer : urclock
Overriding Baud Rate : 115200
avrdude urclock_getsync() warning: attempt 1 of 10: not in sync
avrdude urclock_getsync() warning: attempt 2 of 10: not in sync
avrdude urclock_getsync() warning: attempt 3 of 10: not in sync
avrdude urclock_getsync() warning: attempt 4 of 10: not in sync
avrdude urclock_getsync() warning: attempt 5 of 10: not in sync
avrdude urclock_getsync() warning: attempt 6 of 10: not in sync
avrdude urclock_getsync() warning: attempt 7 of 10: not in sync
avrdude urclock_getsync() warning: attempt 8 of 10: not in sync
avrdude urclock_getsync() warning: attempt 9 of 10: not in sync
avrdude urclock_getsync() warning: attempt 10 of 10: not in sync
avrdude urclock_recv() warning: programmer is not responding; try -xstrict and/or vary -xdelay=100
avrdude main() error: unable to open programmer urclock on port COM5
avrdude done. Thank you.
avrdude has its own fuse calculator:
$ avrdude -pATmega128RFA1 -cdryrun -qqT "write lfuse 0xe0; w hf 0x9e; w ef 0xf6; config"
config sut_cksel=extclk_6ck_65ms # 32
config ckout=co_disabled # 1
config ckdiv8=by_1 # 1
config bootrst=boot_section # 0
config bootsz=bs_512w # 3
config eesave=ee_erased # 1
config wdton=wdt_programmable # 1
config spien=isp_enabled # 0
config jtagen=jtag_enabled # 0
config ocden=ocd_disabled # 1
config bodlevel=bod_1v8 # 6
config lb=no_lock # 3
config blb0=no_lock_in_app # 3
config blb1=no_lock_in_boot # 3
This is suitable for a hardware-supported bootloader (note the bootrst=boot section
), eg, the 1024 h
-type urboot (sixth from top). For the smaller urclock bootloader (j
-type) you want the high fuse to be 0x9f
. (jump to application). If neither combo works, then I would look closely at the optiboot bootloader that works and try to use a similar one from the urboot
section.
Haven't managed to use Atmel ICE programmer with avrdude.
Avrdude should work with the Atmel ICE
And yes, not getting the reset pulse would explain the output you see.
For manual reset I recommend the longer WDT timeout of 2 s. First press the reset button of the board and release it; then start avrdude by pressing enter of the previously typed command line within the WDTO time.
And you can show which ports are available by avrdude -curclock -P\?
(just to be sure COM5 is the one).
Here Microchip's reference reset circuit, and here one that I know works (dtr or rts doesn't matter as avrdude plucks both):
It misses the clamping diode, but that diode would prevent HV programming.
@tglaria How are you getting on?
What's Vcc? If > 5.5 V then this could result in a > 11 V peak on certain boards without a RESET clamp diode to Vcc using a pre-v7.3 -c urclock instance; the > 11 V peak might have triggered HV programming causing the observed time-out behaviour. If so, this is a hardware problem, but v7.3 changed -c urclock so that there would be no such drastic peak in boards that miss the clamp diode. So if Vcc > 5.5 V, try avrdude v7.3 that was recently released.
Turns out that some counterfeit parts seem to have a lower HV programming threshold, and that even with Vcc = 4.75 V, using a v7.2 AVRDUDE and counterfeit parts and boards without a missing clamp diode between reset and Vcc the observed behaviour might occur
@tglaria How are you getting on?
What's Vcc? If > 5.5 V then this could result in a > 11 V peak on certain boards without a RESET clamp diode to Vcc using a pre-v7.3 -c urclock instance; the > 11 V peak might have triggered HV programming causing the observed time-out behaviour. If so, this is a hardware problem, but v7.3 changed -c urclock so that there would be no such drastic peak in boards that miss the clamp diode. So if Vcc > 5.5 V, try avrdude v7.3 that was recently released.
Sorry, I was on vacations, no connection to PC. The board is powered from a 3.3V source, so shouldn't be a a high voltage problem.
I'm using the same circuit you showed (Microchip's reference reset circuit), so my theory is a busted cap. (still, hardware problem)
EDIT: So yeah, changed the capacitor and now (apparently) it works. (at least it is detected by avrdude)
> .\avrdude.exe -c urclock -P COM7 -b 125000
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1ea701 (probably m128rfa1)
avrdude done. Thank you.
(I don't remember which bootloader I used, but now I can test different ones)
I don't remember which bootloader I used
Try avrdude -c urclock -P COM7 -b 125000 -xshowall
and it might tell you
I don't remember which bootloader I used
Try
avrdude -c urclock -P COM7 -b 125000 -xshowall
and it might tell you
Sweet!
Did not know about the -x
command/argument.
> .\avrdude.exe -c urclock -P COM7 -b 125000 -xshowversion
avrdude: AVR device initialized and ready to accept instructions
u7.7 weu-hpr-c
(should I / you close this 'issue'?)
On another note (which probable should be on another section):
With optiboot, I was using the last 16 bytes to store an Id.
From what I understood, I saw that part of this section is used for pgm_write_page(sram, progmem)
.
Is it possible to change the location of this function? If not, is it possible to detect, from software, the presence of this bootloader? Lastly, ¿how is that function called from the application? Is there something special since it's on the bootloader?
With optiboot, I was using the last 16 bytes to store an Id.
Well, doesn't optiboot store its version number in the last two bytes of flash?
From what I understood, I saw that part of this section is used for pgm_write_page(sram, progmem).
Urboot v7.7 bootloaders hold a 6-byte table at top of flash, see "implicit communication" in the protocol definition
Is it possible to change the location of this function?
No, applications need to know how to call the function: they call the address 4 bytes from top flash.
how is that function called from the application?
The section about PGMWRITEPAGE
of the make options explains how an application can call this bootloader function.
Is there something special since it's on the bootloader?
On most MCUs only code in the bootloader can self-program flash, so this function must reside in the bootloader. Now, how would an application know where in the bootloader this function sits? Urboot solves this by placing an rjmp
to the function at the fixed, defined address FLASHEND-4+1
.
is it possible to detect, from software, the presence of this bootloader?
Sure, you can look at the last 6 bytes in flash and see whether they conform to a pattern that would be expected for an urboot or optiboot bootoader. This is what the external program hexls
in this repository does with an intel hex file that is a bootloader. You can write code in the MCU application that examines the top bytes in flash in a similar fashion.
I wouldn't compile an ID into the bootloader flash. Though you could, if you placed the ID into a separate section before the section version that contains the 6-byte table.
Seeing that the problem was a blown cap, I close the issue at hand
Ahh, one more thing. Please confirm whether the urboot bootloader actually works on an ATmega128RFA1
so I can move that MCU into the supported and tested list. Would be neat if you tried a vector bootloader (j
in the version capabilities, different fuse setting) and the larger hardware-supported one (h
)
https://github.com/stefanrueger/urboot/blob/d8557f12db257d5b0b32aef64179a1caec122865/src/urboot.c#L32-L76
OK, Testing:
bootloader: urboot_m128rfa1_1s_x16m0_125k0_uart0_rxe0_txe1_no-led.hex
FUSE_BOOTRST: disabled
FUSE_BOOTZ: 512words (it's the minimum size)
.\avrdude.exe -c urclock -p m128rfa1 -P COM7 -b 115200 -xshowall
avrdude: AVR device initialized and ready to accept instructions
0 0000-00-00 00.00 application 0 store 0 meta 1 boot 256 u7.7 w-u-jPr-- vector 40 (SPM_READY) ATmega128RFA1
Flashing:
Sometimes it works, sometimes it doesn't.
I'm getting spammed with messages avrdude error: bootloader does not implement bytewise write to flash
> .\avrdude.exe -c urclock -p m128rfa1 -P COM7 -b 115200 -U flash:w:"test.hex"
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1ea701 (probably m128rfa1)
avrdude: Note: flash memory has been specified, an erase cycle will be performed.
To disable this feature, specify the -D option.
avrdude: erasing chip
delaying chip erase until first -U upload to flash
avrdude: processing -U flash:w:test.hex:i
avrdude: reading input file test.hex for flash
with 15712 bytes in 1 section within [0, 0x3d5f]
using 62 pages and 160 pad bytes
avrdude: preparing flash input for device bootloader
avrdude: writing 15712 bytes flash ...
Writing | #############------------------------------------- | 26% 6.51 s
avrdude error: protocol expects OK byte 0x58 but got 0x61 in urclock_paged_write()
avrdude error: bootloader does not implement bytewise write to flash
***failed;
[...]
avrdude error: bootloader does not implement bytewise write to flash
***failed;
When it works, it works.
> .\avrdude.exe -c urclock -p m128rfa1 -P COM7 -b 115200 -U flash:w:"test.hex"
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1ea701 (probably m128rfa1)
avrdude: Note: flash memory has been specified, an erase cycle will be performed.
To disable this feature, specify the -D option.
avrdude: erasing chip
delaying chip erase until first -U upload to flash
avrdude: processing -U flash:w:test.hex:i
avrdude: reading input file test.hex for flash
with 15712 bytes in 1 section within [0, 0x3d5f]
using 62 pages and 160 pad bytes
avrdude: preparing flash input for device bootloader
avrdude: writing 15712 bytes flash ...
Writing | ################################################## | 100% 24.50 s
avrdude: 15712 bytes of flash written
avrdude: verifying flash memory against test.hex
Reading | ################################################## | 100% 19.50 s
avrdude: 15712 bytes of flash verified
avrdude done. Thank you.
bootloader: urboot_m128rfa1_1s_x16m0_125k0_uart0_rxe0_txe1_no-led_ee_ce_hw.hex
FUSE_BOOTRST: enabled
FUSE_BOOTZ: 1024 words
> .\avrdude.exe -c urclock -p m128rfa1 -P COM7 -b 115200 -xshowall
avrdude: AVR device initialized and ready to accept instructions
0000ffffffff 0000-00-00 00.00 application 0 store 0 meta 1 boot 1024 u7.7 weu-hpr-c vector 0 (RESET) ATmega128RFA1
Flashing works correctly. The application loads and runs (haven't extensively tested it though).
But, so does using "FUSE_BOOTZ: 512 words". What should the expected behaviour be (knowing that the application does not fill the whole flash)? When should I start start getting problems for selecting a smaller "bootloader size" than the real size? EDIT: The size in the table, listed as 1024, is in bytes? I thought it was in words. This would mean 512 words is the correct size for the bootloader. Am I wrong?
With optiboot, I was using the last 16 bytes to store an Id. Well, doesn't optiboot store its version number in the last two bytes of flash? Yes, but I wasn't using those. Missing the version did not seem like a big problem.
From what I understood, I saw that part of this section is used for pgm_write_page(sram, progmem). Urboot v7.7 bootloaders hold a 6-byte table at top of flash, see "implicit communication" in the protocol definition I'm reading. BTW, I beleive the bytes for "number of pages" and "vector number" are swaped in the description vs the implementation.
I wouldn't compile an ID into the bootloader flash. Though you could, if you placed the ID into a separate section before the section version that contains the 6-byte table. Would be using "pgm_write_page" a better idea for storing ID?
On another thing: I was reading about about 'dual boot', wouldn't that be a good Idea to have implemented as a 'pre-compiled bootloader' for wireless microcontrollers (I'm thinking atmega128RFA1 and atmega256RFR2) leaving the selection of the CS pin the same way as the "LED NOP" pin?
Thanks for testing!
The bootloader name suggests it is compiled for a fixed baudrate of 125000 baud, but the command line shows you test with -b 115200
. I am surprised it works at all. Giving the hefty discrepancy (8%) am not surprised by comms error leading to protocol errors leading to paged access failing leading to trying bytewise access, which isn't supported... I suggest you
-b 125000
if your OS/driver supports that baud rate-b 115200
Yes, with the hardware-supported bootloader of 1024 bytes you need a bootsize of 512 words. The choice of 1024 words works by chance as long as the lower 1024 bytes are not overwritten by the application. A code sequence of four 0xff effectively is a NOP.
leaving the selection of the CS pin the same way as the "LED NOP" pin
Could do, but there are already a lot of pre-compiled bootloaders. Users who run applications with dual booting are probably OK with compiling their own bootloader.
leaving the selection of the CS pin the same way as the "LED NOP" pin
Well, the user would still need a way to change the CS NOPs in the bootloader hex with the op code to set/clear the CS. I haven't yet published a tool for doing so...
the bytes for "number of pages" and "vector number" are swaped in the description
Thanks, well spotted!
Would be using "pgm_write_page" a better idea for storing ID?
You can, but the bootloader pgm_write_page()
function won't overwrite the bootloader area itself. There is a neat trick to store IDs just after the vector table just so in every application code that you upload
uint8_t __attribute__((used)) __attribute__((section(".vectors")))
my_flash_ID[16] = {0x01, 0x02, 0x03, /* ... */ };
Thanks for testing!
The bootloader name suggests it is compiled for a fixed baudrate of 125000 baud, but the command line shows you test with
-b 115200
. I am surprised it works at all. Giving the hefty discrepancy (8%) am not surprised by comms error leading to protocol errors leading to paged access failing leading to trying bytewise access, which isn't supported... I suggest you
- Use
-b 125000
if your OS/driver supports that baud rate- Use a bootloader compiled for 115200 baud (should have 115k2 in the name) with
-b 115200
- Use an autobaud bootloader; this adapts to the speed the host sends (within reason)
The difference in baudrate is because of the different clock source I was using.
During testing, I was using a 14.7xxx MHz external crystal.
Since the bootloader for 125kbps@16MHz is the same as 115.2kbps@14.7xxxMHz, I just used the same.
(I did later test the connection with the 16MHz clock source and it correctly flashes using > .\avrdude.exe -c urclock -p m128rfa1 -P COM7 -b 125000 -U flash:w:"test.hex"
)
Yes, with the hardware-supported bootloader of 1024 bytes you need a bootsize of 512 words. The choice of 1024 words works by chance as long as the lower 1024 bytes are not overwritten by the application. A code sequence of four 0xff effectively is a NOP.
So it's the urboot bootloader who would could overwrite those last 512words when flashing the application, ¿right? I'm guessing the application couldn't write on the bootloader section because of the configured fuses. Am I right?
leaving the selection of the CS pin the same way as the "LED NOP" pin
Could do, but there are already a lot of pre-compiled bootloaders. Users who run applications with dual booting are probably OK with compiling their own bootloader.
Fair enough. I guess I'll try to configure a computer to compile it.
leaving the selection of the CS pin the same way as the "LED NOP" pin
Well, the user would still need a way to change the CS NOPs in the bootloader hex with the op code to set/clear the CS. I haven't yet published a tool for doing so...
I haven't read how it is done for "LED NOP" so I'm asking from ignorance, is that too complicated? Wouldn't it be like duplicate what's been done for the "LED NOP"?
Would be using "pgm_write_page" a better idea for storing ID?
You can, but the bootloader
pgm_write_page()
function won't overwrite the bootloader area itself. There is a neat trick to store IDs just after the vector table just so in every application code that you uploaduint8_t __attribute__((used)) __attribute__((section(".vectors"))) my_flash_ID[16] = {0x01, 0x02, 0x03, /* ... */ };
I'll need to check this out. But from what I read, this is an ID per application, right? Each application will have to have it's ID in the code and will be overwritten when changing the application.
My idea is to have a 'per board ID', like a serial number. That's the whole idea to keep it in the bootloader, it's not writable. Am I correct or wrong?
Using this same bootloader,
I see there's metadata (which I don't care about), could I use this space to store information to be read by the application?
If so, how could this be read?
Another question, is all the information on the 6bytes table at the top of the bootloader required?
I know if I modify the rjmp
for the pgm_write_page
function, it won't work, but what about the number of pages the bootloader uses or the vector number, are those used or they are there only for when asking for those using -xshowall
?
My idea is to have a 'per board ID', like a serial number. That's the whole idea to keep it in the bootloader, it's not writable.
Understand. In this case the bootloader needs to actually have 16 free bytes (check out Usage-Size in the bootloader tables). Then you need a way to overwrite the unused bootloader bytes with your board serial number. If you use a v7.7 urboot bootloader on an ATmega128RFA1 with 16 or more free bytes, the natural place for your serial number would be flash address interval [0x1ffea, 0x1fff9], ie, just below the six-byte table needed by urboot. No guarantees that the next urboot version won't increase the table size at the end of flash, though.
You could create a board-serial.hex file with your serial number in that range (srec_cat
is a great tool for this) and burn together with the urboot bootloader like so
$ avrdude -c your_ISP_programmer -p m128rfa1 ... -U urboot_..._.hex -U board-serial.hex
Voila
I see there's metadata (which I don't care about)
In which case you'd use -c urclock -x nometadata
whenever you upload/download programs
Another question, is all the information on the 6bytes table at the top of the bootloader required?
Yes, avrdude needs to know all this to keep the bootloader small.
I see there's metadata (which I don't care about), could I use this space to store information to be read by the application?
Well, actually the metadata hold information about where the application ends, the date and filename of the last uploaded sketch. Most crucially, the metadata identify the exact unused space between the application and the metadata. This unused space, called store can be used by the application to read and write data.
Note that flash wears out, though, (the manufacturer guarantees some 100,000 writes) so one shouldn't write flash gratuitously. Also note that flash can only physically be written a page at a time, so if you use above functions to write a single byte to flash, the underlying functions need to read the page, modify it and write it back.
My idea is to have a 'per board ID', like a serial number. That's the whole idea to keep it in the bootloader, it's not writable.
Understand. In this case the bootloader needs to actually have 16 free bytes (check out Usage-Size in the bootloader tables). Then you need a way to overwrite the unused bootloader bytes with your board serial number.
If you use a v7.7 urboot bootloader on an ATmega128RFA1 with 16 or more free bytes, the natural place for your serial number would be flash address interval [0x1ffea, 0x1fff9], ie, just below the six-byte table needed by urboot. No guarantees that the next urboot version won't increase the table size at the end of flash, though.
You could create a board-serial.hex file with your serial number in that range (
srec_cat
is a great tool for this) and burn together with the urboot bootloader like so$ avrdude -c your_ISP_programmer -p m128rfa1 ... -U urboot_..._.hex -U board-serial.hex
Voila
Currently, I think that's what I'm doing. I'm writing an unique identifier on the end (or beginnig, FLASHEND) of the bootloader (optiboot in this example) by modifying the hex file before flashing the board. Then, since I'm using the bootloader to update the application, I don't lose that identifier.
I guess I could write this serial to EEPROM, but I'd rather have this info in a place that's not writable by the application.
Another question, is all the information on the 6bytes table at the top of the bootloader required?
Yes, avrdude needs to know all this to keep the bootloader small.
I see there's metadata (which I don't care about), could I use this space to store information to be read by the application?
Well, actually the metadata hold information about where the application ends, the date and filename of the last uploaded sketch. Most crucially, the metadata identify the exact unused space between the application and the metadata. This unused space, called store can be used by the application to read and write data.
Note that flash wears out, though, (the manufacturer guarantees some 100,000 writes) so one shouldn't write flash gratuitously. Also note that flash can only physically be written a page at a time, so if you use above functions to write a single byte to flash, the underlying functions need to read the page, modify it and write it back.
I think this could work. I'll check it out. The number of writes shouldn't be a problem, since I want to use it as a read only section. Flash once and persist when updating the application without losing the data (it's a unique identifier, it should be unmutable).
Should it be compatible on future versions of the bootloader?
I'm writing an unique identifier on the end (or beginnig, FLASHEND) of the bootloader (optiboot in this example) by modifying the hex file before flashing the board.
OK, you can still do that with urboot bootloaders except
Fun fact: avrdude -c urclock
can display a Hex ID of up to 8 bytes as a hex number (low byte first). You specify the location with -xid=...
like so
$ avrdude -qq -curclock -xid=F.-14.8 -xshowid -Pch340
ffffffffffffffff
$ avrdude -qq -curclock -xid=F.-22.8 -xshowid -Pch340
ffff95082411cffd
This shows that my urboot bootloader only has 10 free bytes 0xff below the table.
Of course, you can also use a terminal command such as
$ avrdude -qq -curclock -Pch340 -T "read flash -22 16"
7fea fd cf 11 24 08 95 ff ff ff ff ff ff ff ff ff ff |...$............|
Should it be compatible on future versions of the bootloader?
Well, depends what you do with your ID. If applications never ever read it and it's only for you to inspect with the bootloader as above, then not. But if your application wants to read the board id, it needs to know its location (22 bytes below FLASHEND+1 for urboot v7.7), but a future urboot bootloader might have 8 bytes table and necessitate you mobe the board id 2 bytes lower.
When it works, it works.
During testing, I was using a 14.7xxx MHz external crystal. Since the bootloader for 125kbps@16MHz is the same as 115.2kbps@14.7xxxMHz, I just used the same. (I did later test the connection with the 16MHz clock source and it correctly flashes using > .\avrdude.exe -c urclock -p m128rfa1 -P COM7 -b 125000 -U flash:w:"test.hex")
Seeing that the urboot bootloader can be made to work, I am guessing it's the crystal caps and crystal that sometimes don't play and cause comms error; I concluded that urboot tests OK for ATmega128RFA1
I'm currently using Optiboot with a baudrate of 115.200bps on a board with 14.7456MHz.
Using AVRDUDESS (avrdude gui) on Windows, I can connect to it no problem.
But when flashing urboot, I can't get it to connect.
For optiboot I'm using: avrdude command:
avrdude.exe -c arduino -P COM5 -b 115200 -p m8
Boot Flash size = 1024, Boot reset vector enabled.For urboot I'm bootloader file: urboot_m128rfa1_1s_x14m7456_115k2_uart0_rxe0_txe1_no-led.hex Avrdude command:
avrdude.exe -c urclock -P COM5 -b 115200 -p m8
Same fuses. But can't connect, I get the error:Any help on how to troubleshoot this?
Probably a stupid little thing.