www.mikrocontroller.net

Forum: Compiler & IDEs Frage zur Erstellung von Libraries


Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich habe eine Frage zu Libraries. Ich würde gern wissen, ob das, was ich 
vorhabe, so überhaupt funktioniert. Ich weiß zumindest schon soviel, 
dass man die Funktionen auf möglichst viele Dateien verteilen muss, weil 
der Linker auf Objektebene arbeitet. Nehmen wir an ich hätte die Dateien 
foo.h, foo.c, bar1.c und bar2.c erstellt und dann die Objektdateien in 
libfoo.a zusammengefasst. Beim Compilieren des Hauptprogrammes nutze ich 
-lfoo.
/* foo.h */
void foo_init(void);
void bar1(void);
void bar2(void);

/* foo.c */
#include "foo.h"

void foo_init(void)
{
  // Tu was
}

ISR (SIG_OUTPUT_COMPARE0A)
{
  // Tu was
}

/* bar1.c */
#include "foo.h"

void bar1(void)
{
// Tu was
}

/* bar2.c */
#include "foo.h"

void bar2(void)
{
  bar1();
  // Tu was
}
Meine Fragen:
1.) Wenn ich im Hauptprogamm foo_init() verwende, funktioniert dann die 
ISR? Wird also der entsprechende Vektor gesetzt?
2.) Wenn ich im Hauptprogamm bar2() verwende, wird dann auch bar1() 
automatisch mit eingebunden?

Vielen Dank für eure Hilfe.

Gruß, DetlevT

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Detlev T. schrieb:

> Meine Fragen:
> 1.) Wenn ich im Hauptprogamm foo_init() verwende, funktioniert dann die
> ISR? Wird also der entsprechende Vektor gesetzt?

Da bin ich mir nicht sicher. Probiers einfach aus.
Allerdings würde ich das so nicht machen. Wenn du mehrere Libraries 
gleichzeitig benutzt, wirst du sehr schnell die Übersicht verlieren, wer 
den welchen Interrupt Vektor angemeldet hat.
Ich würde in den sauren Apfel beissen und eine InterruptHandler Funktion 
in die Library mit aufnehmen. Eine ganz normale Funktion mit der 
Auflage, dass der Anwendungsprogrammierer, der die Funktionalität 
benutzen will, sich selbst darum kümmern muss, eine ISR zu schreiben und 
dann von der ISR diese Funktion aufrufen kann.

> 2.) Wenn ich im Hauptprogamm bar2() verwende, wird dann auch bar1()
> automatisch mit eingebunden?

Ja

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Detlev T. schrieb:
> Hallo Leute,
>
/* foo.h */
> void foo_init(void);
> void bar1(void);
> void bar2(void);
> 
> /* foo.c */
> #include "foo.h"
> 
> void foo_init(void)
> {
>   // Tu was
> }
> 
> ISR (SIG_OUTPUT_COMPARE0A)
> {
>   // Tu was
> }
> 

Klar, hier wird natürlich ein Eintrag in die Vektortabelle erstellt. 
Beim Anlegen von Multilibs musst du aber sicher sein, daß alle Derivate, 
für die die Multilib-Variante gedacht ist, die gleiche IRQ-Nummer haben!

Johann

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl heinz Buchegger,

O.K., ich habe es ausprobiert und es geht offenbar nicht . Die 
ISR-Routine landet zwar im Ausgangsfile, der entsprechende Vektor wird 
jedoch nicht gesetzt. Wenn ich das ohne den Umweg über eine Library 
mache, ist alles in Ordnung.

Schade eigentlich.

Damit hat sich eigentlich auch der zweite Teil fast erledigt. Muss ich 
noch einmal sehen.

Hintergrund der Aktion ist, dass ich ein Testboard mit einer Menge 
Hardware drauf erstellen will. Dazu soll(te?) es eine einzige Library 
mit den entsprechenden Routinen geben, um diese Hardware bequem 
anzusprechen und von der eben nur die Funktionen eingebunden werden, die 
man aktuell braucht ohne dass man groß darüber nachdenken muss.

Vielleicht gibt es ja eine Zwischenlösung, wo man die ISR in einem .c 
File definiert, aber nur diejenigen mit compiliert, deren .h Dateien 
aktuell eingebunden sind. Die anderen Funktionen könnte man vielleicht 
doch in eine Library packen. Ob das mit den gemeinsamen Variablen 
funktioniert, muss ich noch einmal schauen.

Notfalls muss ich irgendetwas mit Macros machen und bestimmte Funktionen 
aus einer großen board.c via #ifdef halt einbinden oder nicht. Das ist 
weniger komfortabel und effizient, aber wenigstens das sollte gehen.

