0

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.

1
  • What is aour linking command. What versions of the compiler are you using (2.42 is not a GCC version, and v4.7 is decades old). Also did you check the vector names against iom32*.h ? Also activate warnings, in particular -Wmisspelled-isr. Commented Aug 2, 2024 at 16:25

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.