Forum: Mikrocontroller und Digitale Elektronik uart Lib - Peter Fleury - kompiliert nicht


von Veit D. (devil-elec)


Angehängte Dateien:

Lesenswert?

Hallo,

Atmel Studio 7
uart Lib von Peter Fleury
(http://homepage.hispeed.ch/peterfleury/avr-software.html)

Es ist sein Example file.

Der Kopf wie folgt:
1
#define F_CPU 8000000UL  // Systemtakt in Hz
2
3
#include <stdlib.h>
4
#include <avr/io.h>
5
#include <avr/interrupt.h>
6
#include <avr/pgmspace.h>
7
#include <uart.h>
8
9
#define UART_BAUD_RATE  9600  
10
11
int main(void)
12
{

Die uart.c und uart.h liegen bei mir in einem eigenem Lib Ordner.
In den Projekt Eigenschaften > Toolchain, habe ich den Pfad angepaßt.
Siehe Screenshots.
#include<u ... wird per Autovervollständigung gefunden

Wenn ich dann allerdings F7 drücke, wird jede Funktion als "undefined 
reference" angemeckert.
1
Fehler    undefined reference to `uart_init'  
2
Fehler    undefined reference to `sei'  
3
Fehler    undefined reference to `uart_puts_p'  
4
Fehler    undefined reference to `uart_puts'  
5
Fehler    undefined reference to `uart_puts'  
6
Fehler    undefined reference to `uart_puts_p'  
7
Fehler    undefined reference to `uart_puts_p'  
8
Fehler    undefined reference to `uart_puts_p'  
9
Fehler    undefined reference to `uart_putc'  
10
Fehler    undefined reference to `uart_getc'

Ob < > oder " " ist egal.

Was kann ich noch tun?

von Karl M. (Gast)


Lesenswert?

Nun,

stelle die gesamte Datei/ Projekt ein und füge bitte die Fehlermeldung 
hinzu.

von Veit D. (devil-elec)


Lesenswert?

1
#define F_CPU 8000000UL  // Systemtakt in Hz
2
3
#include <stdlib.h>
4
#include <avr/io.h>
5
#include <avr/interrupt.h>
6
#include <avr/pgmspace.h>
7
#include <uart.h>
8
9
#define UART_BAUD_RATE  9600  
10
11
int main(void)
12
{
13
    unsigned int c;
14
    char buffer[7];
15
    int  num=134;
16
17
    
18
    /*
19
     *  Initialize UART library, pass baudrate and AVR cpu clock
20
     *  with the macro 
21
     *  UART_BAUD_SELECT() (normal speed mode )
22
     *  or 
23
     *  UART_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode)
24
     */
25
    uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
26
    
27
    /*
28
     * now enable interrupt, since UART library is interrupt controlled
29
     */
30
    sei();
31
    
32
    /*
33
     *  Transmit string to UART
34
     *  The string is buffered by the uart library in a circular buffer
35
     *  and one character at a time is transmitted to the UART using interrupts.
36
     *  uart_puts() blocks if it can not write the whole string to the circular 
37
     *  buffer
38
     */
39
    uart_puts("String stored in SRAM\n");
40
    
41
    /*
42
     * Transmit string from program memory to UART
43
     */
44
    uart_puts_P("String stored in FLASH\n");
45
    
46
        
47
    /* 
48
     * Use standard avr-libc functions to convert numbers into string
49
     * before transmitting via UART
50
     */     
51
    itoa( num, buffer, 10);   // convert interger into string (decimal format)         
52
    uart_puts(buffer);        // and transmit string to UART
53
54
    
55
    /*
56
     * Transmit single character to UART
57
     */
58
    uart_putc('\r');
59
    
60
    for(;;)
61
    {
62
        /*
63
         * Get received character from ringbuffer
64
         * uart_getc() returns in the lower byte the received character and 
65
         * in the higher byte (bitmask) the last receive error
66
         * UART_NO_DATA is returned when no data is available.
67
         *
68
         */
69
        c = uart_getc();
70
        if ( c & UART_NO_DATA )
71
        {
72
            /* 
73
             * no data available from UART 
74
             */
75
        }
76
        else
77
        {
78
            /*
79
             * new data available from UART
80
             * check for Frame or Overrun error
81
             */
82
            if ( c & UART_FRAME_ERROR )
83
            {
84
                /* Framing Error detected, i.e no stop bit detected */
85
                uart_puts_P("UART Frame Error: ");
86
            }
87
            if ( c & UART_OVERRUN_ERROR )
88
            {
89
                /* 
90
                 * Overrun, a character already present in the UART UDR register was 
91
                 * not read by the interrupt handler before the next character arrived,
92
                 * one or more received characters have been dropped
93
                 */
94
                uart_puts_P("UART Overrun Error: ");
95
            }
96
            if ( c & UART_BUFFER_OVERFLOW )
97
            {
98
                /* 
99
                 * We are not reading the receive buffer fast enough,
100
                 * one or more received character have been dropped 
101
                 */
102
                uart_puts_P("Buffer overflow error: ");
103
            }
104
            /* 
105
             * send received character back
106
             */
107
            uart_putc( (unsigned char)c );
108
        }
109
    }
110
    
111
}

Die Fehlermeldungen oben sind "alle". Die letzte "recipe for target ... 
.elf" brauch ich nicht posten. Wie gesagt, dass ist der example code.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

wenn ich irgendwas an der include Schreibweise ändere oder das include 
in der uart.c, dann findert er die Lib gleich gar nicht. < > bzw. " ".

Fehler    recipe for target 'main.o' failed
Fehler    uart.h: No such file or directory

von hp-freund (Gast)


Lesenswert?

include sorgt für das Finden der .h Datei.
Die zugehörige .c Datei muss dem Projekt hinzu gefügt werden.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Die Kombination datei.h und datei.c ist keine Library.

Also ist es komplett sinnlos, an den Einstellungen für den Linker 
herumzubasteln.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

wenn ich den Pfad für den Linker lösche, findet er die Lib nicht.
Ich weiß nicht was ich noch machen soll.

von Nop (Gast)


Lesenswert?

Veit D. schrieb:

> Ich weiß nicht was ich noch machen soll.

Endlich das machen, was hp-freund Dir schon gestern um 23:45 geantwortet 
hat.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

na ich dachte der findet nun selbst alle Dateien, wofür gibt man ihm 
dann die Pfadangaben? Wie fügt man die .c dem Projekt hinzu?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Veit D. schrieb:
> Wie fügt man die .c dem Projekt hinzu?

Rechte Maustaste auf das 'Source Files' deines Projektes->Add 
File->uart.c suchen und einfügen.
Es ist sinnvoll, uart.h und uart.c in den Projekt Ordner zu kopieren.

> na ich dachte der findet nun selbst alle Dateien, wofür gibt man ihm
> dann die Pfadangaben?

Die sind nur für zusätzliche echte libraries, wie Rufus schrieb:

Rufus Τ. F. schrieb:
> Die Kombination datei.h und datei.c ist keine Library.

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

okay, habe beide Pfadangaben gelöscht.
Rechts im Explorerfenster, Projektname, rechtsklick, hinzufügen, browse 
... .c und .h ausgewählt, kompiliert.

Danke.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

ich nenne es dennoch mal Library. Ist es nicht einfacher einen Ordner 
für seine Sammlung anzulegen? Als laufend die Dateien zu kopieren. Wenn 
es selbst erstellte sind und man ändert was darin, liegen am Ende 
tausend Versionen verstreut auf der Platte. Halte ich nicht für gut.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Veit D. schrieb:
> Als laufend die Dateien zu kopieren.

Da solche Codes meistens für sehr viele verschiedene MCs und Projekte 
gedacht sind und die Einstellungen meistens im *.h File gemacht werden, 
ist die Kopiererei schon sinnvoll. Denn Register wie der UART und z.B. 
TWI liegen ja nicht immer an der gleichen Adresse und belegen auch nicht 
die gleichen Pins am MC.
Die Fleury LCD Routinen z.B. liegen bei mir in 4 oder 5 Projekten und 
jede lcd.h ist anders.
Das ist z.B. beim ASF auf dem XMega auch nicht anders, oder bei der 
STM32 SPL. Nur von der Hardware abstrahierte Dinge wie z.B. math sind in 
einer echten Library gut aufgehoben.

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

das heißt du löschst in der uart hier sämtliche nicht benötigte defines 
für die verschiedenen µC raus? Aus meiner Sicht ist die universell 
aufgebaut, deswegen dachte ich, belasse es bei universell. Aber okay, 
dass handhabt wohl jeder anders.

Noch eine Frage. Gibt es eine einfache Möglichkeit, sein Projekt einfach 
unter neuen Namen zu speichern? Im Moment erstelle ich jedesmal ein 
neues Projekt von vorn. Das mache ich vor größeren Änderungen, sozusagen 
als Backup. Das ist auf Dauer lästig umständlich. Sowas wie "Speichern 
unter" wäre mir lieber.

von Nop (Gast)


Lesenswert?

Veit D. schrieb:

> Noch eine Frage. Gibt es eine einfache Möglichkeit, sein Projekt einfach
> unter neuen Namen zu speichern? Im Moment erstelle ich jedesmal ein
> neues Projekt von vorn. Das mache ich vor größeren Änderungen, sozusagen
> als Backup.

Zwei Möglichkeiten:

a) komplettes Projektverzeichnis zippen und im Archivnamen das Datum 
eintragen, dann haste das auch chronologisch sortiert. Das ist die 
quick&dirty-Lösung.

b) ein richtiges Versionsverwaltungssystem nutzen, das ist dafür 
gedacht. Ich würd aber trotzdem zusätzlich noch Lösung a) machen, 
zumindest bei erreichten Meilensteinen. Nur falls man durch 
Fehlbedienung seine Datenbank zerschießt.

