"Unhandled exception" code conflicting with bootlo

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

Hi,

I believe that I've kinda got the hang of placing a bootloader in the AVR32 bootloader area. But I have a problem with an instruction at 0x80000000 that skips the bootloader, and jumps directly into my main code.

Disassembly of section .reset:

80000000 <_start>:
_evba:

        .org  0x000
        // Unrecoverable Exception.
_handle_Unrecoverable_Exception:
        rjmp $
80000000:	48 1f       	lddpc	pc,80000004 <_start+0x4>
80000002:	00 00       	add	r0,r0
80000004:	80 00       	ld.sh	r0,r0[0x0]
80000006:	20 24       	sub	r4,2

80000008 :

This looks like some interrupt stuff, but where does it come from? I really use a minimum of files here. Of the source files that I haven't made myself, I only use intc.c, intc.h and exception.S. And then the header files that intc.c uses.

I've placed the .exception section elsewhere, and expect all exception related stuff to end up there. And it kinda looks like it does:

Disassembly of section .exception:

80010000 <_evba>:
80010000:	c0 08       	rjmp	80010000 <_evba>
80010002:	00 00       	add	r0,r0

80010004 <_handle_TLB_Multiple_Hit>:

        .org  0x004
        // TLB Multiple Hit: UNUSED IN AVR32UC.
_handle_TLB_Multiple_Hit:
        rjmp $
80010004:	c0 08       	rjmp	80010004 <_handle_TLB_Multiple_Hit>
80010006:	00 00       	add	r0,r0

80010008 <_handle_Bus_Error_Data_Fetch>:
...

So those first four "instructions", where do they come from? And how do I make them go away?

I've placed the different sections by adding this to the makefile:

LDFLAGS += -Wl,--section-start=.reset=0x80000000
LDFLAGS += -Wl,--section-start=.init=0x80002000
LDFLAGS += -Wl,--section-start=.text=0x80002022
LDFLAGS += -Wl,--section-start=.exception=0x80010000

Yes, you may scold me. But similar stuff works great for me in the 8-bit megas and xmegas.

By the way, I'm using an EVK1101 with a UC3B0256. Not that I think it matters, though.

Br, E

You're absolutely right. This member is stupid. Please help.

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

ErikT wrote:
But I have a problem with an instruction at 0x80000000 that skips the bootloader, and jumps directly into my main code.

Disassembly of section .reset:

80000000 <_start>:
_evba:

        .org  0x000
        // Unrecoverable Exception.
_handle_Unrecoverable_Exception:
        rjmp $
80000000:	48 1f       	lddpc	pc,80000004 <_start+0x4>
80000002:	00 00       	add	r0,r0
80000004:	80 00       	ld.sh	r0,r0[0x0]
80000006:	20 24       	sub	r4,2

80000008 :

This looks like some interrupt stuff, but where does it come from?

ErikT wrote:
So those first four "instructions", where do they come from? And how do I make them go away?
The first 8 bytes (2 bytes lddpc instruction, 2 bytes padding, 4 bytes start address) are called "trampoline", which is used when there's no booloader present. It always gets linked at 0x8000 0000 and cannot be moved. The comment in there is misplaced source code from exception.S.

To get rid of it, remove the trampoline. Removing "-Wl,-e,_trampoline" from the compiler call should do the trick.

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

Quote:
To get rid of it, remove the trampoline. Removing "-Wl,-e,_trampoline" from the compiler call should do the trick.

Hmmm... unfortunately, that is not included in the makefile.

This is linker stuff, right? The linker call looks like this:

avr32-gcc -o AVR32interbusBoot.elf obj/AVR32interbusBoot.o obj/intc.o obj/InterbusMaster.o  obj/exception.o  -Wl,-Map=AVR32interbusBoot.map,--start-group -lm -Wl,--end-group -Wl,--gc-sections --rodata-writable -Wl,--direct-data -mpart=uc3b0256     -lm -Wl,--section-start=.reset=0x80000000 -Wl,--section-start=.init=0x80002000 -Wl,--section-start=.text=0x80002022 -Wl,--section-start=.exception=0x80010000

Just in case it could be interesting, the compiler call looks like this:

avr32-gcc -c -mpart=uc3b0256 -DDEBUG -DF_CPU=60000000UL -O1 -ffunction-sections -masm-addr-pseudos -g3 -funsigned-char -funsigned-bitfields -Wall -Wstrict-prototypes -Wno-char-subscripts -Wno-pointer-sign  -std=gnu99 -MD -MP -MF .dep/AVR32interbusBoot.d -MT.dep/AVR32interbusBoot.d -MTobj/AVR32interbusBoot.o -o obj/AVR32interbusBoot.o AVR32interbusBoot.c

I'll get started (once more) with the gcc manual, and maybe some day I'll understand the majority of this gibberish. :wink:

You're absolutely right. This member is stupid. Please help.

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

Basically the trampoline mechanism is a good thing. It makes it possible to debug your application without the existence of a bootloader.

