avong
avong

Reputation: 31

Compiler Truncates Interrupts Vectors of ATmega328PB in Eclipse AVR Plugin

I would normally use Eclipse avr-gcc plugin and (avr-gcc compiler from zaks https://blog.zakkemble.net/avr-gcc-builds) to develop firmware for AVR MCU. The MCU ATmega328PB has extra timers (3,4), SPI1, TWI1 etc. I am experiencing situation where after compiling the code, any of these extra peripherals' interrupt vectors will not be handled, it does trauncate, the avr-gcc compiler only handles the default 25 vectors of the ATmega328P.

The eclipse avr-gcc (2.42) originally does not support ATmega328PB, I manually generated my header file from the iom328pb.h and also included the neccesary files as instructed here https://gist.github.com/goncalor/51e1c8038cc058b4379552477255b4e1

yet, whenever I configured any of these interrupts from the additional peripherals of the MCU, the interrupt would be registered as <__bad_interrupt>.

The question, how do I solve or does anyone knows a solution?

I tested TIMER3 and 4. I have configured TIMER3 and then TIMER4 OVERFLOW to generate 1ms on 16MHz Prescaler 64 and loaded TCNT3 = 65535-250/ TCNT4= 65535-250.

The interrupts refused to triger, and probing from the .lss file. It shows only the default vectors of ATmega328P.

Initially, I though it has to do with the way I renamed all interrupt vectors in my custome header file; which typically, TIMER1 and TIMER3 overflow vector are:

00000000 <__vectors>:
0:  38 c0           rjmp    .+112       ; 0x72 <__ctors_end>
2:  00 00           nop
4:  5e c0           rjmp    .+188       ; 0xc2 <__bad_interrupt>
6:  00 00           nop
8:  5c c0           rjmp    .+184       ; 0xc2 <__bad_interrupt>
a:  00 00           nop
c:  5a c0           rjmp    .+180       ; 0xc2 <__bad_interrupt>
e:  00 00           nop
10: 58 c0           rjmp    .+176       ; 0xc2 <__bad_interrupt>
12: 00 00           nop
14: 56 c0           rjmp    .+172       ; 0xc2 <__bad_interrupt>
16: 00 00           nop
18: 54 c0           rjmp    .+168       ; 0xc2 <__bad_interrupt>
1a: 00 00           nop
1c: 52 c0           rjmp    .+164       ; 0xc2 <__bad_interrupt>
1e: 00 00           nop
20: 50 c0           rjmp    .+160       ; 0xc2 <__bad_interrupt>
22: 00 00           nop
24: 4e c0           rjmp    .+156       ; 0xc2 <__bad_interrupt>
26: 00 00           nop
28: 4c c0           rjmp    .+152       ; 0xc2 <__bad_interrupt>
2a: 00 00           nop
2c: 4a c0           rjmp    .+148       ; 0xc2 <__bad_interrupt>
2e: 00 00           nop
30: 48 c0           rjmp    .+144       ; 0xc2 <__bad_interrupt>
32: 00 00           nop
34: 17 c5           rjmp    .+2606      ; 0xa64 <__vector_13>
36: 00 00           nop
38: 44 c0           rjmp    .+136       ; 0xc2 <__bad_interrupt>
3a: 00 00           nop
3c: 42 c0           rjmp    .+132       ; 0xc2 <__bad_interrupt>
3e: 00 00           nop
40: 40 c0           rjmp    .+128       ; 0xc2 <__bad_interrupt>
42: 00 00           nop
44: 3e c0           rjmp    .+124       ; 0xc2 <__bad_interrupt>
46: 00 00           nop
48: 79 c4           rjmp    .+2290      ; 0x93c <__vector_18>
4a: 00 00           nop
4c: 99 c4           rjmp    .+2354      ; 0x980 <__vector_19>
4e: 00 00           nop
50: 38 c0           rjmp    .+112       ; 0xc2 <__bad_interrupt>
52: 00 00           nop
54: bf c4           rjmp    .+2430      ; 0x9d4 <__vector_21>
56: 00 00           nop
58: 34 c0           rjmp    .+104       ; 0xc2 <__bad_interrupt>
5a: 00 00           nop
5c: 32 c0           rjmp    .+100       ; 0xc2 <__bad_interrupt>
5e: 00 00           nop
60: 30 c0           rjmp    .+96        ; 0xc2 <__bad_interrupt>
62: 00 00           nop
64: 2e c0           rjmp    .+92        ; 0xc2 <__bad_interrupt>

void __attribute__ ((__INTR_ATTRS))HTIM1_OVR_Handler(void) __asm__\
            ( "__vector_13" ) __attribute__\
            (( __signal__ , __used__ , __externally_visible__));

void __attribute__ ((__INTR_ATTRS))HTIM3_OVR_Handler(void) __asm__\
            ( "__vector_35" ) __attribute__\
            (( __signal__ , __used__ , __externally_visible__));

and in my application .c/.cpp file

void HTIM1_OVR_Handler(void){
  PORTB ^=(1<<5);
}

void HTIM3_OVR_Handler(void){
  PORTB ^=(1<<1);
}

I reverted to the traditional ISR(TIMER3_OVF_vect){ } and ISR(TIMER4_OVF_vect){ }, yet no changes. I tried the same code with the renamed vectors names in Atmel Studio 7, everything work fine.

Upvotes: 0

Views: 70

Answers (1)

emacs drives me nuts
emacs drives me nuts

Reputation: 3918

Flash address 0x64 is 100 i.e. __vector_25. If that's all of the vector table, then you are using a wrong startup code. Notice that ATmega32P has _VECTORS_SIZE of 104 (0x68, 26 vectors), whereas ATmega32PB has _VECTORS_SIZE of 180 (0xb4, 45 vectors).

So maybe you are linking with -mmcu=atmega328p instead of -mmcu=atmega328pb. But that's just guesswork as your commands are very secret.

To see what startup code is being linked, link with -v:

$ avr-gcc -v -mmcu=...
...
$prefix/libexec/gcc/avr/$version/collect2 ... $prefix/avr/lib/avr5/crtatmega328p.o ...

then check that the crt*.o has the vector table as expected.

Upvotes: 1

Related Questions