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

eqqqjvef  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(109)

我正在尝试学习AVR C,并且正在修补atmega 328 p微控制器。我正在使用Linux Mint上的avr-gcc工具链来编译并将代码闪存到Arduino板上。
所以我试着用函数调用来 Flink 两个LED灯。我做了两个函数-一个是 Flink LED连接到引脚7,另一个是 Flink LED连接到我的Arduino板的引脚13。
函数可以正常工作,但是当我修改代码时,我注意到一个奇怪的行为:函数在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板上时,连接到引脚13的LED Flink ,即使函数blinkPin7()被首先调用。我注意到函数的执行顺序总是对应于函数在main()外部定义的顺序,而不是从main()内部调用它们的顺序。
为什么会这样呢?

rxztt3cl

rxztt3cl1#

你的代码没有问题。但是你的Makefile不正确。

avr-gcc -o led.bin led.o

字符串
它不会在link stage中传递-mmcu=atmega328p。如果没有这个选项,你应该会得到这样的ld错误:

avr:103 architecture of input file `led.o' is incompatible with avr output


这意味着你没有一个目标微处理器。使用正确的链接器脚本,main()从地址0开始(重置向量),一切都可以正常工作。但是使用错误的链接器脚本,没有添加启动代码和中断向量表,无论什么函数首先出现,现在都将在地址0,并将按照你观察到的开始执行。
添加目标mcu可以解决问题:

avr-gcc -o led.bin led.o -mmcu=atmega328p

相关问题