Imho the best solution is to use srecord in a script like gen_uc3.sh
from the usb mass storage example:
http://www.atmel.com/Images/avr3...
if you finally need both merged together (without trampoline), the bootloader + the application.

-sb

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

I don't like the sound of that. What I understand from your post is that I cannot get rid of the trampoline, even if I want to. Is that correct? I hoped that there would be a linker option for removing the trampoline, but that doesn't seem to be the case.

For several years, we've compiled the bootloaders as part of the firmwares (for mega and xmega), and it has never created problems. It isn't even difficult to do - once you've figured out how, that is.

I would very much like to do the same thing with the AVR32, but that might not be possible.

Cropping and merging hex files is of course a possibility, but seems to me to be a very awkward workaround for eight silly bytes.

As an alternative, I guess I could write the bootloader as a separate program, upload that with the programmer, and then use the bootloader to upload the main program. Not exactly a smooth operation in production.

Br, ErikT

You're absolutely right. This member is stupid. Please help.

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

I just noticed that the trampoline documentation was already linked for you in this thread over two weeks ago.

The application note mentioned by gchapman explains the trampoline pretty well, IMO, including how to get rid of it. Is anything mentioned there not working for you?

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

exactly, it should be quite easy to get rid of trampoline.

using a script + srecord to manage your flash layout is not a workaround for an existing trampoline. it's a save and reproduceable way to manage developer's and integrator's daily tasks (e.g. for updating your target and in special for manufacturing purpose).

-sb

PS.: a "workaround" would be to first flash the application and overwrite it's trampoline code with the bootloader in a second step.

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

Somehow, my long response wasn't registered.

Anyway, I think I'm giving up on the AVR32. I can make everything work (of the stuff I've tried) except bootloading stuff. And that is the showstopper.

I know that merging hex files is a common and accepted way to combine bootloader and application. What I don't understand is why everybody (except me) seem to think that it is such a great idea. With the mega and the xmega, it is completely unnecessary.

You're absolutely right. This member is stupid. Please help.

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

Somehow, since you seem to be immune to feedback.

consider to read again the "Adding or Removing the Trampoline" chapter from
www.atmel.com/images/doc7745.pdf

You claim to be able to handle makefiles - if you need to remove some assembler code from your project, why don't you just do it?

-sb

PS.: mega and xmega stories are out of topic in this forum

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

Again, I wrote a lengthy reply, which disappeared the moment I clicked "Submit". What on Earth is happening here??? I'll try again in a moment.

You're absolutely right. This member is stupid. Please help.

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

sambrown wrote:
consider to read again the "Adding or Removing the Trampoline" chapter from
www.atmel.com/images/doc7745.pdf

I did. More than once. Doesn't help.

Quote:
The trampoline can be removed from a GCC or IAR project to reallocate the size of the bootloader for the application. This can be achieved by removing the trampoline assembler source file from the project and by removing the program entry point override.

I'm not using trampoline.S. It is not present in the project, and not mentioned in the makefile. So removing that is quite a challenge.

If I remove the program entry point override, there will be no room for the bootloader.

Funny thing is, that if I take a close look at the .lss file from a project where I do not define specific sections in the makefile, I get the exact same beginning (although with a different destination, obviously):

Disassembly of section .reset:

80000000 <_start>:
_evba:

        .org  0x000
        // Unrecoverable Exception.
_handle_Unrecoverable_Exception:
        rjmp $
80000000:	48 1f       	lddpc	pc,80000004 <_start+0x4>
80000002:	00 00       	add	r0,r0
80000004:	80 00       	ld.sh	r0,r0[0x0]
80000006:	00 24       	rsub	r4,r0

Disassembly of section .init:

80000008 <_init>:
80000008:	eb cd 40 40 	pushm	r6,lr
8000000c:	48 26       	lddpc	r6,80000014 <_init+0xc>
8000000e:	1e 26       	rsub	r6,pc
80000010:	c0 48       	rjmp	80000018 <_init+0x10>
80000012:	00 00       	add	r0,r0
80000014:	7f ff       	ld.w	pc,pc[0x7c]
80000016:	ff f6 f0 16 	ld.wal	r6,pc[0x58]
8000001a:	00 01       	add	r1,r0
8000001c:	f0 16 00 00 	mcall	r6[0]
80000020:	e3 cd 80 40 	ldm	sp++,r6,pc

Disassembly of section .text:

80000024 <_stext>:
80000024:	30 07       	mov	r7,0
80000026:	49 5a       	lddpc	r10,80000078 <_stext+0x54>

So again, my conclusion is that what I'm trying to do is just not possible. And that's OK, because then I don't need to waste more time trying.

I don't claim to to be able to "handle" makefiles as such, although I know how they work, and I know some of what is going on in them. But I started working with avr-gcc at a time when there was really no other way. And I still think this way is better than using a slow and bulky IDE. But maybe that's just me...

You're absolutely right. This member is stupid. Please help.

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

ok, using make instead of a fancy but unclear IDE build systems is a good idea at this point (and in general, too), but it would really help if you post the makefile that get's actually used + your resulting verbose build output.

