mikrocontroller.net

Forum: Compiler & IDEs AVR-GCC-Eclipse: printf("H") klappt, printf("Ha") klappt nicht!


Autor: Tobias H. (the)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe bisher kleinere Programme mit AVR-Studio progammiert und möchte 
nun auf Eclipse umsteigen (AVR-Plugin).

Da GANZ einfache Programme schnell zum Laufen zu bekommen waren, habe 
ich nun ein kleines Programm geschrieben, dass in einer Endlosschleife 
Buchstaben auf ein RS232-Terminal ausgibt.

Und jetzt kommt das Problem:
Mit dem von Eclipse erzeugten HEX-File funktioniert die Ausgabe von 
EINZELBUCHSTABEN mit printf("H") (beispielsweise) problemlos (natürlich 
auch in ARV-Studio).
Ändere ich diese Ausgabe in printf("Ha") (also mehrere Buchstaben) 
klappt es unter Eclipse NICHT MEHR, unter AVR-Studio schon.

Der C-Code ist (natürlich) in beiden Fällen gleich!

Daher kann es eigentlich nur an den (diversen) IDE-Einstellungen liegen 
[dieses Problem hat man ja eigentlich immer, wenn man die IDE wechselt].

Was mir auffällt ist, dass Eclipse mit avr-g++ kompiliert (obwohl mein 
Program unter Main.c gespeichert ist) und AVR-Studio mit avr-gcc (wobei 
ich noch nicht sehe, wo dabei das Problem sein könnte).

Vielleicht kann einer von Euch mir da weiter helfen? Anbei findet Ihr 
die beiden Makefiles.

Lieben Dank!

P.S.: Sorry für den langen Anhang aber ich war irgendwie nicht in der 
Lage, zwei Dateien anzuhängen... und auf das Entpacken eines .zip hat 
wahrscheinlich keiner Lust ;-)

Eclipse_makefile:
################################################################################
# Automatically-generated file. Do not edit!
################################################################################

-include ../makefile.init

RM := rm -rf

# All of the sources participating in the build are defined here
-include sources.mk
-include subdir.mk
-include source/subdir.mk
-include objects.mk

ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(C++_DEPS)),)
-include $(C++_DEPS)
endif
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
ifneq ($(strip $(ASM_DEPS)),)
-include $(ASM_DEPS)
endif
ifneq ($(strip $(CC_DEPS)),)
-include $(CC_DEPS)
endif
ifneq ($(strip $(CPP_DEPS)),)
-include $(CPP_DEPS)
endif
ifneq ($(strip $(S_DEPS)),)
-include $(S_DEPS)
endif
ifneq ($(strip $(CXX_DEPS)),)
-include $(CXX_DEPS)
endif
ifneq ($(strip $(C_UPPER_DEPS)),)
-include $(C_UPPER_DEPS)
endif
ifneq ($(strip $(S_UPPER_DEPS)),)
-include $(S_UPPER_DEPS)
endif
endif

-include ../makefile.defs

# Add inputs and outputs from these tool invocations to the build variables 
LSS += \
AVR_COBOLT.lss \

FLASH_IMAGE += \
AVR_COBOLT.hex \

EEPROM_IMAGE += \
AVR_COBOLT.eep \

SIZEDUMMY += \
sizedummy \


# All Target
all: AVR_COBOLT.elf secondary-outputs

# Tool invocations
AVR_COBOLT.elf: $(OBJS) $(USER_OBJS)
  @echo 'Building target: $@'
  @echo 'Invoking: AVR C++ Linker'
  avr-g++ -Wl,-Map,AVR_COBOLT.map,--cref -Wl,-u,vfprintf -lprintf_flt -lm -lc -lm -L"C:\WinAVR-20081205\avr\lib\avr6" -mmcu=atmega640 -o"AVR_COBOLT.elf" $(OBJS) $(USER_OBJS) $(LIBS)
  @echo 'Finished building target: $@'
  @echo ' '