@Johann L.
Es geht nur um ein Derivat, ein bestimmtes Board mit einem bestimmten 
Controller. Der Eintrag in die Vektortabelle wurde bei meinem Test 
nicht erstellt, wenn die ISR in der libfoo.a definiert war. Habe ich 
foo.c ganz normal als .o gelinkt, funktionierte das hingegen.

Danke für eure Hilfe.

Gruß, DetlevT

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Detlev T. schrieb:

> Der Eintrag in die Vektortabelle wurde bei meinem Test
> nicht erstellt, wenn die ISR in der libfoo.a definiert war. Habe ich
> foo.c ganz normal als .o gelinkt, funktionierte das hingegen.

Das lässt eher darauf schliessen, daß die Tools falsch angewandt wurden. 
Die Bibliother sammelt ja auch nur Objekte.

Johann

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wichtig ist für die ISR nur, dass es auch wirklich so gemacht wird,
wie du das da oben geschrieben hast: die ISR muss in einem Objektmodul
stehen, aus dem noch (mindestens) ein weiteres Symbol referenziert
wird, ansonsten hat der Linker keine Veranlassung, den Modul zu linken.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:
> Wichtig ist für die ISR nur, dass es auch wirklich so gemacht wird,
> wie du das da oben geschrieben hast: die ISR muss in einem Objektmodul
> stehen, aus dem noch (mindestens) ein weiteres Symbol referenziert
> wird, ansonsten hat der Linker keine Veranlassung, den Modul zu linken.

Das externally_visible und used-Zeug hat keinen Einfluß aufs Objekt?

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jörg Wunsch
Ich habe es so gemacht und der Code der ISR-Routine landet auch in der 
Ausgangsdatei. Nur der Vektor wird nicht automatisch gesetzt.

Wenn ich hingegen dieselbe Objektdatei, die ich zur Erstellung der 
Library erzeugt hatte, direkt linke, stimmt der Vektor.

Gruß, DetlevT

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Detlev T. schrieb:

> Ich habe es so gemacht und der Code der ISR-Routine landet auch in der
> Ausgangsdatei. Nur der Vektor wird nicht automatisch gesetzt.

Dann müsste man sich nochmal angucken, wie der ganze weak-Krams
eigentlich funktioniert.  crtXXX.o definiert ja die komplette
Vektortabelle, wobei alle diese Definitionen `weak' markiert sind.
Damit bekommt eine gleichnamige Definition aus der Applikation
dann Vorrang (ohne `weak' wäre es ein Doppeldefinitionsfehler).

Offenbar wird `weak' wohl ignoriert, wenn der Modul aus einer
Bibliothek entnommen wird.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auf so profane Dinge, wie beim Compilieren der Lib die richtige MCU 
anzugeben, hast du geachtet?

Vergleiche doch mal, welche Symbole in der reinen Objektdatei, und 
welche in der Library definiert sind. Würde mich nicht wundern, wenn du 
dort einen Namensunterschied beim Vector findest.

Vor einiger Zeit hatte ich selbst mal eine ISR in eine Library gepackt, 
und da hat es anstandslos funktioniert.

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

unverkennbar bin ich Anfänger, was die Libraries betrifft. Vielleicht 
kann jemand etwas von euch damit anfangen. nm -s libbtn.a (so heißt die 
Library wirklich) gibt am Anfang folgendes aus:
Archive index:
btn_init in btn_init.o
__vector_14 in btn_init.o
key_state in btn_init.o
key_press in btn_init.o
key_release in btn_init.o
btn_countdown in btn_init.o
btn_key_pressed in btn_key_pressed.o
btn_key_released in btn_key_released.o

btn_init.o:
00000034 a __CCP__
0000003e a __SP_H__
0000003d a __SP_L__
0000003f a __SREG__
         U __do_clear_bss
         U __do_copy_data
00000000 a __tmp_reg__
00000024 T __vector_14
00000001 a __zero_reg__
00000001 C btn_countdown
00000000 T btn_init
00000001 b ct0.1241
00000000 b ct1.1242
00000001 C key_press
00000001 C key_release
00000001 C key_state
Ich habe realen Code verwendet (für die Software-Entprellung von 
Tasten). key_state, key_press, key_release_btn_countdown sind (volatile) 
Variablen. Damit gibt es beim Linken keine Fehlermeldung. btn_init() ist 
in derselben .c Datei wie die ISR. btn_key_pressed und btn_key_released 
jeweils in eigenen.

Der Teil mit ct01241 / ct1.1242 taucht nur bei dieser Datei auf. Ich 
vermute, das hat etwas mit dem Vektor zu tun. Das wisst ihr aber 
wahrscheinlich besser.

Gelinkt habe ich das mit dem Zusatz "-L. -lbtn". Fehlt da vielleicht 
noch irgendein Parameter, damit diese Informationen übernommen werden?

Gruß, DetlevT

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.