I need to tweak/rebuild the bootloader for the Mega2560 Arduino board. From what I can tell, this is the STK500v2 bootloader. I've pretty much figured out the changes and it builds okay. Before I try flashing it however I have a question about what seems to be an unreferenced function in the boot loader.
Where would be the best place to ask that question? I'm guessing it's not here but this is perhaps a good place to start.
I need to tweak/rebuild the bootloader for the Mega2560 Arduino board. From what I can tell, this is the STK500v2 bootloader. I’ve pretty much figured out the changes and it builds okay. Before I try flashing it however I have a question about what seems to be an unreferenced function in the boot loader.
Where would be the best place to ask that question? I’m guessing it’s not here but this is perhaps a good place to start.
I would read through the OptiBoot thread at the top of this forum, @westfw is the current maintainer of the Optiboot code, he is the authority on it.
I don't know if it'll work. I guess it should. The STK500v1 protocol used by optiboot isn't designed for handling more than 64kwords of program memory, and the 2560 version of optiboot "hacks" around this by sending a separate command that switches "bank" of memory essentially "outside" of the protocol. I find it sort-of ugly, You'll be outside of "common ground" and need a boards.txt modification as well, to use optiboot on a 2560 board from the IDE.
Thanks for the info...I guess I'll stick with the stk500 loader; don't feel like spending extra time debugging potential issues with optiboot.
So, regarding stk500boot.c I have a question about the function "jumpMain", declared like this:
since this bootloader is not linked against the avr-gcc crt1 functions,
to reduce the code size, we need to provide our own initialization
void __jumpMain (void) attribute ((naked)) attribute ((section (".init9")));
As I understand it, the .init9 attribute should cause the avr toolchain to use this function to begin execution. Have I got that right? There's a comment there about not using crt1.
But, when I build the hex file, jumpMain winds up completely un-referenced. The reset vector jumps to some different code which appears to copy some flash data to ram (using ELPM) among other things, then it CALLs main(), then JMPs to _exit().
There's a directory in the bootloader source called "good hex files" or similar, and the hex file in there also appears to have the jumpMain code which is also unreferenced.
So, is there a problem with this or is jumpMain just something in the code that never got cleaned up?
Finally, my hex file is a bit smaller 18k vs 21k than the "good hex file" but then I've built this with the toolchain included in Atmel Studio 6.2. Is THAT anything to be concerned about?
when I build the hex file, jumpMain winds up completely un-referenced.
putting code in the .init sections implies a specific physical ordering of the code, so it's POSSIBLE that code that isn't referenced is executed anyway, just because it physically follows other startup code that doesn't have a terminating jump or return. But it looks like stk500boot is currently broken, because the user-provided code in init9 is placed AFTER the init9 code from the startup files, which already contains the call to main(). Thus jump_main is never reached. Optiboot uses .init9 to position code as well, but it completely suppresses ANY of the normal startup code.
is jumpMain just something in the code that never got cleaned up?
It looks that way.
I'm not sure what stk500boot is trying to do - while the comment says the code isn't linked with crt1, the commands to actually do that seem to have been removed from the Makefile a long time ago (along with the attempt to "reduce code size.") The code in jump_main duplicates functionality that the other startup code does anyway; I think it's essentially 'dead code' that should have been removed a long time ago.
my hex file is a bit smaller 18k vs 21k than the "good hex file" but then I've built this with the toolchain included in Atmel Studio 6.2. Is THAT anything to be concerned about?
I don't know. I get three different object file sizes with three different versions of the compiler, and none of them matches the .hex file packaged with the arduino IDE. With Optiboot, changing compiler versions is frequently "exciting", but optiboot is much more dependent on internal details of the compiler operation, and the problems are usually obvious (doesn't compile at all, doesn't fit in the required size, etc.) stk500boot is more conservative in what it does, and has more relaxed "requirements", so it should be less sensitive...
Thanks for putting some serious effort into answering my question. Your help is much appreciated!
I’m just going to try it and see what happens. If the hex file packaged with the Arduino installation is valid I should be able to flash that back in there if the one I built doesn’t work. I’ll post back here with my results…
Thanks also to Dr Azzy for giving me a little more confidence that this might work.
Okay, I got it to work. The only reason I’m doing this is to run the Mega at 10MHz instead of 16MHz. Here’s what I found along the way:
The bootloader needed to be built with WinAvr. For some reason using Atmel Studio doesn’t work. I tried to match the compile and link flags in both builds but that is apparently not enough. I also used the include files packaged with the arduino release instead of the files in the AVR toolchain installed with Atmel Studio. Maybe that was a mistake. Any ideas? Just curious and it matters little since I’ve got it working.
It would not work with a 115,200 baud upload speed. 57,600 did not work either but 28,800 is okay. The system clock is now 10MHz (accurate to better than 1 ppm) and baud rate calcs seem to indicate that 115,200 can be done with only 1.3% error. Bottom line is that it works and I don’t mind the uploads taking a little longer. I would like to understand why, however. Are there significant errors in the baud rate generated on the host computer side?
So....will that really work? I grabbed a copy of the "m2560" branch from github, and was able to build the hex file okay.
I'd prefer to use optiboot if it would work.
It works for me You could check it as these modifications are not very significant, so I bet it's 'production' safe. (I use it for months without any issues along with other features and fixes in supermaster branch).
Only one downside is that you need fresh version of Avrdude (at least 6.1) as version shipped with Arduino is older and doesn't support memory bank switching.
The STK500v1 protocol used by optiboot isn't designed for handling more than 64kwords of program memory, and the 2560 version of optiboot "hacks" around this by sending a separate command that switches "bank" of memory essentially "outside" of the protocol. I find it sort-of ugly,
The same 'ugly' way STK_UNIVERSAL is recommended for reading and writing fuse and lock bits as described in AVR061 (STK500v1 protocol description). Also support for writing flash on devices with more than 128KB memory is present in Avrdude for about 2 years (currently in two official releases) as it works with real STK500 programmer, so I would call it 'stable' and I would be happy that such feature is possible, works and Optiboot also could use it.