November 17th, 2013:
0) Bug fix - the bootloader replied to an erase command with the wrong response.

November 16th, 2013:
0) I removed sizebefore and sizeafter from the makefile 'all' target. The line is still there, but it's commented so the size* targets aren't built by default. This should allow the project to build on both platforms without any issues.

1) AS6 solution files are now in the repository so the project can be built using GNU tools at the command line or in AS6 with an external makefile. You still have to modify the makefile to set the MCU variable in either case. If you choose to use AS6, you also need to set the MCU in the project settings.

2) I added support for all of the Xmegas currently in Atmel Toolchain 3.4.2.

====================================================

I thought I'd make a formal post about this since it's been a while. A few years ago, I worked on an AVR911 bootloader from Atmel with another member here. We made it much easier to use with the hope that more people would be able to benefit from a bootloader. Our experience at that point (and still today...) is that most bootloaders are overly complicated and abstract. This one hopefully isn't. If you have any questions, comments, or feedback, please let me know.

To acquire the source code, go to Github and download it using your browser (zip file) or with git. Here is the link to the repository. To clone the repository from the command line, please do this:

git clone git://github.com/bandtank/Xmega_Bootloader.git

To use the bootloader, open the makefile and edit this section:

###############################################################################
# User modification section
###############################################################################
# Choose one of the following MCUs:
# If you have a different MCU, you will have to define these values:
# Name in makefile Name in ioxxxx.h
# --------------------------- -----------------------------
# BOOT_SECTION_START_IN_BYTES BOOT_SECTION_START
# BOOT_PAGE_SIZE BOOT_SECTION_PAGE_SIZE
# APP_PAGE_SIZE APP_SECTION_PAGE_SIZE
#
# You can find these files in the include path for your compiler. Examples:
# 1) Winavr: C:\WinAVR-20100110\avr\include\avr\ioxxxx.h
# 2) Atmel 3.4.2: C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\
# Native\3.4.2.1002\avr8-gnu-toolchain\avr\include\avr\ioxxxx.h
# MCU = atxmega128a1
# MCU = atxmega64a3
MCU = atxmega64a3u
# MCU = atxmega32a4
# MCU = atxmega16a4
# MCU = atxmega16d4
# Choose a baud rate for the UART.
# If you need a baud rate that is not listed in this makefile, you must add
# new configuration statements in config.macros.h. Remember, Xmegas start-up
# with a 2MHz clock.
# BAUD_RATE = 9600
# BAUD_RATE = 38400
# BAUD_RATE = 57600
BAUD_RATE = 115200
# Specify a pin to check for entry into the bootloader. The notation is
# PORT,PIN. For example, if you wanted to use PIN 3 on PORTC, you would set
# the option as C,3. Then specifiy the logic value required to enable the
# bootloader code (1 = enable the bootloader if the pin is VCC, 0 = enable
# the bootloader if the pin is GND).
BOOTLOADER_PIN = B,2
BOOTLOADER_PIN_ON = 0
# Specify a pin to control an LED. The notation is PORT,PIN. For example, if
# you wanted to use PIN 6 on PORTA, you would set the option as A,6. Then
# specifiy the logic value required to enable the LED (1 = output VCC to turn
# on the LED, 0 = output GND to turn on the LED).
LED_PIN = D,2
LED_ON = 0
# Specify which UART to use with PORT,NUM notation. For example, UART1 on
# PORTD would be D,1.
UART = C,0

If the Xmega you plan to use is in the user modification section, then you're done. If it's not, then it should be easy to add by following the examples in the file. To find the required information, you'll need to search through the header files that came with your compiler.

If you're using the Atmel toolchain in Windows, you can probably find the files here (change the path as necessary depending on version numbers):

If AVRDUDE doesn't support your xmega, you can add support by editing avrdude.conf. My advice is to search the file for an xmega similar to the one you want to use. Copy the whole section, paste it in the file, and then change the necessary parameters. For example, the xmega16d4 isn't supported by AVRDUDE 5.10, but I added it by copying the configuration for the xmega16a4 and then changing the first few lines:

Hi all!
As Deathcow, I'm lost regarding the building of your bootloader. And if I try to compile it from a cmd window, it does not work (saying -f was unexpexcted...).
I will look at your makefile and try to make a new Studio 6 project for this bootloader.

