Forum: Mikrocontroller und Digitale Elektronik STM32: Compilierter Code unterschiedlich groß und Breakpoint nicht setzbar


von Johannes (menschenskind)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich nutze Rowley Crossstudio und habe ein paar merkwürdige Sachen 
festgestellt:
Zum einen wird der compilierte Code aufgebläht, wenn ich die "hw.init()" 
in die if-Abfrage packe und weiterhin kann ich für diesen Schritt keinen 
Breakpoint setzen.
Der Code läuft aber sauber durch beim Debugging. Und die Anweisungen 
innerhalb der init() werden auch alle abgearbeitet bzw. kann ich dort 
Breakpoints setzen.
Evtl. hängen beide Sachen zusammen?

"Hardware" ist meine Hardware-Klasse, in der alle Sub-Hardware-Klassen 
instanziiert werden.

Hannes

von J. S. (jojos)


Lesenswert?

Der zusätzliche Code dürfte vom printf() stammen. Wie sieht es aus wenn 
das if nicht verwendet wird und trotzdem ein print()?

von Johannes (menschenskind)


Lesenswert?

Hi Jojo,
Negativ, Größe bleibt bei ~4KB mit printf()
Das wär doch auch enorm viel für so ne kleine Funktion.

von J. S. (jojos)


Lesenswert?

Dann das mapfile generieren lassen und gucken wo der Speicher verbraten 
wird.

von PittyJ (Gast)


Lesenswert?

Johannes H. schrieb:
> Hi Jojo,
> Negativ, Größe bleibt bei ~4KB mit printf()
> Das wär doch auch enorm viel für so ne kleine Funktion.

Nö, das ist normal.
Da ist doch eine Menge Krams drin, alleine für die Formatbehandlung.

von J. S. (jojos)


Lesenswert?

Bzw wenn der BP nicht gesetzt werden kann dann ist das ein Zeichen das 
der Code wegoptimiert wurde. Dann wäre was mit der Hardware Klasse faul. 
Mit dem if wird der return Wert gebraucht und das init wird eingebaut. 
Dann braucht das init() so viel Speicher.

von Johannes (menschenskind)


Angehängte Dateien:

Lesenswert?

PittyJ schrieb:
> Nö, das ist normal.
> Da ist doch eine Menge Krams drin, alleine für die Formatbehandlung.

Aber die Codegröße BLEIBT doch bei dem niedrigem Wert, wenn ich einfach 
per printf() einen Text ausgebe. 🙁

@Jojo
Meinst Du dieses mit map-File?
Also das mit dem init verstehe ich nicht, denn deren Inhalt wird doch 
angesprungen. Für mich sieht das auch aus, als würde das wegoptimiert, 
deswegen verwirrt mich das auch so.

von Walter T. (nicolas)


Lesenswert?

printf() wird bei einem konstanten String zu einem puts().

von J. S. (jojos)


Lesenswert?

Johannes H. schrieb:
> Meinst Du dieses mit map-File?

ja. Amap ist ein kleines Tool um das etwas übersichtlicher zu machen:
https://www.sikorskiy.net/info/prj/amap/#download

Danach sind .text und .rodata ca. 4 kB groß, da ist vielleicht nur die 
Rowley Anzeige falsch.
Kann auch am Linkerfile liegen das es ein padding zwischen sections gibt 
und dann Luft mitgezählt wird. Mit dem objsize tool der gcc kann man 
auch die Größe anzeigen lassen (wenn Rowley das nicht auch nutzt).

Johannes H. schrieb:
> Also das mit dem init verstehe ich nicht, denn deren Inhalt wird doch
> angesprungen.

ja richtig, hatte ich jetzt überlesen.

: Bearbeitet durch User
von J. S. (jojos)


Lesenswert?

Die verwendete Toolchain ist aber auch sehr alt, 4.8 sagt das mapfile. 
Ist das eine mitgelieferte und kann man die durch eine neuere ersetzen? 
Gerade für C++ würde ich das machen. Die Cortex-M0 werden von gcc auch 
stiefmütterlich behandelt und optimieren schlecht.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Im map-File scheint die größte Adresse im Flash zu sein:
1
0x000000000800110c                __fast_load_start__ = ALIGN (__ARM.exidx_end__, 0x4)
Also ganze 4364 Bytes. Ich vermute auch dass die IDE die Flashnutzung 
falsch anzeigt. Selbst das binutils "size" Tool macht das nicht 
besonders gut. Aufklärung gibt hier, sich die Sections im Detail mittels
1
arm-none-eabi-readelf -S Programmdatei.elf
o.ä. ausgeben zu lassen. In der Ausgabe alles raussuchen was im Bereich 
"08000000" liegt, und die Größe aufsummieren (typischerweise gibt es da 
".text", ".rodata", ".isr_vector" u.a.). Das resultiert in der korrekten 
Flash-Nutzung.

