STM32CubeIDE Position des Breakpoints in Assembler Code

#6696193
Lesenswert?

Ich habe mich ja als ziemlicher Laie im Benutzen von STM32CubeIDE 
bereits schon geoutet. Jetzt kommt noch folgendes Verständnisproblem:

Ich bin es eigentlich gewohnt, daß bei einem Breakpoint die Anzeige so 
ist, daß der PC auf die als nächste auszuführende Instruktion im 
Programmfluß zeigt.

Beim Versuch, einen Breakpoint in einem Assemblercode-Projekt in 
STM32CubeIDE zu setzen, steht der PC immer hinter dem Befehl. Ist das 
ein Bug im IDE?

(s. Bild)
Angehängte Dateien:
#6696266
Lesenswert?

pegel schrieb:
> In der Disassembly Ansicht kannst Du den Breakpoint auch direkt am
> Befehl setzen. Muss wohl doch so eine Art "Unstimmigkeit" sein.

Unstimmigkeit? Bug. Damit kann man doch nicht arbeiten.
Hier noch mal ein weiteres Beispiel.


In der Tat scheint der Breakpoint in der Disassembly-Ansicht richtig 
gesetzt zu werden. Leider ist die Disassembly Ansicht etwas 
unübersichtlich, durch diese Doppeldarstellung jeder Instruktion.

Sorry, Bild aus Versehen zweimal hochgeladen. Bitte ignorieren.

Es sieht so aus, daß sich die Breakpoints in der Source code Ansicht 
dann "fangen" und auf Zeile sind, wenn man einmal in der Disassembly 
View einen BP gesetzt hat. Löscht man alle und setzt einen neuen BP in 
der Source View, dann fängt das wieder mit dem "eine Zeile versetzten 
BP" an.
Gast #6696299
Lesenswert?

Ja. Scheint ein Problem zu geben.
Vorhin hatte ich direkt nach Reset: eine Kommentarzeile drin, da hat das 
gepasst.
Nach einigen Experimenten habe ich nun auch Versatz.

