GCC-Linker meldet 'Undefined reference'

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • GCC-Linker meldet 'Undefined reference'

    Servus zusammen,

    ich sitze an folgendem Problem:
    Der Linker meldet mir eine "Undefined reference", er kann also ein Symbol nicht auflösen.
    Ich benötige die Adresse eines Labels, die ich einer Variablen zuweisen möchte. Und genau dieses
    Label moniert er an, daß er es nicht findet.

    SW: GCC 4.2.8 für Coldfire CPU

    Genauer gesagt geht es um folgendes: Ich möchte uCos-II (ein embedded OS) für unsere Embedded Hardware
    (Coldfire 5307) anpassen. Das läuft soweit, leider bin ich gezwungen meine ISRs in Assembler zu schreiben,
    was ich umgehen möchte - C ist mir da lieber.
    Wenn ich allerdings eine ISR in C schreibe:

    Quellcode

    1. extern void MeineISR(void) __attribute__ ((interrupt_handler))
    2. {
    3. ...
    4. }

    dann erzeugt GCC folgenden Assembler-Code:

    Quellcode

    1. MeineISR: lea #-0x10,a7
    2. movem.l (d0,d1/a0,a1),a7
    3. ...
    4. movem a7,(d0,d1/a0,a1)
    5. lea #10,a7
    6. rte

    Er rettet also vier Register auf den Stack und kurz vor dem Rücksprung (rte) restauriert er sie wieder.
    Das wäre so okay, wenn uCos damit nicht ein Problem hätte. Ich MUSS nämlich als erstes die Interrupts ausschalten,
    bin also gezwungen bevor der Compiler zum Zug kommt ein "move.w #0x2700,sr" zu machen. Ich benötige also die volle Kontrolle.
    Jetzt habe ich gesehen, daß eine Firma, die uCos mit ihrer Hardware verkauft da ein Macro gebastelt hat, dessen Aufruf
    so aussieht: INTERRUPT(meineFunktion, meinStatusRegister).
    Also z.B.

    Quellcode

    1. INTERRUPT(TimerISR, 0x2700)
    2. {
    3. ...
    4. }

    Jetzt weiß ich aber nicht, wie das Macro aussieht, habe mich mit dem Preprozessor etwas weiter beschäftigt und folgendes konstruiert:

    Quellcode

    1. #define INTERRUPT(function, statusreg) asm (#function ":;\n"); \
    2. asm ("move.w #" #statusreg ",%sr\n"); \
    3. static void (function ## Main) (void)

    Wenn ich mir das Disassemblat in unserem Lauterbach ICD anschaue, sieht das prima aus. Er zeigt mir auch das Label OSManagerTimerTick (das mein Einsprungpunkt in die ISR sein soll) an.

    Im Headerfile definiere ich dann in 'OSManager.h':

    Quellcode

    1. extern void OSManagerTimerTick(void) __attribute__ ((interrupt_handler));

    Die Funktion sieht dann so aus in 'OSManager.c':

    Quellcode

    1. INTERRUPT(OSManagerTimerTick, 0x2700)
    2. {
    3. OSIntEnterMCF5307;
    4. TimeManagerFinalizeInterrupt(kTimer1);
    5. OSTimeTick();
    6. OSIntExitMCF5307;
    7. }

    In dem File, in dem auch mein main() liegt mach ich dann:

    Brainfuck-Quellcode

    1. #include "OSManager.h"
    2. typedef void tExceptionHandler(void);
    3. tExceptionHandler* mExceptionHandler;
    4. ...
    5. mExceptionHandler = OSManagerTimerTick; /* <<<<<<<<<<<< hier kann er das Symbol OSManagerTimerTick nicht auflösen */

    Andere Funktionen aus OSManager werden gefunden, kann also kein Datei-ist-nicht-im-Suchpfad Problem sein.
    Da das ganze wohl nicht auf den ersten Blick verständlich ist, habe ich halt etwas weiter ausgeholt.

    Any idea?

    Thanx, Arne
  • Falls es jemanden interessiert:
    Wenn man an die Deklaration der ISR-Funktion ein

    Quellcode

    1. __attribute__ ((naked))

    anhängt, wird beim GCC (zumindest bei der 4.2.8 für Coldfire) kein Entry/Exit code erzeugt. Der Compiler meldet dann zwar bei jedem "naked" Attribut
    "warning: 'naked' attribute directive ignored", aber der Maschinencode wird trotzdem ohne Entry/Exit code erzeugt.