我用 avr-gcc 為帶有 SIMPLE ISR 的 ATMega328p 做了一個簡單的程式。問題是:當我將 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
這會中斷.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
有人可以幫我怎么回事嗎?
提前致謝!
uj5u.com熱心網友回復:
您的構建規則main.elf表明您實際上并未在包含 ISR 的目標檔案中進行鏈接,因此您不應期望它包含在您的程式中。鏈接程式時,您必須提供包含要使用的二進制代碼的所有物件和庫的串列。您的串列包含main.o但您忘記列出任何其他物件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/485570.html