AVR_COBOLT.lss: AVR_COBOLT.elf
  @echo 'Invoking: AVR Create Extended Listing'
  -avr-objdump -h -S AVR_COBOLT.elf  >"AVR_COBOLT.lss"
  @echo 'Finished building: $@'
  @echo ' '

AVR_COBOLT.hex: AVR_COBOLT.elf
  @echo 'Create Flash image (ihex format)'
  -avr-objcopy -R .eeprom -O ihex AVR_COBOLT.elf  "AVR_COBOLT.hex"
  @echo 'Finished building: $@'
  @echo ' '

AVR_COBOLT.eep: AVR_COBOLT.elf
  @echo 'Create eeprom image (ihex format)'
  -avr-objcopy -j .eeprom --no-change-warnings --change-section-lma .eeprom=0 -O ihex AVR_COBOLT.elf  "AVR_COBOLT.eep"
  @echo 'Finished building: $@'
  @echo ' '

sizedummy: AVR_COBOLT.elf
  @echo 'Invoking: Print Size'
  -avr-size --format=avr --mcu=atmega640 AVR_COBOLT.elf
  @echo 'Finished building: $@'
  @echo ' '

# Other Targets
clean:
  -$(RM) $(OBJS)$(C_DEPS)$(EEPROM_IMAGE)$(ELFS)$(FLASH_IMAGE)$(LSS)$(S_DEPS)$(CXX_DEPS)$(S_UPPER_DEPS)$(C++_DEPS)$(ASM_DEPS)$(CC_DEPS)$(CPP_DEPS)$(C_UPPER_DEPS)$(SIZEDUMMY) AVR_COBOLT.elf
  -@echo ' '

secondary-outputs: $(LSS) $(FLASH_IMAGE) $(EEPROM_IMAGE) $(SIZEDUMMY)

.PHONY: all clean dependents
.SECONDARY:

-include ../makefile.targets


AVR-Studio_makefile:
###############################################################################
# Makefile for the project AVR_COBOLT
###############################################################################

## General Flags
PROJECT = AVR_COBOLT
MCU = atmega640
TARGET = AVR_COBOLT.elf
CC = avr-gcc

## Options common to compile, link and assembly rules
COMMON = -mmcu=$(MCU)

## Compile options common for all C compilation units.
CFLAGS = $(COMMON)
CFLAGS += -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d 

## Assembly specific flags
ASMFLAGS = $(COMMON)
ASMFLAGS += $(CFLAGS)
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2

## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS +=  -Wl,-Map=AVR_COBOLT.map


## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature

HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings


## Libraries
LIBS = -lm 

## Objects that must be built in order to link
OBJECTS = Main.o 

## Objects explicitly added by the user
LINKONLYOBJECTS = 

## Build
all: $(TARGET) AVR_COBOLT.hex AVR_COBOLT.eep AVR_COBOLT.lss size

## Compile
Main.o: ../Main.c
  $(CC) $(INCLUDES) $(CFLAGS) -c  $<

##Link
$(TARGET): $(OBJECTS)
   $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)

%.hex: $(TARGET)
  avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@

%.eep: $(TARGET)
  -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0

%.lss: $(TARGET)
  avr-objdump -h -S $< > $@

size: ${TARGET}
  @echo
  @avr-size -C --mcu=${MCU} ${TARGET}

