Bootloader basic

Go To Last Post
24 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My boss asked me to set up a bootloader. Since I don't yet have the device designed I would be reprograming from I do not need to actually reflash the code at this time. For now I just want to set up the framework. What I want to do (and this part is not a problem) is given a certain condition I will set a bit in the EEPROM. Then reboot. Then, for now, I want to have the bootloader skeleton just go read that bit and if it is set, reset the EEPROM flag, and just spin. Then I could pull the power and it should reboot and notice the EEPROM flag is not set and jump back to main. Then later when I get a new programmer key designed I can just add the stuff in that loader before I reset the flag to update the application code. Then reboot...

So I already have the code to set the flag and reboot. I read through the docs and I get what I need to do to the fuses to get it to enable the boot loader. But then I get a bit lost. I have searched the forum and there is a ton of stuff scattered all over but I have not found info I can use. I have a proprietary interface not even designed yet so I can't use the ATMEL USB DFU tools or anything like that. So this is why I just want a framework to start with then I will do the heavy lifting when I get a new "Reprograming KEY".

So is there a special function like main() that the compiler knows about (perhaps bootloader()) that if I create it and set the fuses properly the system will not start at main() rather start in the bootloader start address and execute this function first?

Any good links would be appreciated as well.

Not sure this matters but my product is running on Mega 168P and 328P controlers depending on availability.

Thanks!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just look at how the Arduino bootloader works.

It all functions fairly well. There is a slight pause before the application runs.

Depending on your level of paranoia, you can add security keys and encode the files.

It is wise to use proven code. There is no point in reinventing wheels. Any bootloader must be 100% reliable.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If I follow you correctly, this can be done easily. If the BOOTRST fuse is programmed, the device will begin execution at the boot section address. Just put code in there to test the EEPROM, with a jump to address 0x0000 if the condition is not met.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the response but I am not finding it. I never have been much of an Arduino user. I just make my own stuff so I am not very familiar with their code archive. I went to the website, read the page on their bootloader and at the bottom was a link to a code archive for AVR DUDE. It said it was the bootloader but my understanding is that is not a bootloader rather a command line tool that interfaces with a bootloader to reload code. Any chance anyone out there has a link to just the bootloader code somewhere?

I have done some more snooping and it seems the real answer to my question is I need to build two different programs (a bootloader and my program) and smash together the HEX files manually and program that. Then set the fuses to always start at the bootloader.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So another way of asking it would be how do I make sure my real code is in the APP memory space not the bootloader space and vice versa without my bootloader yet? If I can keep my real code in a space outside the bootloader then it can be reflashed without disturbing the bootloader. One tutorial was saying just program on the bootloader and then use that for your code. Well I don’t have the HW yet for that. I am not using any standard interface for updating the code. I will be using something proprietary to load from. That is not yet designed. That is why I just want to do the framework now.

So really I just want to take 2 programs and smash them together (removing the end of file line in the APP hex) and program it into the boot space but I need to buffer it out to the next page. How do I buffer it out so I never erase the bootloader when updating?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Buy an Arduino. You can then see how it works.

Until you try it, you will not be familiar with the procedure.

Any bootloader needs some mechanism to determine whether you want to 'load' a new app or 'run' the existing app.
You can test a pin, wait for UART, input a special key, ...
No method is perfect. You just choose what will be most convenient for your punters (in your opinion)

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the advice but I really can't spend any money here. I know they are cheap and I personally have an old one at home that I purposefully trashed the bootloader on years ago when I was messing around with trying to use it my own way. I could reload that on mine and mess with it on my time but I really would rather do this on their time :) ... I have cool projects I am doing on my time.

In any case here at work I have a STK600 and a JTAGICE MKII, so I have enough tools to play around with. I just need to know how to force code into specific pages to isolate them so I can have it overwrite the APP not the bootloader.

But hey David you are correct...that would be the thing to do if I was playing around at home. I have only been at this place for 3 weeks and the last time I opened my mouth about spending any money was not a good thing :) I have the tools... I have been coding embeded systems for nearly 2 decades, just never a bootloader. I never had to care about forcing code into specific pages...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Optiboot, the most actively supported (cough) of the Arduino bootloads, can be found here: http://code.google.com/p/optiboot/

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wasn't that written by an AVRfreak?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I have only been at this place for 3 weeks

All the more reason to resurrect the Arduino that you have at home. i.e. you would see how a bootloader works in practice.

Yes, I see a lot of sense in porting a proven bootloader. At the same time, you read Bootloader Tutorials. e.g.
1. why a bootloader must be in a special area.
2. how to enable bootloader with fuses
3. how to protect bootloader with lockbits.
4. how you 'detect'. e.g. pin, UART, timeout, ...
5. how you invoke. e.g. avrdude, GUI, ...

If you understand all these subjects, your boss will be very pleased. He will be even more pleased if you use proven code.

Unless he thinks that he has just employed Einstein, he will not be expecting you to write something from scratch.

