Bootloader and Interrupts

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

I am trying to write an interrupt-driven bootloader. I plan to have ISRs for the UART (send and receive), and for SPM ready. I have read the avr-libc documentation on avr/interrupt.h and avr/boot.h, and I've also read the AVR documentation on bootloader support, but there are a few things I am still not sure about.

1) I am aware that the IVSEL bit is used to "move" the interrupt vector table from the application to the bootloader. Does this mean that I can have seperate ISRs for the same interrupt (e.g., have a UART receive ISR for the application and a seperate UART receive ISR in the bootloader)?

2) How do I tell avr-gcc that I want my ISR in the bootloader section? Simply adding the BOOTLOADER_SECTION macro to the end of the ISR declaration creates an error. I don't want my ISR to be erased during application re-programming!

Thanks in advance.

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

You build your bootloader and you app code as to entirely separate projects. Each will have it's own vector table but in the case of the bootloader project you'll have a linker commad to relocate the .text to the start of BLS address and, because it will have a vector table of its own at the start of .text then this will arrange for the AVR to end up with two vector tables in it. One from the boot project and one from the app project. This will involve you having two .elf files andtwo .hex files. If you want to program the AVR in one go then use srecord or some other Intel Hex aware program to merge the two .hex files together before you ISP/JTAG it into the chip.

Do not consider using BOOTLOADER_SECTION for this. That is for an app that just wants to add some flash programming routines and therefore arrange for them to be relocated to the BLS (by moving .bootloader) but for a true bootloader you should build in two unconnected halves (which makes sense because in future you will be building/delivering new versions of the main app code and you don't want a copy of the boot stuff bolted onto the end of that!)

Cliff

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

Why when I want to change the IVSEL bit, it doesn't work :

MCUCR |= (1<<IVCE);
MCUCR |= (1<<IVSEL);

Finally, the interrupt vector select is only "Start of application section"

I'm using :
- AVR Studio 4.13.528
- WinAVR 20070122
And there are two differents projects :
-Bootloader (I'm moving .text)
-Application

For the moment, only interrupt doesn't work ...

Thanks for any help ...

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

Normally when the "make two writes to the same register in quick succession" thing doesn't work it's because the code is being built -O0 rather than -Os and the timing constraint is not being met. What does your .lss show for those two instructions and are you building -O0? (if you use Studio as an IDE you probably are!)

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

Thanks you for your help !!!
In fact, it works very well with -O1 !

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

There is 4 instructions for each instruction when optimization is -O0 ...

MCUCR = (1<<IVCE);   
 1e0ea:	e5 e5       	ldi	r30, 0x55	; 85
 1e0ec:	f0 e0       	ldi	r31, 0x00	; 0
 1e0ee:	81 e0       	ldi	r24, 0x01	; 1
 1e0f0:	80 83       	st	Z, r24
MCUCR = (1<<IVSEL);  
 1e0f2:	e5 e5       	ldi	r30, 0x55	; 85
 1e0f4:	f0 e0       	ldi	r31, 0x00	; 0
 1e0f6:	82 e0       	ldi	r24, 0x02	; 2
 1e0f8:	80 83       	st	Z, r24