## Clean target
.PHONY: clean
clean:
  -rm -rf $(OBJECTS) AVR_COBOLT.elf dep/* AVR_COBOLT.hex AVR_COBOLT.eep AVR_COBOLT.lss AVR_COBOLT.map


## Other dependencies
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)

Autor: Michael Haberler (mah)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und wo ist das Program, Ha?

-Michael

Autor: Tobias H. (the)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, dachte, dass interessiert niemanden, da es ja in beiden Fällen 
identisch ist...

Aber kein Problem, kommt.

Danke schonmal für die schnelle Antwort!
// ============================ USART-Test for ATmega48 on STK500 valuation-board ===

#ifndef F_CPU
#define F_CPU 4000000 //Quarz frequency in Hz. Insert actual value!!
#endif

#include <stdio.h>

//our own inlcude files:
#include "Usart.h"
#include "I2c.h"
#include "Adc.h"

// ===============================================================
//  BEGIN OF MAIN PROGRAMM
// ===============================================================

int main(void)
{
  stdin = stdout = fdevopen(usartPutc, usartGetcNowait);
  usartInit();
  adcInit();

  DDRJ = 0xFF;
  PORTJ = 0xFF;

  //to give some visible feedback to the user, that the software update was successful:
  //TODO: Extract the following to a function inside GeneralAtmelMcu.h
  _delay_ms(1000);
  PORTJ = 0x00;
  _delay_ms(1000);
  PORTJ = 0x01;

  while(1) {
    printf("Ha");
    _delay_ms(10);
    //printf("Hallo Welt!");
  }

  return 0;
}

Autor: Michael Haberler (mah)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
einmal gehts noch - usart.h bitte. Und woher sind usartPutc & 
usartGetcNowait?

Ihr erwartet immer Hilfe und benehmt Euch dabei wie verlegene 
Verdächtige, denen man erstmal die Tatsachen abpressen muss..

-mah

Autor: Nicolas S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann das usartPutc ganze Strings oder nur chars ?

Autor: Tobias H. (the)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
;-)

Ich habe gar kein schlechtes Gewissen! Denke nur (nach wie vor), dass 
der Fehler nicht im CODE liegen kann, da es ja im AVR-Studio läuft, nur 
halt unter Eclipse nicht => Makefile-Unterschiede.

Aber klar, könnt Ihr den Code sehen:
#ifndef USART_H
#define USART_H

//TODO: Add comments for this class

#include <avr/interrupt.h>

#include "GeneralAtmelMcu.h"
#include "ErrorHandling.h"


// ================== Definitions for UART ================================
// from   uart.h ==========


#define UART_BAUD_RATE 9600L
#define UART_BAUD_CALC ((F_CPU)/((UART_BAUD_RATE)*16L)-1)

#define RING_BUFFER_LENGTH 20 //bufferlength for serial receive  /  Pufferlänge für seriellen Empfang


volatile unsigned char ringBuffer[RING_BUFFER_LENGTH];    // Ringbuffer
volatile uint8_t
                 ringBufferPosition,   // Position to read next / die als nächstes gelesen werden muß im Ringpuffer
             ringBufferCounter,   // Number of Char to read / Anzahl zu lesender Zeichen im Puffer
             udrData;   // Data from UART / Daten aus dem UART
                    // (volatile, to prevent removal by opimizer / Präprozessor)






void usartInit()
{
  /* Set baud rate */
  UBRR1H = (unsigned char)(UART_BAUD_CALC>>8);
  UBRR1L = (unsigned char) UART_BAUD_CALC;

  /* Enable receiver and transmitter */
  UCSR1B =  (1<<TXEN1);   // UART TX (send) enable
  UCSR1B |= (1<<RXEN1);   // UART RX (receive) enable
  UCSR1B |= (1<<RXCIE1);  // Interrupt on receive enable
  sei();                  // enable global Interrupt

    /* Set frame format: 8data, 2stop bit */
    UCSR1C = (1<<USBS1)|(3<<UCSZ10);
}



// send ONE character  // Ein Zeichen senden
int16_t usartPutc(char c, FILE* notused)
{
    while(!(UCSR1A & (1 << UDRE1)));     // wait until USART send register ready / warte, bis UDR bereit

    UDR1 = c;                // send caracter / sende Zeichen
    //  _delay_ms(2);
    return 0;
}  // end of usartPutc