I'm a little bit confused at this point.
are we talking about the bootloader project here, or about the application?

as explained above, for the app I prefer to use trampline instead of manipulating the entry point in the linker script. of course you will need to merge the resulting "free space" with the bootloader code or use the workaround of reverse flashing.

if you're talking about the bootloader (I assume, your project is based on the quite outdated dfu project from asf 1.7) then you must remove the trampoline and may try to use the following linker options:

# Extra flags to use when linking
LDFLAGS = \
    -Wl,--gc-sections -nostartfiles -Wl,--direct-data

of course you will need some assembler startup code that get's linked to the .reset section there, so there must exist one assembler file in your bootloader makefile for that!

-sb

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

sambrown wrote:
I'm a little bit confused at this point.
are we talking about the bootloader project here, or about the application?

Originally, we were talking about both, because I thought I could integrate the bootloader into the application. That idea has now been rejected, so now the main issue is the application. That is, having the application moved outside the bootloader area. So I guess I'll have a go at trampoline.S once more. If I can make that reserve the flash area from 80000000 to 80001FFF, I'l be happy.

I just tried adding -nostartfiles to the linker, just to see what happened. The contents of my application disappeared, and the flash was empty.

Anyway, here is the compile result with the makefile in the form that does work:

Compiling C: AVR32interbusBoot.c
avr32-gcc -c -mpart=uc3b0256 -DDEBUG -DF_CPU=60000000UL -O1 -ffunction-sections -masm-addr-pseudos -g3 -funsigned-char -funsigned-bitfields -Wall -Wstrict-prototypes -Wno-char-subscripts -Wno-pointer-sign  -std=gnu99 -MD -MP -MF .dep/AVR32interbusBoot.d -MT.dep/AVR32interbusBoot.d -MTobj/AVR32interbusBoot.o -o obj/AVR32interbusBoot.o AVR32interbusBoot.c
AVR32interbusBoot.c: In function 'IBusRx':
AVR32interbusBoot.c:294: warning: unused variable 'TempBuf'
AVR32interbusBoot.c:286: warning: unused variable 'uiTemp'

Linking: AVR32interbusBoot.elf
avr32-gcc -o AVR32interbusBoot.elf obj/AVR32interbusBoot.o obj/intc.o obj/InterbusMaster.o  obj/exception.o  -Wl,-Map=AVR32interbusBoot.map -Wl,--start-group -lm -Wl,--end-group -Wl,--gc-sections --rodata-writable -Wl,--direct-data -mpart=uc3b0256     

Creating load file for Flash: AVR32interbusBoot.hex
avr32-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature AVR32interbusBoot.elf AVR32interbusBoot.hex

Creating load file for EEPROM: AVR32interbusBoot.eep
avr32-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
	--change-section-lma .eeprom=0 --no-change-warnings -O ihex AVR32interbusBoot.elf AVR32interbusBoot.eep || exit 0

Creating Extended Listing: AVR32interbusBoot.lss
avr32-objdump -h -S -z AVR32interbusBoot.elf > AVR32interbusBoot.lss

Creating Symbol Table: AVR32interbusBoot.sym
avr32-nm -n AVR32interbusBoot.elf > AVR32interbusBoot.sym

Size after:
   text	   data	    bss	    dec	    hex	filename
   5844	   1320	   5156	  12320	   3020	AVR32interbusBoot.elf

-------- end --------

I have attached the makefile. I've added a .txt extension - otherwise I couldn't attach it. As you may see, it is an older makefile which I modified to work with AVR32. I used the output from AS6 as a reference, so some of the stuff that I have added (mainly linker options) is there simply because it was present in AS6. I know. Eyes wide shut...

I'll have a further look at trampoline.S.

Attachment(s): 

You're absolutely right. This member is stupid. Please help.

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

Getting trampoline.S working as intended proved to be no trouble at all. So now that I've accepted that the bootloader and the application should be two different things (that was probably the hardest part), I believe I am good to go.

Thank you for putting up with my hardheadedness! :)

When I have a simple application and a bootloader working, I'll post it somewhere around here.

You're absolutely right. This member is stupid. Please help.

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

good to hear about your progress :-)

and good idea to accept that the bootloader should be handled as a separate, independent project.

It's worth to have a look at the mass storage bootloader's startup code,
Atmel provides in http://www.atmel.com/Images/avr3...

it checks at startup for a pattern in user flash to decide if the application can be started directly or if the bootloader's c-runtime should be launched.

a good solution for switching between the bootloader and the app is to write/reset this pattern followed by a watchdog reset.

there do exist a bunch of threads in this forum that discuss this procedure, including sample code. good luck!

-sb

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

Thanks a lot.

I'm used to using some dedicated EEPROM addresses for the bootloader to decide whether to start the application, or to ask for new firmware. And to report what went wrong in case of a failed upload. But obviously, that is not an option in the AVR32. I'll get some inspiration from the startup code in avr32758.

Br, E

You're absolutely right. This member is stupid. Please help.