von Nop (Gast)


Lesenswert?

Ach ja, denk auch daran, Deine Backups auf einem unabhängigen 
Datenträger zu kopieren. Idealerweise ein externer, der nur beim Backup 
angeschlossen wird.

Gerade SSDs sterben, wenn sie denn sterben, gerne mal ohne jede 
Vorwarnung. Grund ist, daß sie sich nicht langsam abnutzen (das tun sie 
auch), sondern daß der Controller die Grätsche macht.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

zum packen auf Mausklick nutze ich ein Batchdatei, worin mehrere Ordner 
gesichert werden. Bsp. für AS.
1
winrar a -agYYMMDD "Z:\Backup\Atmel Studio 7 Projekte_" "C:\Users\...\Documents\Atmel Studio"

Mir ging es in der Frage eher darum nicht laufend ein neues Projekt 
anlegen zu müssen. Hast du einen Link für die Versionsverwaltung?

von Nop (Gast)


Lesenswert?

Veit D. schrieb:

> Mir ging es in der Frage eher darum nicht laufend ein neues Projekt
> anlegen zu müssen.

Äh? Wenn Du das bisherige Projekt gezipt hast, kannste es doch einfach 
nach Belieben verändern, ohne ein neues anzulegen? Das Backup ist ja im 
Zipfile.