Ca. 1 KB wird für Library-Funktionen benutzt, inkl. printf, malloc und 
Floating-Point-Funktionen.

: Bearbeitet durch User
von Johannes (menschenskind)


Angehängte Dateien:

Lesenswert?

J. S. schrieb:
> Die verwendete Toolchain ist aber auch sehr alt, 4.8 sagt das mapfile.

Nee, 4.8.8 ist die aktuelle Version für die ARM-Entwicklung, die ich 
nutze. Auf was beziehst Du dich da mit dem "sehr alt"?

Danke für die Hinweise zur Speicherberechnung 👍

Gibt es noch Ideen, warum der Breakpoint nicht gesetzt werden kann?
Ich habe mal die hw.init() direkt an den Anfang der main gesetzt.
Nun taucht da plötzlich das kleine blaue Dreieck an der Zeile auf 🤔

Seltsam ist auch, dass beim Überspringen von "SysTick_Config()" mit 
"Step Over", der Debugger immer in die Funktion in der 
"CMSIS_5\CMSIS\Core\Include\core_cm0plus.h" reinspringt, außer ich setze 
einen Breakpoint an anderer Stelle und lass den µC laufen.
Wie kann ich das vermeiden?

von Stefan F. (Gast)


Lesenswert?

Johannes H. schrieb:
> Nee, 4.8.8 ist die aktuelle Version für die ARM-Entwicklung, die ich
> nutze. Auf was beziehst Du dich da mit dem "sehr alt"?

Version 4.8 ist von 2013-2015

Meine wenige Monate alte Cube IDE von ST enthält Version 10.3.1

von J. S. (jojos)


Lesenswert?

Habe es gecheckt, das ist die CrossWorks Version, die enthält gcc 10.3, 
ist also frisch.
Ist die Optimierung im debug build auch aus?

von Johannes (menschenskind)


Lesenswert?

Hi Jojo,

Also ich habe Optimization auf "Debug" gesetzt und das Debugging Level 
auf 3.

@stefanus
Du hast doch das schöne STM-Tutorial gemacht. Hast Du auch ein Szenario, 
wo der Debugger in die SysTick_Config reinspringt?
Die "__Vendor_SysTickConfig" wird ja in der "STM32L011xx.h" definiert 
mit 0 und steht in der Datei bevor "core_cm0plus.h" includiert wird. Der 
Code nach
1
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
 ist bei mir aber ausgegraut, obwohl die Bedingung doch wahr ist.
Hast Du da ne Idee?

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Johannes H. schrieb:
> Hast Du auch ein Szenario,
> wo der Debugger in die SysTick_Config reinspringt?

Habe ich noch nicht probiert, das brauchte ich bisher nicht.

Johannes H. schrieb:
> ist bei mir aber ausgegraut

Bei mir nicht. Ich habe einfach ein Projekt mit Standardvorgaben für den 
STM32L011K4Tx erstellt und diese drei Zeilen eingefügt.

von J. S. (jojos)


Lesenswert?

wenn man nicht sicher ist ob der Code im #if kompiliert wird, dann kann 
man da ein #error einfügen. An der Stelle muss der Compiler dann 
meckern.

von Walter T. (nicolas)


Lesenswert?

Johannes H. schrieb:
> ist bei mir aber ausgegraut, obwohl die Bedingung doch wahr ist.
> Hast Du da ne Idee?

Viele IDE sind nicht besonders gut darin festzustellen, ob Bedingungen 
des Präprozessors erfüllt sind.

Generell lässt sich in SysTick_Config() ganz normal ein Breakpoint 
setzen und hineingucken.

von J. S. (jojos)


Lesenswert?

SysTick_Config ist im Mapfile nicht zu finden, da kocht Rowley 
vielleicht sein eigenes Süppchen. Das define kann ja auch an anderer 
Stelle umgebogen werden.

: Bearbeitet durch User
von Walter T. (nicolas)


Lesenswert?

J. S. schrieb:
> SysTick_Config ist im Mapfile nicht zu finden

Ist static inline.

Bei mir ist es in der core_cm4.h, aber bei anderen MCUs wird es wohl 
woanders liegen.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Wenn die IDE sich weigert Breakpoints zu setzen kann man auch die 
Holzhammermethode anwenden und den Breakpoint manuell im Code setzen mit
1
__BKPT ();
oder
1
__asm__ volatile ("BKPT #0");

Der wird dann garantiert ausgelöst wenn der Code ausgeführt wird.

von J. S. (jojos)


Lesenswert?

Walter T. schrieb:
> Ist static inline.

ok, damit wird aber auch kein Symbol dafür angelegt und dann kann der BP 
da auch nicht gesetzt werden.

von Walter T. (nicolas)


Lesenswert?

Nicht an der Funktion, aber in der dritten Zeile der Funktion. (Die 
erste Zeile wird wegoptimiert.)

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.