avr-gcc 在另一个文件中时不编译中断
avr-gcc not compiling interrupts when they are in another file
我用 avr-gcc 为 ATMega328p 和一个简单的 ISR 做了一个简单的程序。问题是:当我将 ISR 放在外部 main.c 文件时,编译器不使用它。
原main.c:
#include <avr/interrupt.h>
int main()
{
while (1) {}
}
ISR(TIMER0_OVF_vect) {}
原始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>
现在看看这个main.c:
#include <interrupts.h>
extern ISR(TIMER0_OVF_vect);
int main()
{
while (1) {}
}
用这个 interrupts.h:
#ifndef INTERRUPTS_H
#define INTERRUPTS_H
#include <avr/interrupt.h>
ISR(TIMER0_OVF_vect);
#endif
和这个 interrupts.c:
#include <interrupts.h>
ISR(TIMER0_OVF_vect) {}
当我编译程序时,我得到了这个反汇编:
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>
我预想的结果和之前的代码反汇编是一样的,但是并没有像我预想的那样进行...
我正在用 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.
使用此 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
谁能帮我看看这是怎么回事?
提前致谢!
你的构建规则 main.elf
表明你实际上并没有链接到包含你的 ISR 的目标文件中,所以你不应该期望它包含在你的程序中。链接您的程序时,您必须提供包含要使用的二进制代码的所有对象和库的列表。您的列表包含 main.o
但您忘记列出任何其他对象。
我用 avr-gcc 为 ATMega328p 和一个简单的 ISR 做了一个简单的程序。问题是:当我将 ISR 放在外部 main.c 文件时,编译器不使用它。
原main.c:
#include <avr/interrupt.h>
int main()
{
while (1) {}
}
ISR(TIMER0_OVF_vect) {}
原始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>
现在看看这个main.c:
#include <interrupts.h>
extern ISR(TIMER0_OVF_vect);
int main()
{
while (1) {}
}
用这个 interrupts.h:
#ifndef INTERRUPTS_H
#define INTERRUPTS_H
#include <avr/interrupt.h>
ISR(TIMER0_OVF_vect);
#endif
和这个 interrupts.c:
#include <interrupts.h>
ISR(TIMER0_OVF_vect) {}
当我编译程序时,我得到了这个反汇编:
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>
我预想的结果和之前的代码反汇编是一样的,但是并没有像我预想的那样进行...
我正在用 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.
使用此 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
谁能帮我看看这是怎么回事?
提前致谢!
你的构建规则 main.elf
表明你实际上并没有链接到包含你的 ISR 的目标文件中,所以你不应该期望它包含在你的程序中。链接您的程序时,您必须提供包含要使用的二进制代码的所有对象和库的列表。您的列表包含 main.o
但您忘记列出任何其他对象。