> Hast du einen Link für die Versionsverwaltung?

Da gibt's ne Menge, was man nehmen kann. Der Haken ist, alle erfordern 
eine gewise Einarbeitung. Manche mehr, manche weniger. Bekannt und 
verbreitet sind beispielsweise SVN und Git, wobei letzteres sehr viel 
kann, aber eine extreme Lernkurve hat.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

das packen ist für Tageweise sichern gedacht. Außerdem müsste ich dafür 
AS jedesmal erst schließen, packen, öffnen usw. Dann kann ich auch 
gleich ein neues Projekt erstellen. Ich gucke mir das SVN/Git mal an.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Veit D. schrieb:
> ich nenne es dennoch mal Library.

Gewöhn Dir das ab. Denn das ist schlicht und einfach Unfug.

Was eine Library ist, ist klar und eindeutig definiert; und es hat einen 
Sinn, daß Dinge klar und eindeutig definiert sind.

Einfach aus --sorry-- Blödheit etwas anders zu nennen, ist 
kontraproduktiv.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Veit D. schrieb:
> das heißt du löschst in der uart hier sämtliche nicht benötigte defines
> für die verschiedenen µC raus?

Aber nein. Aber in den *.h Dateien von Peter Fleury sind die jeweils 
benutzte Taktfrequenz (XTAL), die benutzten Portbeinchen für LCD usw. 
definiert, und das ändert sich von Projekt zu Projekt (zumindest in 
meinen Firmwares) bei der LCD- und bei der (Soft-)I2C Bib. Die UART 
Bibliothek habe ich noch nicht benutzt, konnte ich bisher ohne 
Bibliothek lösen.