// Interruptroutine, for immediate reading of one character from UART, if receive complete
ISR(USART1_RX_vect)
{
  udrData= UDR1;   //get byte in any case to prevent endless interrupt

  if(ringBufferCounter < RING_BUFFER_LENGTH)   // do not write to buffer it full / keinen Zeichen in einem vollen Ringpuffer überschreiben
  {
      ringBuffer[(ringBufferPosition+ringBufferCounter++) % RING_BUFFER_LENGTH] = udrData;  // which position? / welche Position?
                // Gelesene Zeichenpos + Anzahl Zeichen MODULO Pufferlänge
         // (von 0 wieder anfangen, wenn Ende erreicht)
        // >> LESBARER UMSCHREIBEN !!!!!!!!!!!!!!!!!!!!!!!!!!!
    }
  else   // if buffer was full set error flag
  {
       throwError(ERROR_USART_RINGBUFFER_FULL);
  }
}



int16_t  usartGetcNowait (FILE* notused)  // read ONE char from ringbuffer, use int16_t for errorhandling (errors are -1 or -2)
{
  unsigned char c;

  if(ringBufferCounter)        // if there are one or more characters in ringbuffer ...
  {
     cli();    // disable interrupthandling (to prevent disturbing ringbuffer writeroutine)


     c = ringBuffer [ringBufferPosition++];  // get next character ...
     ringBufferCounter--;              // and decrement counter (numbers of unread characters)

     if (ringBufferPosition >= RING_BUFFER_LENGTH)  ringBufferPosition = 0;  // if last position in ringbuffer
                                  // set buffer position pointer to 0

     sei();                  // enable interrupthandling

       if (c == 0x04)    // if End Of File  (ASCII-Code 0x04)
     {
        //return _FDEV_EOF;   // return error code -2 = end of file
     }

    }        // end of "if(ringBufferCounter)"
  else                         // if ringbuffer is empty, i.e. nothing to read
  {                            // do NOT wait until there is a character in buffer
                 // but return an error code
       throwError(ERROR_USART_RINGBUFFER_EMPTY);
     return _FDEV_ERR;         // return error code -1 = transmission error
    }

/*       if (ringBufferCounter < 10)      // if buffer gets nearly full: set
hardware handshake for CTS / "Busy"
  {
    // ----------------------------------------- ALLES NICHT GÜLTIG !!!!
PORT ÄNDERN !!! ---------------
    PORTD &=  ~(1<<PD2);  // PD2 = CTS (Busy) 0 = start TxD from VDIP2
      _delay_ms(1);
    PORTD |=   (1<<PD2);  // PD2 = CTS (Busy) 1 = stopp TxD from VDIP2
    }
  else
    {
    PORTD |=   (1<<PD2);  // PD2 = CTS (Busy) 1 = stopp TxD from VDIP2
    }
*/

   return (c);        // Zeichen zurückgeben
}

#endif //USART_H

Die putc()-Funktion kann nur jeweils nur einen Character senden (denke 
das ist auch allgemein so üblich). Printf() ruft dann für jeden char die 
angegebene putc() auf.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tobias H. wrote:
> Da GANZ einfache Programme schnell zum Laufen zu bekommen waren, habe
> ich nun ein kleines Programm geschrieben, dass in einer Endlosschleife
> Buchstaben auf ein RS232-Terminal ausgibt.

Alles klar, unter einfach versteh ich aber was anderes.

Du hast ja Ringbuffer und Printf Unterstützung eingebaut. Versuch doch 
mal erst mal mit einer normalen Schreibfunktion und grenze den Fehler 
ein.

Autor: Tobias H. (the)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Argh, sorry, aber das ist einer der Gründe dafür gewesen, dass ich das 
Programm ursprünglich NICHT posten wollte.

DENN: wenn man mal hinsieht, verwende ich Ringbuffer, etc. in meinem 
main gar nicht! Die einzigen Funktionen, aus der Uart.h, die in meinem 
main aufgerufen werden, sind init() und putc(), der Rest NICHT. Daran 
kann es also nicht liegen. (Ich hätte den Rest gar nicht zeigen 
sollen...)

Und ausserdem funktioniert das alles unter AVR-Studio wunderbar! Die 
Frage ist und bleibt, warum es in Eclipse nicht läuft, bzw. warum nur 
mit einzelnen Buchstaben.