Keine Ahnung woran das genau liegt. :(
Beitrag #6698181 wurde von einem Moderator gelöscht.
#6698283
Lesenswert?

Jim M. schrieb:
> Christoph K. schrieb:
>> Beim Versuch, einen Breakpoint in einem Assemblercode-Projekt in
>> STM32CubeIDE zu setzen, steht der PC immer hinter dem Befehl. Ist das
>> ein Bug im IDE?
>
> Nö. Schau Dir mal in Ruhe an, was im PC Register eines ARM Cortex-M so
> drin stehen muss während der Befehlsausführung.
>
> Hint: Da steht die Adresse des nächsten Befehls drin...

Der Breakpoint steht vor (auf) dem nächsten auszuführenden Befehl. 
Darauf zeigt auch der PC vor der Befehlsausführung.

Was ich aber moniere, ist, daß der BP in der Anzeige (View) falsch 
steht.
#6698288
Lesenswert?

pegel schrieb:
> Wie sieht es in Assembler bzw. im Linker eigentlich mit der Optimierung
> aus?
> Es ist ja so, das im Debug Fenster die weißen, eingerückten Befehle die
> eigentlich BP sind, nicht erscheinen.


Ich sagte zu jemand an anderer Stelle hier im Forum:

Der Assembler nimmt das Wort des Programmierers sehr ernst. Da wird 
nichts optimiert. Optimieren tut nur der C-Compiler. Assemblerbefehle 
sind in Stein gemeißelt.
#6698345
Lesenswert?

pegel schrieb:
> Wie sieht es in Assembler bzw. im Linker eigentlich mit der Optimierung
> aus?
> Es ist ja so, das im Debug Fenster die weißen, eingerückten Befehle die
> eigentlich BP sind, nicht erscheinen.

Versteh' nicht ganz, was Du meinst. Weiß, eingerückt, sind Labels, keine 
BPs.
Man sieht in meinem Screenshot, daß ich einen BP gesetzt habe auf
1
rstHandler:
2
     sub  r4, pc, #8

Da zeigt auch die "Bubble" hin. Was aber passiert nach dem Start, ist, 
daß das Programm auf Zeile 475 landet:
1
Thread #1 [main] 1 [core: 0] (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)  
2
  defHandler() at ku.s:475 0x194  
3
  <signal handler called>() at 0xfffffff9  
4
  0xfffffffe

capiche?
Gast #6698448
Lesenswert?

Der defHandler() ist doch der handler für ungültige Interrupts und 
diverse Fault Exceptions, oder nicht?

Ich denke, dein Programm ist gar nicht bis zum Breakpoint gekommen, 
sondern schon vorher abgeschmiert.
#6698459
Lesenswert?

Stefan ⛄ F. schrieb:
> Der defHandler() ist doch der handler für ungültige Interrupts und
> diverse Fault Exceptions, oder nicht?
>
> Ich denke, dein Programm ist gar nicht bis zum Breakpoint gekommen,
> sondern schon vorher abgeschmiert.

Ja. Sowas vermute ich auch. Ich sehe gerade in der Source, daß die 
Variable für Mstk (Stack) nicht initialisiert ist (bin im Moment noch 
nicht ganz sicher, aber der Stack sollte im CCM sein). Sowas wie ein 
Double Fault?

Aber es ist doch die erste Instruktion im Programm überhaupt, die 
angesprungen wird und wo cih den BP hingesetzt habe. Vorausgesetzt, der 
Stackpointer ist i.O. und dies sollte er (s. Memory dump in meinem 
Screenshot) doch sein.

(nee, war wohl doch Fehlalarm, was die Nichtinitialisierung von Stack
betrifft). Daß die Addressen alle ungerade gemacht werde (+1) wegen 
thumb
ist OK?

Noch eine Vermutung: der Debugger sagt da: (Suspended: Signal: 
SIGTRAP:Trace/breakpoint trap)

Ist es denn so, daß der Debugger einen Trapvector (breakpoint) in den 
Vectorbereich einpflanzt?
Angehängte Dateien:
Gast #6699230
Lesenswert?

Wie sieht denn der Speicher ab Adresse 0x08000000 aus? Bei einem STM32 
würde ich (sofern am Memory-Mapping nix umgebogen ist) da den Startwert 
des Stackpointers und die Vektortabelle erwarten und nicht bei 0x0.

Gruß,
Michael
#6699631
Lesenswert?

Ich habe noch mal das z.Zt. nicht debugbare Programm hochgeladen.

Was wundert ist nach wie vor, daß

1. im Projekt simple (wo ich den BP setzen kann), die Vektoren (außer 
Stack und Reset) nicht gesetzt sind (obwohl es im source code steht).

2. Den BP konnte ich exakt (im Gegensatz zum nach wie vor gültigen 
Betreff dieses Threads) setzen, weil es in der Disassembly-View offenbar 
exakt geht. Aber setzen im Source View erezugt immer noch noch falsch 
sitzenden BP.

3. daß Projekt ku sich überhaupt nicht debuggen läßt (BP wird nie 
getroffen). Stattdessen landet das Programm direkt in einem der Handler, 
aber eben nicht dort (im rstHandler), wo der BP tatsächlich gesetzt ist.


Das Target ist ein DIYMORE STM32F407
(https://stm32-base.org/boards/STM32F407VGT6-diymore), das am STLINK SWD 
Interface angeschlossen ist mit herausgeführter RST-Leitung, SWCLK, SWIO 
und RST and 2-4-5 des SWD Interfaces angeschlossen.


Wenn jemand das ausprobieren möchte mit den beiden Projekten und mir 
dabei weiterhelfen kann, dem schicke ich gerne ein solches Board. Habe 
noch ein paar davon.

Danke im Voraus.

Grüße
Christoph
Angehängte Dateien:
#6700707
Lesenswert?

Übrigens bin ich jetzt geplättet:

Ich dachte, probierst Du vielleicht mal das Programm (simple.s) direkt 
in die MCU des Discoveryboards zu flashen und siehe da, STM32CubeIDE 
(resp. die MCU) verhält sich richtig, was das Flashen betrifft.

Der Vector-Bereich wird vollständig geflasht.

Ist die MCU auf dem DIYMORE fehlerhaft? Es gab ja schon mal solche 
Andeutungen.
Angehängte Dateien:
#6701129
Lesenswert?

Ich komme langsam zu der Vermutung, daß mein Hauptproblem die Memory Map 
ist, in der der Flash auf 0x00000000 gelegt ist. Das scheint dem 
gdbserver nicht zu schmecken. Es sieht so aus, also ob dann der 
Vector-Bereich gar nicht programmiert wird. Weiß nicht, ob man dem ld 
sagen kann, daß er zwar den .text auf 0 mappen soll, allerdings den 
Vectorbereich aussparen soll.

Kennt der GDB vielleicht noch andere Codebereiche? Ich bin im Moment 
ratlos.

Eigentlich müßte ich für das Problem einen eigenen Thread aufmachen, 
denn das eigentliche Problem in der Titelzeile besteht ja weiterhin, ist 
allerdings in den Hintergrund getreten. Ich habe es mal in der 
ST-Community themtisiert. Vielleicht wird es als Bug anerkannt und 
jemand kümmert sich drum.
#6701768
Lesenswert?

Stefan ⛄ F. schrieb:
> Über das SCB->VTOR Register kann man den Ort der Vektortabelle
> festlegen. Vielleicht musst du das machen.

SCB->VTOR ist etwas im C-Startupcode? Ich habe ja keine 
startup-Umgebung. Nackter Assemblercode. Ich könnte es noch mal mit 
OpenOCD als Debugserver im STM32Cube versuchen, aber ähnliche Probleme 
hatte ich ja schon bei meinen Commandline GDB/OpenOCD Versuchen.

Das Programm läßt sich als BIN-File mit

st-flash write kernel.bin 0x08000000

problemlos flashen und läuft auch. Nur debuggen kann ich es nicht in 
dieser Konfiguration.
#6701815
Lesenswert?

Stefan ⛄ F. schrieb:
> Christoph K. schrieb:
>> SCB->VTOR ist etwas im C-Startupcode?
>
> Das ist ein Register.

OK. Im PM0214, Kap. 4.4.4 gefunden. Das aber hieße, ich müßte mein 
Programm modifizieren, nur damit ich es debuggen kann? Und der Befehl 
kann ja erst ausgeführt werden, wenn mein Programm dahinkommt. Was ist, 
wenn ich vorher einen BP setzen will? Das ist ein Henne-Ei-Problem :).

Das kann's nicht sein.
#6701821
Lesenswert?

Johannes S. schrieb:
> Was ist mit dem Tipp vorher von Stefan, das ein Fault ausgelöst wird?
> Durch singlestep sollte sich die Position doch rausfinden lassen.

Der Fault ist von Anfang an da. Ich komme nicht in den rstHandler, 
sobald ich den Debugee starte (Käfer).

Das könnte ja ein Hard Fault (Double Fault) sein, wenn z.B. der Stack 
nicht initialisiert oder falsch initialisiert ist. Aber der Grund 
erschließt sich mir nicht. Allenfalls, wenn GDB 'denkt' (beim Laden des 
.elf Images): Aha, das soll nach 0x00000000. Also Programm? Da rühre ich 
die Vektoren nicht an.

Ich müßte dem Linker sagen können: linke mir den Code relativ zu Adresse 
0, aber lade ihn auf 0x08000000.
Gast #6701900
Lesenswert?

ok, Bildschirmfoto geht. Argh, die liegen automagisch im Bilderordner. 
Zu einfach für einen Informatiker :)

