Forum: Mikrocontroller und Digitale Elektronik STM32F407VG-Codeblocks-Linux Projekt - Globale Objekte funktionieren nicht? Was tun??


von Daniel F. (franken_3)


Angehängte Dateien:

Lesenswert?

Hallo,

mein Ziel ist es seit einiger Zeit, unter Linux mit C++ und CodeBlocks 
das STM32F407VG DISCOVERY Board zu programmieren (und am besten auch zu 
Debugen).

Ich bin jetzt soweit, das ich ein lauffähiges C-Programm habe, das auch 
von Linux aus auf dem STM32 laden kann, nur habe ich noch ein kurioses 
Problem.

C-Code funktioniert Problemlos, aber wenn ich in C++ Objekte erstelle, 
funktionieren diese nach dem laden des Programms auch, solange ich Sie 
innerhalb der Main-Funktion erstellt habe. Global erstellte hingegen 
arbeiten nicht??

Habe nach einiger Suche gelesen, man muss im Make-File folgendes 
Eintragen:

...make sure to enable C++ Support in makefile - without that switch 
your global constructors/destructors will not be called!
1
# set to 1 to compile and link additional code required for C++
2
USES_CXX=0


Nun verwendet CodeBlocks aber standardmäßig keine Makefiles, sonder ihre 
.cbp Datein des Projektes.

Weis jemand wo ich das den einstellen kann in CodeBlocks???
Hab schon alles mögliche Versucht, aber ich finde den Schalter nicht :/

Habe mal mein Projekt hier im Anhang, vielleicht kann es ja mal jemand 
von euch, der Ahnung hat, durchschauen.

Möglicherweise ist auch noch was anderes im argen, aber wie gesagt, 
C-Code und lokale Objekte laufen ja schon wie gewollt.


Danke schon mal an alle

von drama (Gast)


Angehängte Dateien:

Lesenswert?

Daniel Frank schrieb:
> C-Code funktioniert Problemlos, aber wenn ich in C++ Objekte erstelle,
> funktionieren diese nach dem laden des Programms auch, solange ich Sie
> innerhalb der Main-Funktion erstellt habe. Global erstellte hingegen
> arbeiten nicht??

Definiere "funktioniert nicht". Was genau heißt das?

Deine Problembeschreibung deutet i.A. auf ein Linker-Script hin, das die 
Initialisierung von statischen C++-Objekten nicht implementiert.

Schaue dir mal das angehängte Script an.

von Daniel F. (franken_3)


Lesenswert?

Hallo,

Danke für das Script. Habe es mal in mein Projekt eingebunden, bekomme 
aber leider beim Linken folgende Fehlermeldung