Also nochmal: Woran könnte es liegen, dass IDENTISCHER Code unter 
AVR-Studio auf dem Controller anständig läuft und unter Eclipse eben 
nicht? Meiner Meinung nach kann es nur an den Makefiles liegen (s.o.)?

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tobias H. wrote:
> Argh, sorry, aber das ist einer der Gründe dafür gewesen, dass ich das
> Programm ursprünglich NICHT posten wollte.
Hä? Bleib mal auf dem Teppich.

> DENN: wenn man mal hinsieht, verwende ich Ringbuffer, etc. in meinem
> main gar nicht!
Na klar, Printf ruft die Ringbuffer Funktionen auf.

> Und ausserdem funktioniert das alles unter AVR-Studio wunderbar! Die
> Frage ist und bleibt, warum es in Eclipse nicht läuft, bzw. warum nur
> mit einzelnen Buchstaben.
Das hat zu 99% nichts mit AVR Studio oder Eclipse zu tun. Das ist nur 
ein Symptom, welches du siehst. Das Problem wird an einer 
unterschiedlichen Kommandozeile liegen und an Optionen, die beim 
Kompilieren mitgegeben werden. Dadurch tritt der Fehler zufällig einmal 
auf, und einmal nicht.

> Also nochmal: Woran könnte es liegen, dass IDENTISCHER Code unter
> AVR-Studio auf dem Controller anständig läuft und unter Eclipse eben
> nicht? Meiner Meinung nach kann es nur an den Makefiles liegen (s.o.)?
Ich vermute den Fehler in den Ringbuffer Funktionen. Wo hast du diese 
her? Sind die getestet? Ich habe mir die nicht angeschaut, aber ich 
schlage vor, dass du die erst mal raus machst und an FDEV_STREAM_SETUP 
eine ganz stinknormale uart_putc funktion reingibst.

Übrigens, was heißt "Funktioniert nicht"? Ich muss da Michael Haberler 
schon Recht geben, mit der Geheimniskrämerei kommt man nicht weit.
Wie gesagt: Fehler eingrenzen ist die Devise. Und zwar bei jedem Fehler, 
du kannst ja nicht bei jedem Fehler jemand anders fragen.

Autor: Tobias H. (the)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Simon,

entschuldige bitte. Das "Argh" und so weiter war kein Vorwurf. Eher an 
mich gerichtet, weil ich den Code vorher hätte "filtern" sollten, um 
Mißverständissen vorzubeugen (ich will doch nix verheimlichen!).
Ich bin sehr dankbar für die Existenz solcher Foren und für die Hilfe, 
die einem von Forenteilnehmern gewährt wird.

Da ich mich offensichtlich unglücklich ausgedrückt habe, hier nochmal 
das Problem:

1. Der obige Code kompiliert unter AVR-Studio (mit dem avr-gcc) und 
Eclipse (hier mit dem avr-g++, weiß nicht, wie man das ändert) 
fehlerfrei.

2. Mit Hilfe des AVR-Studios habe ich meinen Controller programmiert und 
das Programm getestet (es macht ja nichts ausser einer sich endlos 
wiederholenden Ausgabe von "Ha" auf dem Hyperterminal eines 
angeschlossenen Rechners). So funktioniert es prima.

3. Meine Uart.h besteht schon seit ein paar Wochen und die darin 
enthaltenen Funktionen zum Empfangen von Daten habe ich auch schon 
genutzt (den Ringbuffer hat ein Kollege geschrieben...) und deren 
korrekte Funktion getestet.

4. Punkt 3 ist insofern irrelevant, als ich der Meinung bin, dass ausser 
den init() und putc() Funktionen KEINE weiteren Funktionen dieser Datei 
von meinem main aufgerufen werden. Soweit ich weiß, ruft printf() NICHT 
getc() oder eine andere, mit dem Empfangen von Daten verbundene Funktion 
auf. Natürlich kann ich da irren aber in dem Fall wäre ich für eine 
Erklärung dankbar, da dann etwas ganz anders läuft, als ich dachte.