If he does think like this, you should change job.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I have searched the forum and there is a ton of stuff scattered all over but I have not found info I can use.

Not even this tutorial?

https://www.avrfreaks.net/index.p...

Quote:

So is there a special function like main() that the compiler knows about (perhaps bootloader()) that if I create it and set the fuses properly the system will not start at main() rather start in the bootloader start address and execute this function first?

You need to understand that when you use a bootloader your AVR will contain two almost totally unrelated programs. Each will have it's own main(). Each will be built separately. Each wil have it's own C startup and interrupt vector table code (though for the bootloader you may choose to suppress some of that to save space as it's unlikely you will use interrupts). Each will have it's own notion of what is located where in SRAM. It's possible the application may "borrow" some of the routines in the bootloader (say they both use UARTputchar/getchar() for example). The application may also share data with the bootloader though, on the whole, this should not be necessary and may be unwise. Bottom line: two programs, built as separate projects - the only time they might come together is if you join their .hex files to program them in just one ISP session (actually you kind of have to do this if you want app code in there from the start).
Quote:

So another way of asking it would be how do I make sure my real code is in the APP memory space not the bootloader space and vice versa without my bootloader yet?

The only way the two programs differ is that when you build the app code, like all programs you have written up to now you allow it to be built at the default location of 0x0000 in flash. The bootloader differs because you set the base address where it will be located to 0x3F00 or something (depending on AVR and boot section size). Other than that it's built like any other program. When you join their .hex files they don't "clash" because the booloader code has addresses way above the app code (or at least you hope it does - if the app is so big it encroaches into the bootloader area you have a problem!).
Quote:

I just need to know how to force code into specific pages to isolate them so I can have it overwrite the APP not the bootloader.

If you use AS6 (and hence avr-gcc) the "magic" to get the bootloader positioned at the high address is the linker command -Ttext= so you might add a linker command such as -Ttext=0x3F00 or whatever address your BOOTRST fuse is going to make the first opcode fetch at. AS6 even has a fancy "memories" dialog where you can just enter .text(flash)=0x1F80. If you wonder why 0x1F80 and not the 0x3F00 I've been using so far in my example it's because Atmel do everything in flash using 16bit "word" addressing. But everything in GCC is done in terms of 8bit "byte" addressing. So 0x3F00 / 2 = 0x1F80.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How should i connect USB to atmega? Should i use diode D1 and D2 if my atmega powered by 3,3V ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

amid_avr,

Why have you hijacked this thread? Your post has nothing to do with what is being discussed here.

(also a tiny2313 is not an "atmega", it is an "attiny"). The answer to your question is almost certainly on this page: http://vusb.wikidot.com/hardware

If you want to discuss this further do not continue this thread hijack but start a new thread.

Moderator

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks to everyone except amid_avr!

I really appreciate the clarification.

@Clawson thanks for the link. I did not find that one and I will review it today when I have a chance. As I stated before I understand I have to have two programs and smash them together. What I am really asking is HOW to set the base address of the bootloader to 0x03F00 (or where ever the start address is when you program the fusses) to run the bootloader first. *** I don’t know how to force code into specific memory maps. *** Which I think you addressed at the bottom of your response… THANKS I will play with that later today!

@david.prentice Thanks I do understand all of that stuff. I have worked on projects with bootloaders before but they were large enough projects I was on a team of developers and I did not work on the DFU stuff (just some debug when it failed). And yes my new boss is kind of testing me to see if I can pull together something he has wanted for some time but not been able to get anyone to do. This is really a “nice to have” not a needed thing but since my code is done and working and the HW is still not designed right (twice boards came in designed and assembled incorrectly) I might as well work on this. :D To be honest this product is a security device and this whole topic opens up a potential security hole and is probably why they never had one to begin with. So using a proven bootloader may not be desired or approved. This is a simple product that won’t get a lot of updates and none in the field. He is just trying to make things easier in the factory to enable changing things on the line without using a computer to reload code. They want the operators to be able to just plug in the encrypted key (key not designed yet) and have the code update. I haven’t worked here long enough to know how fast and loose these guys are running but this seems all a bit overkill for something we should never be doing.

Again Thanks Guys!!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@Clawson sorry but I was wrong I did view that PDF yesterday. It explains a bunch of stuff I already knew but I did not find a clear definition of how to force the code to the bootloader section in memory. Maybe it is there and because so much of it was so basic and obvious stuff I skimmed right by it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

wrong again I remember now (needs me some more coffee)...That doc explains it using a make file...which is the right way to do it but I had decided I am not going to make one just for this. I would rather do it manually for now. So that is when I posted my second post. I just want to force this manually for now.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't ever do things manually.

Add a specific target and method to your Makefile.
And remember to comment it.

Atmel have an appnote for an encrypted bootloader.
Use it. AFIK, there is no way to break it without a key.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you using AS6 or are you using Makefiles? As I say the key is the linker command -Ttext=0xNNNN. This is just a shorthand way for saying the more generic --section-start=.text=0xNNNN (section-start is what you can use to place ANY named section of code or data but the avr-ld linker also recgnises -Ttext, -Tdata as short-hand ways for placing .text and .data as they are such a common requirement.

The questions that then remain are (a) how do you get this command to the linker and (b) what is the value of 0xNNNN.

(a) differs between Makefiles and AS6. In Makefiles the easiest way is to add it to LDFLAGS with something like:

LDFLAGS += -Ttext=0xNNNN

In AS6 you have other options. I mentioned the Properties-Toolchain-AVR/GNU Linker-Memory Settings option above. Personally I don't like that way of doing it as this is one of those occasions (for me anyway) where the "IDE gets in the wya". I'd actually add it under AVR/GNU Linker-Miscellaneous in the text box there. I would add it as:

-Wl,-Ttext=0xNNNN

the reason for adding the -Wl on the front is that Atmel pass all commands to avr-gcc (the "compiler driver") and "-Wl," is the prefix that says what comes after this should be fed to the linker. This ensures it is avr-ld that gets to see the option.

I include two pictures below to show the BLS being set to byte address 0x3F00 below. Pick one.

(b) is dependent on the model of AVR you use and how big a boot section you want to use. A mega16, for example has four options for the bootloader. You pick the smallest one you can fit it into. That often means starting with the biggest, see how much code is actually generated and if it's not too big switching to a smaller one. The options are 256 bytes, 512 bytes, 1KiB, 2KiB. The base for these four would be 0x3F00, 0x3E00, 0x3C00, 0x3800. When you enablethe BOOTRST fuse you also set the two BOOTSZ fuse bits to one of four combinations to pick amongst these four options. When the AVR next poweres on it will make it's first opcode fetch from one of 0x3F00, 0x3E00, 0x3C00, 0x3800. Hopefully you will have ISP'd some bootloader code into it that matches that address.

Attachment(s): 

Last Edited: Thu. Aug 1, 2013 - 03:41 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not using a make file, that is the point...that is the reason for this thread. Otherwise the PDF file in the link above tells you everything you need. For right or wrong I am not going to be setting that up right now. I just want to know how to force the address map so I boot correctly into the loader. I mean if I just program on a loader how do I know it is going into the address pointed to when the fuses are set up for this?

After reading through the entire thread Clawson refered to what I would like to do is hard code boot routine addresses and the app start address for now. there were two concerns noted neither of which are relevant for my situation.

We also already have a complex rotating pseudo random encryption on our current key that I have to use, but thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

. I mean if I just program on a loader how do I know it is going into the address pointed to when the fuses are set up for this?

Did you see my pictures above (I edited them in so you may have missed it)?
Quote:
mean if I just program on a loader how do I know it is going into the address pointed to when the fuses are set up for this?

I just built this for a mega16 with a -Ttext=0x3F00:

#include 

int main(void) {
	while(1) {
	}	
}

the .hex file produced was as follows. I have edited it a bit to make the column with the destination addresses stand out:

:10 3F00 002DC0000033C0000031C000002FC00000F1
:10 3F10 002DC000002BC0000029C0000027C00000F9
:10 3F20 0025C0000023C0000021C000001FC0000009
:10 3F30 001DC000001BC0000019C0000017C0000019
:10 3F40 0015C0000013C0000011C000000FC0000029
:10 3F50 000DC000000BC0000009C0000011241FBEEE
:10 3F60 00CFEFD0E1DEBFCDBF02D002C0C9CFFFCFBF
:04 3F70 00F894FFCFF3
:0400000300003F00BA
:00000001FF

Hopefully you can see this is a "standard program" but that it starts at 0x3F00.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

THANKS CLAWSON!!!!!! I am yes unfortunatley using AS6. I have IAR at home but here at work I have to use AS6. What a drag...but free is hard to pass up right? And as of now I can't work from home :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You think IAR is better than AS6+avr-gcc? In what way? I've always found IAR to be quite impenetrable and under-featured for $3000. About the only thing in its favour is that its code generator is a little more efficient than all the other AVR compilers so if you are really scratching for bytes to downsize from the 32K to 16K chip and save $0.30 on that 1,000,000 unit production run the cost is justified - otherwise it isn't.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I use IAR. Last year or so, big improvements.
For me, much better than Eclipse.

I use IAR professionally, so the tool cost is far less important than the reliable combination of IAR and J-Link, plus flash breakpoints.
Good tools. Pay for themselves quickly. Just consider the fully burdened cost of an hour's labor, including overhead, G&A, fringe. Not many hours = $3000. I've used the same IAR license for like 5 years now. Just a few hundred $ a year for updates and support from people that answer the phone quickly and are erudite.

Not so for students. They're expected to flagellate! Build a house with a tack hammer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes but what are it's advantages over AS6+avr-gcc or CodeVision say? I see nothing but the slightly better code generation model and everything else just seems inferior. Clearly there must be some hidden gem in there but they are keeping it pretty well hidden!!