von Theor (Gast)


Lesenswert?

@ Veit D.

Man kann die Bedeutung einer präzisen Ausdrucksweise und klaren 
Definition gar nicht genug übertreiben. :-)

Jedenfalls führt es absehbar zu komplizierter und sogar fehlschlagender 
Kommunikation, wenn man einen Begriff neu definiert, der für den 
überwiegenden Teil der programmierenden Menschheit schon eine 
feststehende und klar umrissene Bedeutung hat.

Du siehst ja, was hier geschehen ist: Du behandelst eine Sache als 
Library die in den Begriffen des AVR-Studio, des Linkers und des 
Compilers eben keine Library ist und prompt werden die Dinge kompliziert 
und funktionieren nicht.

Das ist genauso als wenn Du einen Amboss in "Apfel" umbenennst und dann 
meinst Du kannst ihn auch wie das Ding behandeln, dass der Rest der 
Menschheit einen Apfel nennt: Das Resultat ist, dass Du Dir die Zähne 
ausbeisst.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Veit D. schrieb:
> das heißt du löschst in der uart hier sämtliche nicht benötigte defines
> für die verschiedenen µC raus?

 Warum ?

 Gerade deswegen sind die defines so nützlich. Für dich sind viele
 defines vielleicht verwirrend, Compiler sucht sich aber nur
 entsprechende raus.

 Mit #define MyProcTyp sind für Compiler alle anderen uC die mit
 #ifdef EinAndererProcTyp beschrieben sind, gelöscht.

von Veit D. (devil-elec)


Lesenswert?

Hallo Marc,

reden wir aneinander vorbei? Gerade weil das mit dem defines der Vorteil 
ist universal zu bleiben, macht es doch gerade deswegen Sinn einen 
zentralen Ort für seine zusätzlichen Libs zu haben und eben nicht immer 
alles in den Projektordner kopieren zu müssen.

von Karl M. (Gast)


Lesenswert?

Hallo Libs,

die C- und H-Datei ist keine "Lib", eher ein Modul oder eine 
Funktionsbibliothek.

Ich kopiere auch immer alle in einen Ordner, so kann ich dort Zentral 
alle Projektdateien halten und einfach Sichern.
Z.B. automatisch mit einem Script und einer Zip-Datei.

Ja ich weiß, es gibt auch andere Projektverwaltungen.

Nicht jeder arbeitet mit dem "Atmel Studio", erst recht nicht, wenn man 
kein WinOS mehr verwendet.

Dann wird alles viel schmaler, schneller und - wie ich finde - 
einfacher.

von 123456 (Gast)


Lesenswert?

