Home > Enterprise >  avr-gcc not compiling interrupts when they are in another file
avr-gcc not compiling interrupts when they are in another file

Time:06-03

I did a SIMPLE program with avr-gcc for ATMega328p with a SIMPLE ISR. The issue is: when I put the ISR OUTSIDE main.c file the compiler doesn't use it.

The original main.c:

#include <avr/interrupt.h>

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

ISR(TIMER0_OVF_vect) {}

disassembly of original main.c:

bin/main.elf:     file format elf32-avr


Disassembly of section .text:

00000000 <__vectors>:
   0:   0c 94 35 00     jmp 0x6a    ; 0x6a <__ctors_end>
   4:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
   8:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
   c:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  10:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  14:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  18:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  1c:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  20:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  24:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  28:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  2c:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  30:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  34:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  38:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  3c:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  40:   0c 94 41 00     jmp 0x82    ; 0x82 <__vector_16>         <<<<<< LOOK THERE IS AN INTERRUPT!!
  44:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  48:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  4c:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  50:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  54:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  58:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  5c:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  60:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  64:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
    ...

0000006a <__ctors_end>:
  6a:   11 24           eor r1, r1
  6c:   1f be           out 0x3f, r1    ; 63
  6e:   cf ef           ldi r28, 0xFF   ; 255
  70:   d8 e0           ldi r29, 0x08   ; 8
  72:   de bf           out 0x3e, r29   ; 62
  74:   cd bf           out 0x3d, r28   ; 61
  76:   0e 94 4b 00     call    0x96    ; 0x96 <main>
  7a:   0c 94 4c 00     jmp 0x98    ; 0x98 <_exit>

0000007e <__bad_interrupt>:
  7e:   0c 94 00 00     jmp 0   ; 0x0 <__vectors>

00000082 <__vector_16>:            <<<<< THE INTERRUPT!!!
  82:   1f 92           push    r1
  84:   0f 92           push    r0
  86:   0f b6           in  r0, 0x3f    ; 63
  88:   0f 92           push    r0
  8a:   11 24           eor r1, r1
  8c:   0f 90           pop r0
  8e:   0f be           out 0x3f, r0    ; 63
  90:   0f 90           pop r0
  92:   1f 90           pop r1
  94:   18 95           reti

00000096 <main>:
  96:   ff cf           rjmp    .-2         ; 0x96 <main>

00000098 <_exit>:
  98:   f8 94           cli

0000009a <__stop_program>:
  9a:   ff cf           rjmp    .-2         ; 0x9a <__stop_program>

Now take a look at this main.c:

#include <interrupts.h>

extern ISR(TIMER0_OVF_vect);

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

with this interrupts.h:

#ifndef INTERRUPTS_H
#define INTERRUPTS_H
#include <avr/interrupt.h>
ISR(TIMER0_OVF_vect);
#endif

and this interrupts.c:

#include <interrupts.h>
ISR(TIMER0_OVF_vect) {}

when I compile the program, I get THIS disassembly:

bin/main.elf:     file format elf32-avr

Disassembly of section .text:

00000000 <__vectors>:
   0:   0c 94 35 00     jmp 0x6a    ; 0x6a <__ctors_end>
   4:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
   8:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
   c:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  10:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  14:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  18:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  1c:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  20:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  24:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  28:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  2c:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  30:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  34:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  38:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  3c:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  40:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>    <<<<<<< NO INTERRUPT!!!
  44:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  48:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  4c:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  50:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  54:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  58:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  5c:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  60:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
  64:   0c 94 3f 00     jmp 0x7e    ; 0x7e <__bad_interrupt>
    ...

0000006a <__ctors_end>:
  6a:   11 24           eor r1, r1
  6c:   1f be           out 0x3f, r1    ; 63
  6e:   cf ef           ldi r28, 0xFF   ; 255
  70:   d8 e0           ldi r29, 0x08   ; 8
  72:   de bf           out 0x3e, r29   ; 62
  74:   cd bf           out 0x3d, r28   ; 61
  76:   0e 94 41 00     call    0x82    ; 0x82 <main>
  7a:   0c 94 42 00     jmp 0x84    ; 0x84 <_exit>

0000007e <__bad_interrupt>:
  7e:   0c 94 00 00     jmp 0   ; 0x0 <__vectors>

00000082 <main>:
  82:   ff cf           rjmp    .-2         ; 0x82 <main>

00000084 <_exit>:
  84:   f8 94           cli

00000086 <__stop_program>:
  86:   ff cf           rjmp    .-2         ; 0x86 <__stop_program>

The result I expected is the same disassembly as the previous code, but it is not going on as I expected...

I am compiling the program with avr-gcc:

avr-gcc.exe (AVR_8_bit_GNU_Toolchain_3.6.2_1778) 5.4.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

With this Makefile:

CC      = avr-gcc
OBJCOPY = avr-objcopy
SIZE    = avr-size
DUMP    = avr-objdump
SRC_DIR = src
INC_DIR = inc
BIN_DIR = bin
OBJ_DIR = obj

SRCS = $(wildcard $(SRC_DIR)/*.c)
OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRCS))

# includes
INC  = -Iinc

# defines
DEF      = -D__AVR_ATmega328P__
DEF      = -DF_CPU=16000000UL

# cflags
CFLAGS   = -mmcu=atmega328p
CFLAGS   = -Wall
CFLAGS   = -Os

# ldflags
LDFLAGS = -Wl,-Tld\linker_script_atmega328p.ld,--cref

.PHONY: all clean dump flash

all: $(BIN_DIR)/main.bin

$(BIN_DIR)/main.bin: $(BIN_DIR)/main.elf
    $(OBJCOPY) -j .text -j .data -O binary $(BIN_DIR)/main.elf $(BIN_DIR)/main.bin
    $(SIZE) $(BIN_DIR)/main.elf

$(BIN_DIR)/main.elf: $(OBJS) | $(BIN_DIR)
    @$(CC) $(CFLAGS) $(OBJ_DIR)/main.o --output $@ $(LDFLAGS)

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
    $(CC) $(DEF) $(INC) $(CFLAGS) -c $< -o $@

$(BIN_DIR) $(OBJ_DIR):
    mkdir $@

clean:
    del /F /Q obj
    del /F /Q bin

dump: $(BIN_DIR)/dump.lst

$(BIN_DIR)/dump.lst: $(BIN_DIR)/main.elf
    $(DUMP) -d .text -d .data $(BIN_DIR)/main.elf > $(BIN_DIR)/dump.lst

flash: $(BIN_DIR)/main.bin
    avrdude -c usbasp -p m328p -U flash:w:"C:\avr_project\bin\main.bin":a 

Can someone help me what is going on?

Thanks in advance!

CodePudding user response:

Your rule for building main.elf shows you are not actually linking in the object file that contains your ISR, so you should not expect it to be included in your program. When linking your program, you must provide a list of all objects and libraries containing binary code that you want to use. Your list contains main.o but you forgot to list any other objects.

  • Related