Deathcow, I have created a new project under Studio 6.1, with the name "Xmega_Bootloader" for my device, ATXmega128A1U. Then I've overwrite the newly created Xmega_Bootloader.c with the one from the git repo, and copied all the other files inside the solution directory, except the .git, the README and the makefile.
Then I opened said makefile in Studio to see its internals. What you have to do is to look at the lines 107, 111 and 117.
Line 107 will give you the symbols to define in the project properties->AVR/GNU C Compiler->Symbols (10 including MCU and F_CPU).
Line 111 tells you to add those same flags to the ASM flags (project properties->AVR/GNU Assembler->General).
Line 117 tells you to relocate the .text section to the start of the boot section of your xmega (project properties->AVR/GNU Linker->Misc). And that should do the trick. I will add the DFLL to have a better precision on the USART.

Bandtank there is a BOOTUP_DELAY symbol which is not used nor defined. Did I missed something here ?

AS6 has "Create project from Makefile" on the Tools menu. I just attempted to use this after having git clone'd the files (and test built them using the old WinAVR tools). The As6 process was not entirely successful in that it ended with the Solution Explorer constant showinf "(loading)" but never completing. I looked at the .atsln and .cproj files it had created and it turns out that the .atsln still referred to a .cproj file in my %TEMP% directory which was no longer there. However it HAD created the .cproj file in the project directory so I just edited the XML of the .atsln file to fix up the file reference to "./proj.cproj" and then the solution loaded and built OK.

I didn't know about this feature of Studio, it is much quicker than my method...
However, my compiled version does not work with AVROSP, I will have to check with a terminal and send a few command, and/or use avrdude.

I didn't know about this feature of Studio, it is much quicker than my method...
However, my compiled version does not work with AVROSP, I will have to check with a terminal and send a few command, and/or use avrdude.

Did you make sure to change the programming address to the boot section byte address? I've never tried my file in AS6, so I'm not sure how to do it. I'll try now, though...

Ok, I got it to work with basically no issues in about two minutes. I'm not sure if I just got lucky, but here's what I did:

1) Cloned the bootloader
2) Opened AS6 - Install "Create Project from Makefile" from the Extension Manager (it wasn't listed in the tools menu for me)
3) Imported the makefile using the "Create Project from Makefile" tool
4) Built the project (no errors or warnings for me)
5) Programmed using JTAGICE3
6) Communicated with the bootloader using AVRDUDE

I should also add that I built the project using Winavr's avr-gcc in the same directory after creating an AS6 project. It's clear that AS6 used the Atmel Toolchain to build because the build size was 2626 bytes when it's usually 2652 bytes with Winavr's avr-gcc on my system.

Sorry for all of the spam, but I thought these posts should remain discrete so people can find all of the relevant information.

I created a branch of the repo that has a working AS6 solution file. You'll need to change the MCU define in the makefile as well as the project settings, but, otherwise, this should work assuming your environment is setup correctly.

It doesn't seem to like the sizebefore routine. Someone else had that problem as well because they were using make in cmd.exe instead of sh.exe, which is the default. Try altering line 132 in the makefile from this:

I was able to reproduce your error on a computer that doesn't have Winavr installed . I don't actually know if that's what causes sizebefore/after to work correctly, but the makefile definitely failed then passed with sizebefore/after in the makefile and then commented, respectively. Let me know if you get the same results please.

It doesn't seem to like the sizebefore routine. Someone else had that problem as well because they were using make in cmd.exe instead of sh.exe, which is the default. Try altering line 132 in the makefile from this:

This change allowed it to build. Thanks for that. I can't wait to try it out. I am using a 256A3B. This is new territory for me. I assume I can load only the bootloader into the XMEGA via AVR Studio 6 - then I am forced to load my app via the new bootloader. You cant load the bootloader and your revision 1 app both onto the chip from AVR Studio?

The error above is because the clean: rule uses the Unix command "rm -fr". If you have WinAVR installed (and in the PATH) it has gnuwin32 tools in ./utils/bin and that includes rm.exe which is a Windows build of the Unix command. So edit the Makefile and use "del" instead if you don't have gnuwin32 tools.

It doesn't seem to like the sizebefore routine. Someone else had that problem as well because they were using make in cmd.exe instead of sh.exe, which is the default. Try altering line 132 in the makefile from this:

This change allowed it to build. Thanks for that. I can't wait to try it out. I am using a 256A3B. This is new territory for me. I assume I can load only the bootloader into the XMEGA via AVR Studio 6 - then I am forced to load my app via the new bootloader. You cant load the bootloader and your revision 1 app both onto the chip from AVR Studio?

I'm guessing you can, but I don't know how. You'd have to specify the placement of the bootloader code to be in the bootloader section and the application code in the application section.

I do that in the makefile for the bootloader on line 117:

LDFLAGS += -Wl,-section-start=.text=$(BOOT_SECTION_START_IN_BYTES)

That's why you have to modify the settings for each MCU so the code will end up in the right place. To load both at once, you can probably play some games with the linker flags on a per file/project basis.

In the end, though, I don't know if you gain much by spending the time to do that. Once the bootloader is on the MCU, it's very simple to program the application. Loading both at once would only save you time the first time you want to program the application code.

The error above is because the clean: rule uses the Unix command "rm -fr". If you have WinAVR installed (and in the PATH) it has gnuwin32 tools in ./utils/bin and that includes rm.exe which is a Windows build of the Unix command. So edit the Makefile and use "del" instead if you don't have gnuwin32 tools.

I'm not sure if my system is different somehow, but I don't have the Winavr/bin directory in my path and I still have access to rm. Maybe I need to edit the makefile to detect the OS so different tools can be used...

0) I removed sizebefore and sizeafter from the makefile. The line is still there, but it's commented so the size* targets aren't built by default. This should allow the project to build on both platforms without any issues.

1) I merged the branches because there's no reason the AS6 files can't live in the same branch as the non-AS6 version.

2) I added support for all of the Xmegas currently in the Atmel toolchain.

FYI - I caught this using the -vvvv option to AVRDUDE. It showed me that the programmer was responding, but the response wasn't correct. I introduced this bug a few commits earlier when I changed all of the responses to be preprocessor defines for readability. I accidentally switched the return value to be 'Y' instead of '\r'.

You can see the response was 0x59 ('Y'). The reason it worked when you specified -D is because the chip already erased even though AVRDUDE failed because of the bad response. The next time you programmed the chip, it was in an erased state so it could be programmed correctly.

Line 93 is correct in my codeset. To make sure, I cleaned the build and tried to validate -- and saw that it couldn't find the hex file to validate. I then rebuilt the solution and validated, and it validated correctly against my device.

I was able to reproduce the failure with AVRDUDE 6.0.1. The bootloader works fine with AVRDUDE 5.10.

If you specify -D it works and if you specify -e it works. -e forces a full chip erase, and that's the behavior I would expect AVRDUDE to have by default. I don't know what it's doing if you don't use either option.

I'm looking at the source code to see if I can figure out what's wrong.

Wow you are right, -e works. I ..swear.. I tried -e and it immediately failed. I must have had something else wrong. So, with -e, I have a fully functional solution. I had thought -e was erasing the bootloader too.

Wow you are right, -e works. I ..swear.. I tried -e and it immediately failed. I must have had something else wrong. So, with -e, I have a fully functional solution. I had thought -e was erasing the bootloader too.

Thanks for all your help, this is a really great thing for me.

Mike

We've swapped emotions. Now I'm annoyed that I can't figure out what's wrong with it. =P

I'll probably post to the mailing list because the behavior obviously changed between 5.10 and 6.0.1. The real issue is the unknown. I don't know if there's more wrong than what we've seen so far. For example, the EEPROM might unintentionally get nuked if the erase routine isn't working correctly. I'd like to avoid issues of that nature.

I'm trying to use your code with AVR Studio 6.1. I installed WinAVR and using AVRispmk2 as programmer. I changed the makefile to use with xmega128a3u and was able to compile it. However, when program the "xmega_bootloader.hex" file with AVR Studio I got this message: "Verifying Flash...Failed! address=0x20c00 expected=0xca actual=0xff"

Why on earth would you install WinAVR (avr-gcc 4.3.3) when Studio 6 (latest is 6.2 not 6.1 by the way) comes with avr-gcc 4.8.1 and if you wait a bit there will be Studio 7.0 and that comes with 4.9.2

No point using a 5..6 year old compiler when you can have a very recent one with tons of new features and bug fixes.

None of this has anything to do with your actual programming error but the fact you are using an out of date Studio (6.1) with presumably out of date USB drivers probably DOES have a lot to do with it.