Wenn du für deine verschiedenen Projekte Änderungen an der .h Datei bzw. 
den Defines machst, musst du auch die .c Datei neu compilieren. Deshalb 
ist es keine echte Lib. Du kannst dir natürlich daraus eine echte Lib 
machen und alle änderbaren Parameter an Funktionen übergeben.
Es wird sich aber nicht lohnen, weil es ganz praktisch ist, wenn man 
projektspezifische Änderungen machen kann.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

letzteres macht Sinn als Begründung das ihr das immer lieber kopieren 
wollt. Okay leuchtet ein. Alles benötigte an Ort und Stelle.

Nur was macht denn in euren Augen eine Lib aus, wenn ihr zu der 
Funktionssammlung Peters uart nicht Library sagen wollt?

von Nop (Gast)


Lesenswert?

Veit D. schrieb:

> Nur was macht denn in euren Augen eine Lib aus, wenn ihr zu der
> Funktionssammlung Peters uart nicht Library sagen wollt?

Eine Library ist ein vorcompiliertes Binärpaket, was ins Projekt 
eingelinkt wird, wie z.B. die C-Standardlibrary, oder die Math-Library. 
Man kann dazu die Quelltexte haben, muß man aber nicht.

Wenn man die Quelltexte aber braucht, weil man immer projektspezifische 
Anpassungen machen muß, ist eine Library technisch das verkehrte Format.

von 123456 (Gast)


Lesenswert?

Wie ich schon geschrieben hab, kannst du aus der Funktionssammlung eine 
Lib machen. Du musst aber bedenken, dass unnötige Defines vorm 
Compilieren automatisch gelöscht werden und keinen zusätzlichen Code 
generieren.

Wenn du daraus jetzt eine lib machst und alle änderbaren Parameter an 
Funktionen übergibst, musst du alles mit if, else bzw switch Konstrukten 
abfangen. Da die Lib beim Compilieren nicht wissen kann was gebraucht 
wird, wird das Binary entsprechend groß und das will man besonders bei 
keinen Mikrocontrollern nicht.

Du kannst das mal ausprobieren, indem du alles aus dem uart.c File 
löscht,
was nicht für deinen Controller bestimmt ist. Dann siehst du wie kurz 
der wirklich verwendete Code ist.

von batman (Gast)


Lesenswert?

Nop schrieb:
> Veit D. schrieb:
>
>> Nur was macht denn in euren Augen eine Lib aus, wenn ihr zu der
>> Funktionssammlung Peters uart nicht Library sagen wollt?
>
> Eine Library ist ein vorcompiliertes Binärpaket, was ins Projekt
> eingelinkt wird, wie z.B. die C-Standardlibrary, oder die Math-Library.
> Man kann dazu die Quelltexte haben, muß man aber nicht.
>
> Wenn man die Quelltexte aber braucht, weil man immer projektspezifische
> Anpassungen machen muß, ist eine Library technisch das verkehrte Format.

Und wie nennst du dann das betreffende Dingsda von Peter Fleury?

von Nop (Gast)


Lesenswert?

batman schrieb:

> Und wie nennst du dann das betreffende Dingsda von Peter Fleury?

Eine Funktionssammlung. Aus den vom Vorposter um 10:17 genannten Gründen 
wäre eine Library da auch nicht sinnvoll.

von batman (Gast)


Lesenswert?

Stimmt aber nicht so ganz, denn auch eine kompilierte Library landet 
nicht komplett im Mikrocontroller, sondern nur die verwendeten Objekte.

von Nop (Gast)


Lesenswert?

batman schrieb:
> Stimmt aber nicht so ganz, denn auch eine kompilierte Library landet
> nicht komplett im Mikrocontroller, sondern nur die verwendeten Objekte.

Posting um 10:17, zweiter Absatz lesen.

von batman (Gast)


Lesenswert?

Genau, da schreibt er vom Compilieren obwohl es eigentlich ums Linken 
geht. Naja, muß man heute wohl alles nicht mehr so genau wissen.

von Nop (Gast)