5. Sobald ich den Code mit Eclipse kompiliere und dann auf den 
Controller programmiere, geht es schief und auf dem Terminal landet 
nichts mehr.

6. Ändere ich die printf("Ha")-Anweisung in printf("H"), so läuft das 
Programm wieder einwandfrei.

7. Da der Quellcode beider IDEs identisch ist, kann es nur an den 
IDE-Einstellungen liegen, aus denen ja in beiden Fällen das Makefile 
erstellt wird.
Dieses Makefile definiert die exakte Form der avr-gcc/avr-g++ 
Kommandozeile. Sind die Makefiles unterschiedlich, resultieren 
unterschiedliche Kommandozeilen und damit ergibt sich eine mögliche 
Fehlerursache.

Liebe Grüße und besten Dank für die Hilfe.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Sind die Makefiles unterschiedlich, resultieren
>unterschiedliche Kommandozeilen und damit ergibt sich eine mögliche
>Fehlerursache.

Schau dir die Compileraufrufe doch einfach an, dann weisst du, ob es da 
Unterschiede gibt. So viele Möglichkeiten gibt es da gar nicht. Kandidat 
ist z.B die signed oder unsigned-definition des Typs char. Wobei das 
nicht fest vorgegeben ist, sondern in den Settings bzw. Optionen 
eingestellt werden kann.

Sollte es allerdings daran liegen, liegt es trotzdem an deinem Programm. 
Das muß so geschrieben sein, daß es mit beiden Varianten funktioniert.

Oliver

Autor: Tobias H. (the)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimme ich in beiden Punkten voll zu. Sobald ich morgen wieder an den 
Rechner komme, werde ich die Kommandozeilen mal vergleich und hier 
posten.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kompilieren lässt sich der Code nicht, da fehlt die Hälfte. Also such 
deine Fehler selber. In deinem Code, nicht in den makefiles. Die sind in 
Ordnung.

Und dann hinsetzten und tausendmal schreiben:
Ich soll keine .c-Files includen - auch nicht, wenn sie als headerfiles 
getarnt sind.

Oliver

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Sobald ich morgen wieder an den
>Rechner komme, werde ich die Kommandozeilen mal vergleich und hier
>posten.

???

Die stehen doch in deinen makefiles.

Oliver

Autor: Tobias H. (the)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte halt gehofft, dass jemand das Problem kennt und direkt sieht: 
"ah, da musst du das Flag XY noch setzen". Will doch von niemandem 
verlangen, meinen Code zu kompilieren.

Da ich aber langsam einsehe, dass das vielleicht sogar der einfachere 
Weg ist, werde ich morgen ein minimalistisches und hoffentlich dann auch 
kompilier-/reproduzierbares Paket posten.

@header-Files: mea culpa. Sollte allerdings keinerlei Probleme machen, 
da der Compiler das meines Wissens nach einfach implizit "inlined". 
Warum es überhaupt soweit kam? Lange Geschichte, die was mit geerbtem 
Code zu tun hat... ;-)

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt Namenskonflikte wenn du das Headerfile in mehreren .c Dateien 
inkludierst, da die Funktionen nicht static sind.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Lange Geschichte, die was mit geerbtem Code zu tun hat... ;-)

In der Zeit, in der du diesen Beitrag hier geschrieben hast, hättest du 
schon die UART-Funktionen in ein .c und ein .h aufteilen können. Die 
passende Struktur ist da ja schon drin. Mach das mal, dann sieht es 
gleich viel besser aus.

Oliver