/usr/lib/gcc/arm-none-eabi/4.8.2/../../../arm-none-eabi/bin/ld:/home/sea 
n/Programmierung/STM32-Linux/iCBox//linker/sections_flash.ld:17: 
warning: memory region `FLASH' not declared
/usr/lib/gcc/arm-none-eabi/4.8.2/../../../arm-none-eabi/bin/ld:/home/sea 
n/Programmierung/STM32-Linux/iCBox//linker/sections_flash.ld:76: 
warning: memory region `RAM' not declared
obj/Release/startup_stm32f4xx.o:(.isr_vector+0x0): undefined reference 
to `_estack'
collect2: error: ld returned 1 exit status

Hast du vielleicht noch ein passendes startup-file zu dem linker-Script?
Danke

Mit "funktioniert nicht" meine ich, dass das Programm sich verhält, als 
hätte ich das Objekt einfach nicht erzeugt. Im Beispiel soll das Objekt 
mit einer Mehtode eine LED anschalten, diese bleibt aber leider aus wenn 
das Objekt außerhalb von main erzeugt wird.

von drama (Gast)


Lesenswert?

Daniel Frank schrieb:
> Danke für das Script. Habe es mal in mein Projekt eingebunden, bekomme
> aber leider beim Linken folgende Fehlermeldung

Das ist ein generisches Script, da fehlen dann natürlich Informationen 
dazu, wieviel Flash und RAM dein MCU hat und wo die liegen. Kombinier 
das mit deinem existierenden Linkerscript oder nutze Includes.

von Daniel F. (franken_3)


Lesenswert?

Ich habe nun mal mein orginales Linker-Skript mit dem generic 
Verglichen.

Dabei sind mir einige Unterschiede aufgefallen.

im Linkerskript meines Projektes sind enthalen:

*(.glue_7)
*(.glue_7t)

In einem noch ganz anderen Script habe ich dies gefunden:

_ctors_start_ = .;
  KEEP(*(.init_array));      /* C++ constructors */
  KEEP(*(.ctors));      /* C++ constructors */
  _ctors_end_ = .;


Das KEEP(*(.ctors)); fehlt bei mir ganz??

Außerdem gibt es einen ganzen Block der im generic nicht enthalen ist

/* User_heap_stack section, used to check that there is enough RAM left 
*/
  ._user_heap_stack :
  {
    . = ALIGN(4);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(4);
  } >RAM

  /* MEMORY_bank1 section, code must be located here explicitly 
*/
  /* Example: extern int foo(void) _attribute_ ((section 
(".mb1text"))); */
  .memory_b1_text :
  {
    *(.mb1text)        /* .mb1text sections (code) */
    *(.mb1text*)       /* .mb1text* sections (code)  */
    *(.mb1rodata)      /* read-only data (constants) */
    *(.mb1rodata*)
  } >MEMORY_B1


Weis jemand was jetzt der Grund sein könnte das globale Objekte nicht 
erstellt werden??

PS: Gibt es irgendeine Möglichkeit sich in das Thema Linkerskripte 
einzulesen? Ich würde mich gerne näher mit dem Thema beschäftigen um 
mehr über den STM32F4 zu erfahren.

Aktuell habe ich keinen Dunst was die Zeilen oben bedeuten sollen??

Danke schon mal an alle,

von drama (Gast)


Lesenswert?

Interessant/Relevant sind vor allem die Teile für C++:
1
    /* Static constructor initialization (C++) */
2
    .preinit_array :
3
    {
4
        PROVIDE_HIDDEN (__preinit_array_start = .);
5
        KEEP (*(.preinit_array*))
6
        PROVIDE_HIDDEN (__preinit_array_end = .);
7
    } >FLASH
8
    .init_array :
9
    {
10
        PROVIDE_HIDDEN (__init_array_start = .);
11
        KEEP (*(SORT(.init_array.*)))
12
        KEEP (*(.init_array*))
13
        PROVIDE_HIDDEN (__init_array_end = .);
14
    } >FLASH
15
    .fini_array :
16
    {
17
        PROVIDE_HIDDEN (__fini_array_start = .);
18
        KEEP (*(SORT(.fini_array.*)))
19
        KEEP (*(.fini_array*))
20
        PROVIDE_HIDDEN (__fini_array_end = .);
21
    } >FLASH

Sowas o.ä. sollte in deinem Script stehen.

von Daniel F. (franken_3)


Lesenswert?

Danke für den Hinweis.

Die oben genannten Sektionen sind bereits alle im Skript enthalten, 
leider immer noch keine Veränderung?

Kann es doch sein, das auch noch im StartUp File irgendetwas eingetragen 
werden muss für libstc++?

Habe ein anderes Projekt im Internet gefunden, da ist im StartUp-File 
folgendes enthalten was in meinem aktuellen StartUp File nicht drin ist:
Kann es daran liegen? Kann es leider erst heute Abend selbst testen
1
/*
2
+-----------------------------------------------------------------------------+
3
| Call C++ destructors for global and static objects
4
+-----------------------------------------------------------------------------+
5
*/
6
#ifdef __USES_CXX
7
  ldr    r0, =__libc_fini_array
8
  blx    r0
9
#endif

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

/* Pointers to end of data for dynamic memory management */
    PROVIDE (end = _ebss);
    PROVIDE (_end = _ebss);

    /* Remove debugging from standard libraries */
    DISCARD :
    {
        libc.a (*)
        libm.a (*)
        libgcc.a (*)
    }


Tut das hier not? Ich glaube langsam es geistern für das gleiche Board 
dutzen de Versionen des Linker Scriptes herum? :-(

von temp (Gast)


Lesenswert?

Die fehlenden Destruktoren sollten wohl nicht das Problem sein. Da 
fehlen sicher die Konstruktoren. Die werden üblicherweise von:

   __libc_init_array();

aufgerufen. So was muss in deinem Code zu finden sein und auch nicht 
durch #ifdefs disabled sein. Wenn es aktiviert ist und kein Linkerfehler 
auftritt, sollte das Linkerscript auch passen. Zur Not kann man den 
Aufruf auch als erstes in die main() schreiben.

von Daniel F. (franken_3)


Lesenswert?

Hi,

ich habe jetzt vermutlich den Fehler gefunden.
Da ich mir mein Projekt oben aus Internet-Beispielen zusammenkopiert 
habe, und ich ja von den Asembler-Sachen und Linkerscript bisher kaum 
eine Ahnung habe, ist mir eine Auskommentierte Zeile untergeschoben 
worden.


Habe gerade folgendes in meiner StartUp.S Datei gefunden:

1
/* Call the clock system intitialization function.*/
2
  bl  SystemInit   
3
/* Call static constructors */
4
//    bl __libc_init_array
5
/* Call the application's entry point.*/
6
  bl  main
7
  bx  lr    
8
.size  Reset_Handler, .-Reset_Handler

Die Zeile

bl __libc_init_array

ist auskommentiert. Denke mal das erklärt einiges...

Danke für die Hilfe!!!!
1
Tut das hier not? Ich glaube langsam es geistern für das gleiche Board 
2
dutzen de Versionen des Linker Scriptes herum? :-(

Keine Ahnung, es ist wohl wirklich so. Jeder kocht da sein eigenes 
Süppchen... :D



PS: Konnte es eben testen, jetzt funktioniert es. Also wer ein 
Linux-Codeblocks-STM32F4 Projekt aufsetzen möchte, einfach oben das 
Projekt nehmen und die Änderung in der startup Datei machen.

Danke an alle nochmals!!

: Bearbeitet durch User
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.