das sind die Settings für BMP. Unten ist noch das 'set Breakpoint at', 
das steht per default auf main.

das ist für BMP, für STLink dann nur die erste Zeile:
1
 set mem inaccessible-by-default off
2
target extended-remote /dev/ttyACM0
3
shell sleep 2
4
mon swd scan
5
attach 1
#6701943
Lesenswert?

Johannes S. schrieb:
> ok, Bildschirmfoto geht. Argh, die liegen automagisch im Bilderordner.
> Zu einfach für einen Informatiker :)
>
> das sind die Settings für BMP. Unten ist noch das 'set Breakpoint at',
> das steht per default auf main.
>
> das ist für BMP, für STLink dann nur die erste Zeile:
>
>
1
>  set mem inaccessible-by-default off
2
> target extended-remote /dev/ttyACM0
3
> shell sleep 2
4
> mon swd scan
5
> attach 1
6
>

Ach, da sind sie ja wieder, die alten Bekannten. Danke für den 
Hinweis.Werde da mal forschen.
Gast #6701946
Lesenswert?

Stefan ⛄ F. schrieb:
> Siehst du: Erst wird kritisiert, dass Linux für normale User zu
> kompliziert sei, und jetzt ist es zu einfach geworden.

naja teilweise. Das schnelle kompilieren unter Linux irritiert mich 
auch, ich weiß nie ob es jetzt schon ausgeführt wurde :) Aber das 
bisschen Assembler geht natürlich unter Windows auch fix. Und schön das 
es vieles schon Mulit-Kulti gibt.

