logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

ATmega64A - Zawieszanie programu podczas wychodzenia z funkcji

sgt_ding 25 Wrz 2015 00:33 1071 4
REKLAMA
  • #1 15019036
    sgt_ding
    Poziom 15  
    Witam,
    w projekcie inżynierskim wykorzystuję m.in. mikrokontroler ATmega64A i właśnie z tym uC mam problem. Każda próba wywołania dowolnej funkcji powoduje jej zawieszenie (funkcja foo() się zapętla)... co najdziwniejsze ten sam przykładowy program skompilowany na ATmegę32 działa prawdłowo, a próba kompilacji z parametrem -mmcu=avr5 też nie przyniosła poprawy...

    Oto kod programu, który nie działa:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Korzystam z:
    Ubuntu 12.04 LTS
    avr-gcc-4.5.3 (testowałem też toolchain z avr-gcc-4.8.1)
    avr-libc 1.7.1
    avr-binutils 2.20.1
    Eclipse (tylko jako edytor, programy kompiluję z konsoli)

    Tutaj .lss (niestety assemblera nie za bardzo ogarniam, by doszukać się jakiś błędów):
    Kod: AVR assembler
    Zaloguj się, aby zobaczyć kod


    Tutaj makefile:
    
    # MCU name
    MCU = atmega64
    
    # Output format. (can be srec, ihex, binary)
    FORMAT = ihex
    
    # Target file name (without extension).
    TARGET = main
    
    # Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization.
    OPT = 1
    
    
    # List C source files here. (C dependencies are automatically generated.)
    SOURCE_DIR = src
    
    SRC	= \
    $(SOURCE_DIR)/main.c \
    
    # List Assembler source files here.
    ASRC = 
    
    
    # List any extra directories to look for include files here.
    EXTRAINCDIRS = 
    
    DEBUG_LEVEL=-g
    
    CFLAGS = -D GCC_MEGA_AVR -I. \
    -Iinclude \
    $(DEBUG_LEVEL) -O$(OPT) \
    -fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \
    $(WARNINGS) \
    -Wa,-adhlns=$(<:.c=.lst) \
    $(patsubst %,-I%,$(EXTRAINCDIRS))
    
    
    # Set a "language standard" compiler flag.
    CFLAGS += -std=gnu99
    
    # Optional assembler flags.
    ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs 
    
    
    
    # Optional linker flags.
    LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
    
    
    
    # Additional libraries
    LDFLAGS += -lm
    
    
    
    
    # Programming support using avrdude. Settings and variables.
    AVRDUDE_PROGRAMMER = stk500v2
    
    
    AVRDUDE_PORT = /dev/ttyUSB0	   # programmer connected to serial device
    
    AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
    #AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
    
    AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
    
    
    # ---------------------------------------------------------------------------
    
    # Define programs and commands.
    SHELL = sh
    
    CC = avr-gcc
    
    OBJCOPY = avr-objcopy
    OBJDUMP = avr-objdump
    SIZE = avr-size
    
    
    # Programming support using avrdude.
    AVRDUDE = avrdude
    
    
    REMOVE = rm -f
    COPY = cp
    
    HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
    ELFSIZE = $(SIZE) -A $(TARGET).elf
    
    
    
    # Define Messages
    # English
    MSG_ERRORS_NONE = Errors: none
    MSG_BEGIN = -------- begin --------
    MSG_END = --------  end  --------
    MSG_SIZE_BEFORE = Size before: 
    MSG_SIZE_AFTER = Size after:
    MSG_COFF = Converting to AVR COFF:
    MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
    MSG_FLASH = Creating load file for Flash:
    MSG_EEPROM = Creating load file for EEPROM:
    MSG_EXTENDED_LISTING = Creating Extended Listing:
    MSG_SYMBOL_TABLE = Creating Symbol Table:
    MSG_LINKING = Linking:
    MSG_COMPILING = Compiling:
    MSG_ASSEMBLING = Assembling:
    MSG_CLEANING = Cleaning project:
    
    
    
    
    # Define all object files.
    OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) 
    
    # Define all listing files.
    LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
    
    # Combine all necessary flags and optional flags.
    # Add target processor to flags.
    ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
    ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
    
    
    
    # Default target.
    all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \
    	$(TARGET).lss $(TARGET).sym sizeafter finished end
    
    
    # Eye candy.
    # AVR Studio 3.x does not check make's exit code but relies on
    # the following magic strings to be generated by the compile job.
    begin:
    	@echo
    	@echo $(MSG_BEGIN)
    
    finished:
    	@echo $(MSG_ERRORS_NONE)
    
    end:
    	@echo $(MSG_END)
    	@echo
    
    
    # Display size of file.
    sizebefore:
    	@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
    
    sizeafter:
    	@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
    
    
    
    # Display compiler version information.
    gccversion : 
    	@$(CC) --version
    
    
    
    
    # Convert ELF to COFF for use in debugging / simulating in
    # AVR Studio or VMLAB.
    COFFCONVERT=$(OBJCOPY) --debugging \
    	--change-section-address .data-0x800000 \
    	--change-section-address .bss-0x800000 \
    	--change-section-address .noinit-0x800000 \
    	--change-section-address .eeprom-0x810000 
    
    
    coff: $(TARGET).elf
    	@echo
    	@echo $(MSG_COFF) $(TARGET).cof
    	$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
    
    
    extcoff: $(TARGET).elf
    	@echo
    	@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
    	$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
    
    
    
    
    # Program the device.  
    program: $(TARGET).hex $(TARGET).eep
    	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
    
    
    
    
    # Create final output files (.hex, .eep) from ELF output file.
    %.hex: %.elf
    	@echo
    	@echo $(MSG_FLASH) $@
    	$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
    
    %.eep: %.elf
    	@echo
    	@echo $(MSG_EEPROM) $@
    	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
    	--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
    
    # Create extended listing file from ELF output file.
    %.lss: %.elf
    	@echo
    	@echo $(MSG_EXTENDED_LISTING) $@
    	$(OBJDUMP) -h -S $< > $@
    
    # Create a symbol table from ELF output file.
    %.sym: %.elf
    	@echo
    	@echo $(MSG_SYMBOL_TABLE) $@
    	avr-nm -n $< > $@
    
    
    
    # Link: create ELF output file from object files.
    .SECONDARY : $(TARGET).elf
    .PRECIOUS : $(OBJ)
    %.elf: $(OBJ)
    	@echo
    	@echo $(MSG_LINKING) $@
    	$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
    
    
    # Compile: create object files from C source files.
    %.o : %.c
    	@echo
    	@echo $(MSG_COMPILING) $<
    	$(CC) -c $(ALL_CFLAGS) $< -o $@
    
    
    # Compile: create assembler files from C source files.
    %.s : %.c
    	$(CC) -S $(ALL_CFLAGS) $< -o $@
    
    
    # Assemble: create object files from assembler source files.
    %.o : %.S
    	@echo
    	@echo $(MSG_ASSEMBLING) $<
    	$(CC) -c $(ALL_ASFLAGS) $< -o $@
    
    
    
    
    
    
    # Target: clean project.
    clean: begin clean_list finished end
    
    clean_list :
    	@echo
    	@echo $(MSG_CLEANING)
    	$(REMOVE) $(TARGET).hex
    	$(REMOVE) $(TARGET).eep
    	$(REMOVE) $(TARGET).obj
    	$(REMOVE) $(TARGET).cof
    	$(REMOVE) $(TARGET).elf
    	$(REMOVE) $(TARGET).map
    	$(REMOVE) $(TARGET).obj
    	$(REMOVE) $(TARGET).a90
    	$(REMOVE) $(TARGET).sym
    	$(REMOVE) $(TARGET).lnk
    	$(REMOVE) $(TARGET).lss
    	$(REMOVE) $(OBJ)
    	$(REMOVE) $(LST)
    	$(REMOVE) $(SRC:.c=.s)
    	$(REMOVE) $(SRC:.c=.d)
    
    
    # Automatically generate C source code dependencies. 
    # (Code originally taken from the GNU make user manual and modified 
    # (See README.txt Credits).)
    #
    # Note that this will work with sh (bash) and sed that is shipped with WinAVR
    # (see the SHELL variable defined above).
    # This may not work with other shells or other seds.
    #
    %.d: %.c
    	set -e; $(CC) -MM $(ALL_CFLAGS) $< \
    	| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \
    	[ -s $@ ] || rm -f $@
    
    
    # Remove the '-' if you want to see the dependency files generated.
    -include $(SRC:.c=.d)
    
    
    
    # Listing of phony targets.
    .PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \
    	clean clean_list program
  • REKLAMA
  • #2 15019128
    Andrzej__S
    Poziom 28  
    Nie widzę, żebyś gdzieś zdefiniował F_CPU, które jest wymagane przez 'delay.h', w związku z czym opóźnienia są obliczane dla częstotliwości 1MHz (podczas kompilacji powinieneś otrzymać ostrzeżenie). Jeśli w rzeczywistości mikrokontroler taktujesz np. częstotliwością 16MHz, to opóźnienia będą 16-krotnie krótsze (czyli ok. 31ms).

    Kod asm wygląda ok, czyli teoretycznie powinno działać (przy założeniu taktowania 1MHz).
    Jakie są objawy, na podstawie których uznałeś, że "funkcja foo() się zapętla"?
    Czy bez funkcji foo() program działa prawidłowo?
    Jakie komunikaty otrzymujesz podczas kompilacji i podczas programowania mikrokontrolera?
  • REKLAMA
  • #3 15019190
    sgt_ding
    Poziom 15  
    Zadeklarowanie F_CPU nie rozwiązuje problemu, który wg. mnie jest związany z wywoływaniem funkcji foo().

    Wgranie na uC (ATmega64) załączonego przeze mnie programu powoduje widoczne, ciągłe miganie diody na porcie C.0, dopiero usunięcie wywołania funkcji foo() powoduje przejście do pętli głównej, która jest wykonywana prawidłowo.

    Kompilacjia i wgrywanie programu z dodaną deklaracją F_CPU i zmianą <avr/delay.h> na <util/delay.h> przebiega prawidłowo (nie pojawiają się komunikaty o błędach, ostrzeżeniach, itp.), a błąd nadal występuje... oczywiście na atmedze32 wszystko działa...

    P.S.
    Program, który wrzuciłem na forum powstał w wyniku szukania błędu, który zawiesza mi uC, a jest na tyle prosty by bez zbędnego nakładu kodu pokazać mój problem.
  • REKLAMA
REKLAMA