为什么函数按照定义的顺序执行,而不是按照 avr-c 中 int main() 调用的顺序执行?

问题描述 投票:0回答:1

我正在尝试学习 AVR C,并且正在修补 atmega328p 微控制器。我正在 Linux Mint 上使用 avr-gcc 工具链来编译我的代码并将其刷新到 Arduino 板。

所以我尝试使用函数调用来闪烁两个 LED 灯。我制作了两个函数 - 一个用于连接到 Arduino 板的引脚 7 的闪烁 LED,另一个用于连接到 Arduino 板的引脚 13 的闪烁 LED。

这些功能正在运行,但是当我修改代码时,我注意到一个奇怪的行为。这些函数按照它们定义的顺序在 main() 之外被调用和执行;而不是按照从

int main()

 内部调用它们的顺序。

这是我的代码

#include <avr/io.h> #include <util/delay.h> void blinkPin13() { while(1) { DDRB = DDRB | (1 << DDB5); PORTB = PORTB | (1 << PORTB5); _delay_ms(5000); PORTB = PORTB & ~(1 << PORTB5); _delay_ms(500); } } void blinkPin7() { while(1) { DDRD = DDRD | (1 << DDD7); PORTD = PORTD | (1 << PORTD7); _delay_ms(1000); PORTD = PORTD & ~(1 << PORTD7); _delay_ms(500); } } int main(void) { blinkPin7(); blinkPin13(); return 0; }
这是用于编译和刷新代码的 makefile 

default: avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o led.o led.c avr-gcc -o led.bin led.o avr-objcopy -O ihex -R .eeprom led.bin led.hex sudo avrdude -F -V -c arduino -p ATMEGA328P -P /dev/ttyACM0 -b 115200 -U flash:w:led.hex
因此,当我将上述代码刷新到 Arduino 板时,即使首先调用函数 

blinkPin7()

,连接到引脚 13 的 LED 也会闪烁。我注意到函数的执行顺序始终对应于函数在 main() 外部定义的顺序,而不是对应于从 main() 内部调用函数的顺序。

为什么会这样?

c avr atmega avr-gcc
1个回答
0
投票
您的代码没有任何问题。但你的 Makefile 不正确。

avr-gcc -o led.bin led.o

链接阶段没有通过

-mmcu=atmega328p

。如果没有此选项,您应该会收到如下所示的 ld 错误:

avr:103 architecture of input file `led.o' is incompatible with avr output
意味着您没有目标 MCU。使用正确的链接器脚本,main() 从地址 0(重置向量)开始,一切都会正常工作。但是如果链接器脚本错误,那么现在首先出现的任何函数都将位于地址 0 处,并且将按照您观察到的情况开始执行。

添加目标 MCU 即可解决问题:

avr-gcc -o led.bin led.o -mmcu=atmega328p
    
© www.soinside.com 2019 - 2024. All rights reserved.