Christoph K. schrieb:
> Ach, da sind sie ja wieder, die alten Bekannten. Danke für den
> Hinweis.Werde da mal forschen.

wie gesagt, wichtiger wäre das 'set Breakpoint at'.
Und der µC könnte sich natürlich noch daran stören wohin welche sections 
geladen werden, aber normalerweise meckert der gdb dann schon. Auch in 
der IDE wird der verwendet, die IDE versteckt das ja nur.
Gast #6701975
Lesenswert?

der Submenu Pfeil rechts neben dem Käfer, Debug Configurations. Die für 
STLink müsste existieren und kann bearbeitet werden. Meine habe ich über 
das Menu neu angelegt, als 'GDB Hardware Debugging'
#6702024
Lesenswert?

Johannes S. schrieb:
> der Submenu Pfeil rechts neben dem Käfer, Debug Configurations. Die für
> STLink müsste existieren und kann bearbeitet werden. Meine habe ich über
> das Menu neu angelegt, als 'GDB Hardware Debugging'

OK. Man kommt ja auch über die Properties dahin. Aber ich habe gar nicht 
die Möglichkeit, da einen "GDB-Command" einzugeben, geschweige denn 
irgendwelche weiteren Befehle einzugeben.

Interessant ist der Punkt "Use Download Offset", den ich auch beim 
Editieren der Konfiguration (im Startup-Tab) einstellen kann. Allerdings 
hat der nicht den erhofften Effekt auf den Vectorbereich.

Habe den Fehler jetzt auch in der MCU des DISC1, also Chip/MCU auf dem 
DIYMORE außen vor.

Und er läuft jetzt nicht in den defaultHandler sondern in den 
stkHandler.
Angehängte Dateien:
#6702085
Lesenswert?

Stefan ⛄ F. schrieb:
> Christoph K. schrieb:
>> OK. Man kommt ja auch über die Properties dahin. Aber ich habe gar nicht
>> die Möglichkeit, da einen "GDB-Command" einzugeben, geschweige denn
>> irgendwelche weiteren Befehle einzugeben.

Was hast Du für ein SMT32CubeIDE? Für Linux? Ich habe gar keine andere 
Möglichkeit als über STLINK (GDB server), Segger oder ST-LINK(OpenOCD) 
zu verbinden. Meine STM32CubeIDE 1.6.1 ist für macOS. Vielleicht kann 
ich es nachher mal an Ubuntu probieren.
Angehängte Dateien:
#6702168
Lesenswert?

Johannes S. schrieb:
> einen Tab weiter ist doch 'Startup'
> 1.6.1 ist schon die gleiche Version unter Windows, Linux, Mac. Ein Java
> eben.

Den Startup-Tab sehe ich wohl und ich habe dort auch den Run-Command
arm-none-eabi-gdb eingetragen. Nur - und das sollte der Screenshot des 
Debugger-Tabs zeigen, sind mir da nur 3 Möglichkeiten gegeben, zu einem 
Debugger zu verbinden.

Übrigens, wenn man über die Project->Properties->Run/Debug Edit Launch 
configuration properties in den Startup-Tab geht, ist die Textbox "Run 
Commands" für die Eingabe gesperrt.
#6702335
Lesenswert?

Stefan ⛄ F. schrieb:
> Christoph K. schrieb:
>> Den Startup-Tab sehe ich wohl und ich habe dort auch den Run-Command
>> arm-none-eabi-gdb eingetragen
>
> Ich bin ziemlich sicher, dass du da nicht den Debugger angeben sollst,
> sondern Kommandos die an den Debugger gesendet werden.

Ja, hast recht. Ich hatte noch nicht die richtige GDB-Konfiguration 
gefunden. Und bin auch jetzt immer noch auf'm Holzweg. Ich muß doch eine 
(blaue) IDE-Debugkonfiguration kreieren, oder?

Offenbar doch eine GDB-Hardware Debugging Konfiguration? Wenn ich die 
GDB Hardware Debugging Konfiguration starte, passiert gar nichts. Bin 
jetzt ratlos.
#6702366
Lesenswert?

