I'm trying to write software for an ATtiny814 (tiny avr 1-series) microcontroller, but I encounter a strange problem: whatever the first function in main.c is, gets executed and the remaining code gets ignored - including the main()
function.
I'm using the avr-toolchain from the Arduino IDE on macOS, but I'm not using the IDE, I just added the bin/ directory of the avr-toolchain to the PATH variable. The code just compiles fine without errors or warnings. Using pyupdi I can successfully flash the program to the chip, and again it works fine - except that only code from the first function in the main.c is executed.
Makefile:
TARGET = project
CLOCK = 2000000 # configured in main
SOURCES = main.c
OBJECTS = $(SOURCES:.c=.o)
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(CLOCK) -D__AVR_DEVICE_NAME__=attiny814 -D__AVR_DEV_LIB_NAME__=tn814
# compiling and linking, target is the finished hex file
all: $(TARGET).hex
# compile source files to object files
.c.o:
$(COMPILE) -c $< -o $@
# link the object files together
$(TARGET).elf: $(OBJECTS)
$(COMPILE) $(OBJECTS) -o $(TARGET).elf
# convert elf file to hex file
$(TARGET).hex: $(TARGET).elf
avr-objcopy -O ihex -j .data -j .text $(TARGET).elf $(TARGET).hex
clean:
rm -f $(TARGET).hex $(TARGET).elf $(OBJECTS)
Example 1
main.c:
#include <avr/io.h>
void test1() {
// turn on PB1
PORTB.DIR |= PIN1_bm;
PORTB.OUT |= PIN1_bm;
}
int main() {
// disable protection to configure clock frequency
CCP = CCP_IOREG_gc;
// configure CPU frequency
CLKCTRL.MCLKCTRLA = CLKCTRL_CLKSEL_OSC20M_gc; // use 20 MHz internal clock as source
CLKCTRL.MCLKCTRLB = CLKCTRL_PDIV_10X_gc | CLKCTRL_PEN_bm; // divide by 10 and enable divider
// turn on PB0
PORTB.DIR |= PIN0_bm;
PORTB.OUT |= PIN0_bm;
// main program loop
while(1) {};
return 0;
}
Here, only test1()
is executed, as only PB1 turns on.
Example 2
main.c:
#include <avr/io.h>
// prototype
void test1();
int main() {
// disable protection to configure clock frequency
CCP = CCP_IOREG_gc;
// configure CPU frequency
CLKCTRL.MCLKCTRLA = CLKCTRL_CLKSEL_OSC20M_gc; // use 20 MHz internal clock as source
CLKCTRL.MCLKCTRLB = CLKCTRL_PDIV_10X_gc | CLKCTRL_PEN_bm; // divide by 10 and enable divider
// turn on PB0
PORTB.DIR |= PIN0_bm;
PORTB.OUT |= PIN0_bm;
// main program loop
while(1) {};
return 0;
}
void test1() {
// turn on PB1
PORTB.DIR |= PIN1_bm;
PORTB.OUT |= PIN1_bm;
}
Here, main()
gets skipped and again test1()
is executed, turning PB1 on.
Example 3
main.c:
#include <avr/io.h>
void test0() {
// turn on PB0
PORTB.DIR |= PIN0_bm;
PORTB.OUT |= PIN0_bm;
}
void test1() {
// turn on PB1
PORTB.DIR |= PIN1_bm;
PORTB.OUT |= PIN1_bm;
}
No main function at all. No compiler errors. Only test0()
gets executed and PB0 turns on.
I have no clue whats going on here. Btw, using the same avr-toolchain setup, I can write software for an ATtiny841 (it's a different architecture/series) as expected.
question from:
https://stackoverflow.com/questions/65647177/avr-attiny814-program-executes-first-function-ignoring-main 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…