The 2boots bootloader is a lovely bootloader, developed by Thomas Seiler that is
- Just 2kb of flash, fits into normal 2kb bootblock of most atmega chips
- Serial (stk500v1) bootloader, compatible with avrdude and Arduino IDE
- Additional MMC bootloader, can read directly a intel .hex format file from an MMC/SD
What is appealing here is the ability to upload firmware without a programmer, simply by inserting a SD card with the .HEX file and performing a reset. That is a nice feature to have when having to remotely update the firmware – imagine that you have multiple nodes at clients in many locations: they can upgrade firmware quite easily now.
I (and many others) have previously tried to get it working, but couldn’t; we ended up using another bootloader that is SD card only (and .bin, not .hex compatible) and 4Kb.. I shared my experience here and here. Clearly 2boots is better..if only it was working. After failing to get it run, I have abandoned the project until recently I noticed some activity in Thomas’ github repository. There seems to be some fixes introduced and I decided to give it a new try. It didn’t work again, so I took a deeper look. It seems that he had another branch (new-makefile) in the repository that was having quite a bunch of changes, I tested it too and noticed that there is improvement: it did update the firmware from SD card, but only after a successful serial upload..odd? After couple days of debugging and testing, it turns out that there is a logical problem in the stk500v1.c file – it performs a WDT reset after timing out on serial, therefore the MMC upload procedure was never called unless preceded by a successful serial sketch upload.. duh. I fixed that by using a “break;” instead of performing watch-dog reset and Voila – it worked!
I tried it on my uIoT gateway with SD shield on and it works nicely. Quite nice feature to have. I have added it to my collection of bootloaders for the uIoT on github.
Tried using the code you have put on github but I cannot see what to tell it to use digital pin 10 as the CS pin. I’m trying to us a standalone arduino with an SD Card Module that has the CS pin at 10. Any help would be great.
Scott,
you have to adjust the Makefile, for the uIoT it has these lines
board-arduino: FCPUS = 6250000L
board-arduino: MCUS = atmega328p
board-arduino: MMC_CSS = PC1
while for a “normal” arduino you need
board-arduino: FCPUS = 16000000L
board-arduino: MCUS = atmega328p
board-arduino: MMC_CSS = PB2 //digital 10
then build and burn
Hi,
I would love some help to get this ported over onto the arduino Mega. Specifically running at 3.3V and MHz
That should be fairly easy; I guess changing the SD CS and LED pins + using appropriate fuses should do it.
I don’t have a Mega, neitither the time to help further than this 😉
Pingback: Re-vamping my Daikin Internet Air-conditioner controller | Martin's corner on the web
I am going to try your bootloader at the Arduiono Ethernet board but I am also very interested in using on the new Due board with and Ethernet shield (which has the SD socket). Is this possible or is it something completely different?
It won’t work, this bootloader is for the Atmega328 processor only
So any ideas on what to do with the DUE?
🙂 not really. at that price tag, I’d use a Raspberry Pi instead.
Hey Martin, this looks very good.
I have tried out your code, compiled it and flashed it. But then i can’t contact the arduino over the serial interface any more. I’m using a Arduino Uno and normaly it should work when i understand the 2boot description right. Do you have any ideas?
Thank, Thomas
Few things to watch out:
1) mind the FCPU and set it to whatever frequency you run
2) mind the SD card select pin
3) upload baud rate is 19200, update this in your boards.txt
Hi there !
I managed to compile you code, but when I try to upload a program using arduino I get
avrdude: stk500_recv(): programmer is not responding
I’ve set the FCPU to 16000000L in the make file, and baud rate to 19200 in boards.txt. Even with the nommc it doesnt works. I also tried to upload with the arduino and the stk500v1 protocol (by editing boards.txt)
When I try to upload, the RX and TX leds blinks the following pattern once :
RX TX RX RX
It means that I’ve got a answer from the µcontroller, but avrdude doesn’t seem to take it into account as it says “not responding”.
It’s really important for me to get 2boots working for my project. It’s a portable gaming device based on arduino, and thank to 2boots it would be able to switch between games without a computer.
Thank you for reading, I hope you have any idea what the problem could be :/
…I forgot to say, I’m running on an atmega328p @16Mhz, and I use a FT232L for the USB port. It works like a charm with uno and duemilanove bootloader.
Can you share the compile flags, I have lost mine too, so these will be for the history/future visitors.
My boards.txt has the upload protocol set to stk500v1 too, here is what is working for me: (I have 12.5Mhz MCU, ignore that part)
##############################################################
2buiot.name=Simon K. Micro Web Server @ 12.5Mhz /19200 2Boots
2buiot.upload.protocol=stk500
2buiot.upload.maximum_size=30720
2buiot.upload.speed=19200
2buiot.bootloader.low_fuses=0xE0
2buiot.bootloader.high_fuses=0xDD
2buiot.bootloader.extended_fuses=0x05
2buiot.bootloader.path=atmega
2buiot.bootloader.file=uiot.hex
2buiot.bootloader.unlock_bits=0x3F
2buiot.bootloader.lock_bits=0x0F
2buiot.build.mcu=atmega328p
2buiot.build.f_cpu=12500000L
2buiot.build.core=arduino
2buiot.build.variant=standard
I use the compile flags from your github :
OPTIMIZE = -Os -funsigned-char -fno-split-wide-types -fno-inline-small-functions -mcall-prologues -ffunction-sections -fdata-sections -ffreestanding -fno-jump-tables -fno-tree-scev-cprop -fno-split-wide-types
When I compile it does a 2006B text size.
I’m going to try to upload that again, I’ll post my progress here.
It appears from the Readme file that you are making it on a Linux machine, and I am having big problems getting it to make on a Win7 PC. It starts processing the Makefile but it has problems with mkdir, cut and awk. I wonder if you have a simpler Makefile that would work on Windows.
I compiled it on a Linux VM; Ubuntu is fairly easy to run without installation (from a CD)
I am still struggling with the build on Linux and wonder if you could upload hex files for all boards? In particular I need it for the Arduino Ethernet board, which I think should be:
2boots-arduino-atmega328p-16000000L-PD4.hex
This is not included.
Thanks….
Hi Martin,
Thanks for the great post and details! I’d like to use this bootloader with a custom board I’m working on but had a question regarding the reset. My current board design doesn’t include a reset button with it, so users simply reset by taking the power plug out and plugging it back in.
Do you see any reason that loading new sketches with 2boots won’t work with such board design? Do I need to add a reset button to get this working?
My assumption is that taking the power out and back in will give identical result as a reset button and therefore just placing the power back in with the new hex file placed in the SD card slot should work just fine.
Would love to get your thoughts and experience with this.
Thanks!
-J-
It does work, my uIoT project also doesn’t have a reset pin and a power cycle does the trick.
Cheers,
Martin
Super! Thanks Martin! 🙂
Hi Martin,
After a long night (and partially morning..) I managed to build it on my Windows machine. But I’m suspecting I might be heading to a new problem. After completing the build, make reports the result size of 2070 bytes.
According to the original readme file, the bootloader shouldn’t exceed 2Kb. I tried to see if I can find anything in the src I can just remove – but I doubt there is any spare code in there.
What is the size you’re getting? Do you believe this will indeed cause a problem?
Thanks again!
Actually thinking about it some more – since I’m preparing my own custom boards I can probably remove the entire eeprom check section – and just place my fixed board name in the code. Do you see any reason this change won’t work?
I assume such change will free enough space.
I remember running into the same issue, I fiddled with the OPTIMIZE flags line in the MakeFile and eventually got it to less than 2048 bytes.
I compiled this on a Raspberry Pi by the way.
Using hardcoded sketch name will definitely save you few bytes
Yup – changed the code to a fixed name and I’m down to 2044, seems like this might work!
Now making changes in the Arduino IDE and will try to burn the new bootloader shortly for some testing. Thanks for the help!
Just mind that the baud rate is forced to 19200 (you can easily change that in the arduino-board.h file)
Hi !
I’m also trying to compile 2boots for a custom board, and I get a 2190 bytes hex… what did you do with the optimization flags ? Could you share which one you used ? Tanks !
Hi Martin,
Well done reworking this bootloader. I downloaded your version a month or so ago but didn’t have any luck getting it working at the time. I have recently had some time to look into why.
I didn’t require the serial upload capability in my application so I removed that which left plenty of room to add debug output. I found that my cards were all failing init(). I was confident the FAT16 formatting was ok. The cards I have to play with are limited to Verbatim and Transcend brands – don’t know if this is a factor.
I ended up increasing the timeouts of a few loops in the code and now the bootloader works perfectly and reliably for all my SD cards. This is on genuine Arduino boards, a freetronics “EtherTen” board, and a custom 328P-based application-specific board I have made.
For interest (or anyone else having similar issues), these are the parts where I modified the timeouts –
– MMC_CMD0_RETRY
– send_cmd() (“wait for response” loop)
– mmc_init() (“reset MMC”)
– wait_start_byte()
Thanks for sharing this!
No problem! Also perhaps worth mentioning I added a timeout to the “while(send_cmd() != 0)” loop at the end of mmc_init(). There is a comment there wondering if it could become an endless loop, and I found this is exactly what happened if I had a FAT32 [4GB only tested] card in when the chip was reset. My custom board is used in a datalogging application so this is a pretty likely scenario for me, and having the bootloader hang is not exactly ideal! 😉
Hello nick, what values did you take for the timeouts and how exactly did you solve the fat32 problem?
(would you consider uploading the code, i’m not that good at bootloaders?)
I have doubled the values of i and the CMD0, however, some cards still aren’t working. (What am i doing wrong here?)
Hello, please can upload the hex of the boot, u.u i can’t compile this project, please !!!
Is it possible make a programme that can change the name of the sketches so that you can choose what sketch you want to use?
Yes, I have done that. The name of the sketch is stored in EEPROM, so whatever you write there, that would be started
Hello,-
I’ve managed to get out some more bytes 🙂
now i’m waiting to put in nick’s changes to be more reliable
however, there’s still a problem: it keeps flashing the hex from sd on every reset; i think martin, you said that this isn’t good and that it should be taken care of.
i also tried to let mmc first check if there’s a file called 0, in order to let it flash (and letting the Hex file stay on sd card), but to no avail…
Hello Martin,
I finally managed to write the bootloader to my atmega 328p (with some help of a friend to compile it) and ran into the next problem. what format the file on the sd card must have? what must i do with the .ino file to make the thing work.
Thanks in advance for your answer, Michael
hi,
see
http://stackoverflow.com/questions/11607834/where-are-the-hex-files-compiled-by-arduino
Hello Martin,
thank you for the quick answer.
I found the .hex of the blink example and put it on the card, but unfortunately the code wouldnt load 🙁
I wanted to name the ardoino but didn’t get a connection to the board via serial connection.
I just get the error message avrdude: stk500_getsync(): not in sync: resp=0x00
I tried to write back the original bootloader but got an error message again.
I hope you can help,
Michael
Error log for uploading NameBoardSketch
Binäre Sketchgröße: 2.326 Bytes (von einem Maximum von 30.720 Bytes)
C:\Programme\Dev\Arduino\hardware/tools/avr/bin/avrdude -CC:\Programme\Dev\Arduino\hardware/tools/avr/etc/avrdude.conf -v -v -v -v -patmega328p -carduino -P\\.\COM7 -b57600 -D -Uflash:w:C:\DOKUME~1\VONBAR~1\LOKALE~1\Temp\build3319578670752978141.tmp\NameBoardSketch.cpp.hex:i
avrdude: Version 5.11, compiled on Sep 2 2011 at 19:38:36
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2009 Joerg Wunsch
System wide configuration file is “C:\Programme\Dev\Arduino\hardware/tools/avr/etc/avrdude.conf”
Using Port : \\.\COM7
Using Programmer : arduino
Overriding Baud Rate : 57600
avrdude: Send: 0 [30] [20]
avrdude: Send: 0 [30] [20]
avrdude: Send: 0 [30] [20]
avrdude: Recv:
avrdude: stk500_getsync(): not in sync: resp=0x00
avrdude done. Thank you.
Command lines for avrdude to write original bootloader
avrdude -p m328p -P com7 -c stk500v1 -b 19200 -F -v -v -e -Ulock:w:0x3F:m -Uefuse:w:0x00:m -Uhfuse:w:0xdd:m -Ulfuse:w:0xff:m
avrdude -p m328p -P com7 -c stk500v1 -b 19200 -F -v -v -e -U flash:w:ATmegaBOOT_168_atmega328.hex
Error log from avrdude to write original bootloader
Using Port : com7
Using Programmer : stk500v1
Overriding Baud Rate : 19200
AVR Part : ATMEGA328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page
Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW Max
W ReadBack
———– —- —– —– —- —— —— —- —— —– —
— ———
eeprom 65 5 4 0 no 1024 4 0 3600 36
00 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 45
00 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 45
00 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 45
00 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 45
00 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 45
00 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0
0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0
0 0x00 0x00
Programmer Type : STK500
Description : Atmel STK500 Version 1.x firmware
Hardware Version: 2
Firmware Version: 1.18
Topcard : Unknown
Vtarget : 0.0 V
Varef : 0.0 V
Oscillator : Off
SCK period : 0.1 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.08s
avrdude: Device signature = 0x000000
avrdude: Yikes! Invalid device signature.
avrdude: Expected signature for ATMEGA328P is 1E 95 0F
avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: erasing chip
avrdude: reading input file “0x3F”
avrdude: writing lock (1 bytes):
Writing | | 0% 0.00s ***faile
d;
Writing | ################################################## | 100% 0.17s
avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x3F:
avrdude: load data lock data from input file 0x3F:
avrdude: input file 0x3F contains 1 bytes
avrdude: reading on-chip lock data:
Reading | ################################################## | 100% 0.03s
avrdude: verifying …
avrdude: verification error, first mismatch at byte 0x0000
0x3f != 0x00
avrdude: verification error; content mismatch
avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: safemode: Fuses OK
avrdude done. Thank you.
C:\WinAVR-20100110\bin>
C:\WinAVR-20100110\bin>avrdude -p m328p -P com7 -c stk500v1 -b 19200 -F -v -v -e
-U flash:w:ATmegaBOOT_168_atmega328.hex
avrdude: Version 5.10, compiled on Jan 19 2010 at 10:45:23
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2009 Joerg Wunsch
System wide configuration file is “C:\WinAVR-20100110\bin\avrdude.conf”
Using Port : com7
Using Programmer : stk500v1
Overriding Baud Rate : 19200
AVR Part : ATMEGA328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page
Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW Max
W ReadBack
———– —- —– —– —- —— —— —- —— —– —
— ———
eeprom 65 5 4 0 no 1024 4 0 3600 36
00 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 45
00 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 45
00 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 45
00 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 45
00 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 45
00 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0
0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0
0 0x00 0x00
Programmer Type : STK500
Description : Atmel STK500 Version 1.x firmware
Hardware Version: 2
Firmware Version: 1.18
Topcard : Unknown
Vtarget : 0.0 V
Varef : 0.0 V
Oscillator : Off
SCK period : 0.1 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.06s
avrdude: Device signature = 0x000000
avrdude: Yikes! Invalid device signature.
avrdude: Expected signature for ATMEGA328P is 1E 95 0F
avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: erasing chip
avrdude: reading input file “ATmegaBOOT_168_atmega328.hex”
avrdude: input file ATmegaBOOT_168_atmega328.hex auto detected as Intel Hex
avrdude: writing flash (32670 bytes):
Writing | ################################################## | 100% 2.59s
avrdude: 32670 bytes of flash written
avrdude: verifying flash memory against ATmegaBOOT_168_atmega328.hex:
avrdude: load data flash data from input file ATmegaBOOT_168_atmega328.hex:
avrdude: input file ATmegaBOOT_168_atmega328.hex auto detected as Intel Hex
avrdude: input file ATmegaBOOT_168_atmega328.hex contains 32670 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 25.34s
avrdude: verifying …
avrdude: verification error, first mismatch at byte 0x0000
0xff != 0x00
avrdude: verification error; content mismatch
avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: safemode: Fuses OK
avrdude done. Thank you.
C:\WinAVR-20100110\bin>avrdude -p m328p -P com7 -c stk500v1 -b 19200 -F -v -v -e
-U flash:w:ATmegaBOOT_168_atmega328.hex
avrdude: Version 5.10, compiled on Jan 19 2010 at 10:45:23
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2009 Joerg Wunsch
System wide configuration file is “C:\WinAVR-20100110\bin\avrdude.conf”
Using Port : com7
Using Programmer : stk500v1
Overriding Baud Rate : 19200
AVR Part : ATMEGA328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page
Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW Max
W ReadBack
———– —- —– —– —- —— —— —- —— —– —
— ———
eeprom 65 5 4 0 no 1024 4 0 3600 36
00 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 45
00 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 45
00 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 45
00 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 45
00 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 45
00 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0
0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0
0 0x00 0x00
Programmer Type : STK500
Description : Atmel STK500 Version 1.x firmware
Hardware Version: 2
Firmware Version: 1.18
Topcard : Unknown
Vtarget : 0.0 V
Varef : 0.0 V
Oscillator : Off
SCK period : 0.1 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.06s
avrdude: Device signature = 0x000000
avrdude: Yikes! Invalid device signature.
avrdude: Expected signature for ATMEGA328P is 1E 95 0F
avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: erasing chip
avrdude: reading input file “ATmegaBOOT_168_atmega328.hex”
avrdude: input file ATmegaBOOT_168_atmega328.hex auto detected as Intel Hex
avrdude: writing flash (32670 bytes):
Writing | ################################################## | 100% 2.61s
avrdude: 32670 bytes of flash written
avrdude: verifying flash memory against ATmegaBOOT_168_atmega328.hex:
avrdude: load data flash data from input file ATmegaBOOT_168_atmega328.hex:
avrdude: input file ATmegaBOOT_168_atmega328.hex auto detected as Intel Hex
avrdude: input file ATmegaBOOT_168_atmega328.hex contains 32670 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 25.34s
avrdude: verifying …
avrdude: verification error, first mismatch at byte 0x0000
0xff != 0x00
avrdude: verification error; content mismatch
avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: safemode: Fuses OK
avrdude done. Thank you.