Lesenswert?

batman schrieb:
> Genau, da schreibt er vom Compilieren obwohl es eigentlich ums Linken
> geht.

Nein, Du hast sein Argument nur nicht verstanden. Nichtmal ansatzweise.

> Naja, muß man heute wohl alles nicht mehr so genau wissen.

Jepp. Und sich dann wundern, wieso die eigenen Projekte sich nicht 
übersetzen lassen.

von 123456 (Gast)


Lesenswert?

batman schrieb:
> Genau, da schreibt er vom Compilieren obwohl es eigentlich ums Linken
> geht. Naja, muß man heute wohl alles nicht mehr so genau wissen.

Es geht ums compilieren der Lib und nicht des Projektes.
Das Ziel einer Lib ist es, sie nur einmal zu compilieren.
Ich bin jetzt auch kein Profi, aber nach meinem Verständnis, müsste man 
jeder Funktion der Lib den verwendeten Controller übergeben.
Jetzt wäre die Frage, ob ein Linker sich die benötigten Teile der 
binären Lib herausziehen kann?
Wäre interessant zu wissen ob sowas geht.

von Nop (Gast)


Lesenswert?

123456 schrieb:

> Jetzt wäre die Frage, ob ein Linker sich die benötigten Teile der
> binären Lib herausziehen kann?

Nein. Was natürlich ginge, wäre, für jeden Controller jede Funktion 
explizit hinzuschreiben. Die nicht benötigten könnten dann entfernt 
werden.

Die Folge wäre aber wesentlich mehr Wartungsaufwand wegen der 
Code-Duplikation. Deswegen macht man das ja mit defines und als 
Funktionssammlung anstatt als Library.

von batman (Gast)


Lesenswert?

Ja, der Linker linkt im Allgemeinen nicht komplette Dateien sondern nur 
die Objekte (in Maschinensprache), die verwendet (referenziert) werden. 
Sonst könnte man kaum eine Standard-C-Lib verwenden.

Der Maschinencode ist generell hardwarespezifisch, d.h. man braucht pro 
Controllertyp eine lib. Das wäre der eigentliche Nachteil der 
kompilierten Lib.

von 123456 (Gast)


Lesenswert?

batman schrieb:
> Ja, der Linker linkt im Allgemeinen nicht komplette Dateien sondern nur
> die Objekte (in Maschinensprache), die verwendet (referenziert) werden.
> Sonst könnte man kaum eine Standard-C-Lib verwenden.
>
> Der Maschinencode ist generell hardwarespezifisch, d.h. man braucht pro
> Controllertyp eine lib. Das wäre der eigentliche Nachteil der
> kompilierten Lib.

Da du dich mit Linkern besser auskennst, hab ich mal eine theoretische 
Frage:
Mal angenommen, ich würde aus der besagten Funktionssammlung eine echte 
vorcompilierte Lib machen wollen, die weiterhin auf allen Controllern 
läuft.
Dann müsste ich doch den Controller an die Funkionen übergeben, mit 
einem switch Konstrukt auswerten und dann die entsprechene Funktion mit 
den richtigen Registeradressen aufrufen.

Könnte der Linker in so einem Fall feststellen welche Funkionen nicht 
gebraucht werden?
Könnte er wissen, dass immer der selbe Controller in einem Projekt an 
die Funkionen übergeben wird?
Oder würde er die ganze Lib linken, weil es einen möglichen 
Funktionsaufruf aus einer switch/case Anweisung gibt?

Mir ist klar, dass diese Lib absolut sinnlos wäre. Es geht mir nur 
darum, wie sich der Linker verhalten würde.

Der Unterschied zu Standard C-Libs wäre ja, dass Funktionen nicht 
gelinkt werden, die nicht aufgerufen werden. In meinem Beispiel würde 
nicht der Aufruf der Funktion entscheiden ob sie verwendet wird, sondern 
der übergebene Parameter an eine Funktion der Lib.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.