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 但您忘记列出任何其他对象。