Autor: Thomas Holland (innot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tobias H. wrote:

>
> Was mir auffällt ist, dass Eclipse mit avr-g++ kompiliert (obwohl mein
> Program unter Main.c gespeichert ist) und AVR-Studio mit avr-gcc (wobei
> ich noch nicht sehe, wo dabei das Problem sein könnte).

Tobias, Du hast, als Du das Projekt angelegt hast, (wahrscheinlich aus 
versehen) 'C++ Project' ausgewählt. Damit wird dann der C++ Linker 
anstatt des normalen C Linkers benutzt. Ob das was mit Deinem Problem zu 
tun hat weiß ich nicht, aber es kann nicht schaden das zu korrigieren. 
Dazu gibt es zwei Möglichkeiten:

1. Offizieller und sicherer weg: Neues 'C Project' anlegen, die Sourcen 
dorthin kopieren und die Einstellungen anpassen.

2. Inoffizieller 'Hack' (auf eigene Verantwortung): In der Datei 
'.project' im Projektverzeichnis die Zeile
<nature>org.eclipse.cdt.core.ccnature</nature>
löschen. Wichtig: nicht die Zeile mit cnature löschen, sondern nur die 
mit ccnature (zwei c am Anfang)

Anschließend Eclipse neu starten (oder das Projekt schließen und wieder 
öffnen).
Die Datei '.project' wird nur im "Navigator" angezeigt (Window->Show 
View->Navigator)

Thomas

Autor: Tobias H. (the)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Thomas!

Entschuldige die späte Antwort, ich war auf Reisen.

Habe Deinen Rat beherzigt und aus dem Eclipse-C++-Projekt ein C-Projekt 
gemacht (gemäß Deinem "Hack"...).

Tatsächlich FUNKTIONIERT der Code dann auch unter Eclipse, unabhängig 
davon, wieviele Buchstaben man mit printf() sendet (zur Erinnerung: 
printf("H") funktionierte unter Eclipse UND AVR-Studio, printf("Ha") nur 
unter AVR-Studio)!

Insofern möchte ich mich ganz herzlich bei Dir aber auch allen anderen 
Hilfsbereiten Beantwortern bedanken!

Falls jemand dieses Verhalten näher untersuchen möchte, hier nochmal 
meine Main.c, in einer Version in der keine weiteren Dateien gebraucht 
werden (Atmega640):
// ============================ USART-Test for ATmega640 =========

#ifndef F_CPU
#define F_CPU 4000000 //Quarz frequency in Hz. Insert actual value!!
#endif

// baud rate calculation:
#define UART_BAUD_RATE 9600L
#define UART_BAUD_CALC ((F_CPU)/((UART_BAUD_RATE)*16L)-1)

#include <stdio.h>
#include <util/delay.h>
#include <avr/io.h>


// usart functions:
void usartInit()
{
  /* Set baud rate */
  UBRR1H = (unsigned char)(UART_BAUD_CALC>>8);
  UBRR1L = (unsigned char) UART_BAUD_CALC;

  /* Enable receiver and transmitter */
  UCSR1B =  (1<<TXEN1);   // UART TX (send) enable
  UCSR1B |= (1<<RXEN1);   // UART RX (receive) enable

    /* Set frame format: 8data, 2stop bit */
    UCSR1C = (1<<USBS1)|(3<<UCSZ10);
}


// send ONE character
int16_t usartPutc(char c, FILE* notused)
{
    while(!(UCSR1A & (1 << UDRE1)));     // wait until USART send register ready

    UDR1 = c;                // send caracter

    return 0;
}


int16_t  usartGetc(FILE* notused) //just a dummy
{
  return 'c';
}


// ===============================================================
//  BEGIN OF MAIN PROGRAMM
// ===============================================================
int main(void)
{

  stdin = stdout = fdevopen(usartPutc, usartGetc);
  usartInit();

  while(1) {
    //printf("H");  //if you put one letter like "H" it works (Both IDEs)
    printf("Ha");  //if you put more then one letter, like "Ha", it doesn't work under eclipse any more!
            //(it still works under AVR-Studio)
    _delay_ms(10);
  }

  return 0;
}


Da es ja prinzipiell möglich zu sein scheint, C++-Programme für den 
Atmega zu kompilieren, könnte es etwas mit extern "C" { ... } zu tun 
haben, wie auf der AVR-GCC-Wiki angedeutet?

Liebe Grüße

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.