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.