You are not logged in.

  • Login

1

Friday, July 13th 2007, 9:10am

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:

Source code

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

dann erzeugt GCC folgenden Assembler-Code:

Source code

1
2
3
4
5
6
7
8
MeineISR:	lea		#-0x10,a7
			movem.l	(d0,d1/a0,a1),a7
			
			...
			
			movem	a7,(d0,d1/a0,a1)
			lea		#10,a7
			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.

Source code

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

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

Source code

1
2
3
#define	INTERRUPT(function, statusreg)		asm (#function ":;\n");						\
											asm ("move.w	#" #statusreg ",%sr\n");	\
											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':

Source code

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

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

Source code

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

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

Source code

1
2
3
4
5
6
7
8
#include "OSManager.h"

typedef void tExceptionHandler(void);
tExceptionHandler*		mExceptionHandler;

...

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

2

Monday, July 16th 2007, 8:53am

Falls es jemanden interessiert:
Wenn man an die Deklaration der ISR-Funktion ein

Source code

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.

Similar threads

Social bookmarks