Stefan ⛄ F. schrieb:
> Christoph K. schrieb:
>> Hatte übersehen, daß man in der Verwaltung der
>> Debug-Konfigurationen
>> "GDB-Hardware Debugging" auswählen mußte.
>
> Hmm, ich habe/nutze immer Projekt spezifische Einstellungen, die werden
> nämlich beim Klick auf den grünen Käfer automatisch angelegt.

Wenn ich auf den grünen Käfer direkt klicke, wird immer die blaue IDE 
Konfiguration gestartet:
1
STMicroelectronics ST-LINK GDB server. Version 5.8.0
2
Copyright (c) 2020, STMicroelectronics. All rights reserved.
3

4
Starting server with the following options:
5
        Persistent Mode            : Disabled
6
        LogFile Name               : /Users/kuku/STM32CubeIDE/workspace_1.4.0/ku/st-link_gdbserver_log.txt
7
        Logging Level              : 31
8
        Listen Port Number         : 61234
9
        Status Refresh Delay       : 15s
10
        Verbose Mode               : Enabled
11
        SWD Debug                  : Enabled
12

13
Target connection mode: Attach
14
Reading ROM table for AP 0 @0xe00fffd0
15
Hardware watchpoint supported by the target 
16
COM frequency = 4000 kHz
17
ST-LINK Firmware version : V2J37M27
18
Device ID: 0x413
19
PC: 0x1
20
ST-LINK device status: RUN_MODE
21
ST-LINK detects target voltage = 2.92 V
22
ST-LINK device status: RUN_MODE
23
ST-LINK device initialization OK
24
Waiting for debugger connection...
25
Waiting for connection on port 61234...
26
Accepted connection on port 61234...
27
Debugger connected
28
Try halt...
29
ST-LINK device status: HALT_MODE
30
Enter STM32_AppReset() function 
31
NVIC_DFSR_REG = 0x00000008
32
NVIC_CFGFSR_REG = 0x00000000
33
Debugger connection lost.
34
Shutting down...
#6709727
Lesenswert?

Bin nach einiger Forschung noch mal zurück hier. Das eigentliche Thema 
besteht nach wie vor. Aber einige wesentliche Ungereimtheiten konnte ich 
lösen.

1. Je nachdem, ob ich defHandler oder rstHandler als erste Adresse im 
Code stehen hatte, sprang das Programm nach Start sofort dorthin (auf 
die Erstere von beiden). Ist wohl bei .ELF-Files auch normal, wenn man 
keinen ENTRY angibt.

2. Debug-Konfiguration muß in der Startup-Sektion so eingestellt sein:

  Start Address:  Specify Vector Table: 0x00000000

  Set BreakPoint: rstHandler

  Halt on Exception  [X] (muß vielleicht nicht)

  Resume [X]

3. Im Debugger: Connect under Reset.

Das war jetzt alles erst mal getestet unter dem STLINK/V2 auf dem 
STM32F407-DISC1 board mit Debuggee in der onboard MCU.

Meine Loader-Map, die die spezielle Situation berücksichtigt, daß das 
Programm im Adressraum 0x00000000 (und nicht 0x08000000) läuft, sieht 
nun so aus:
1
MEMORY
2
{
3
        FLASH (rx)  : ORIGIN = 0x08000000, LENGTH = 1024K
4
        FLASH_ALIAS (rx)  : ORIGIN = 0x00000000, LENGTH = 1024K
5
        CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
6
        SRAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 128K
7
}
8

9
SECTIONS
10
{
11
        .text   : {
12
                    flashend = 0x00100000 ;
13
                    ccmbgn   = 0x10000000 ;
14
                    ccmend   = 0x10010000 ;
15
                    srambgn  = 0x20000000 ;
16
                    sramend  = 0x20020000 ;
17
                    *(.text)
18
                  } > FLASH_ALIAS AT > FLASH
19
        .bss    : { *(.bss)  } > CCMRAM
20
        .sram   : { *(.sram) } > SRAM
21
}

ENTRY brauche ich bei der Methode nicht zu berücksichtigen, da der 
Debugger
sich des Vectors bedient. Mag sein, daß es andere Wege gibt, aber dieser 
funktioniert jetzt. Danke noch mal für die Mithilfe.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren