Forum: Mikrocontroller und Digitale Elektronik gdb breakpoint setzen


von Christoph K. (chriskuku)


Lesenswert?

Ich habe irgendwie noch initiale Verständnisprobleme in der Benutzung 
von GDB und Debuggen von STM32-Programmen.

Ich wollte durch das geflashte Programm steppen.

Der Vector-Bereich sieht so aus:
1
(gdb) x/20x 0
2
0x0:   0x20000330  0x00003a57  0x00003897  0x00003897
3
0x10:  0x00003897  0x00003897  0x00003897  0x00000000

Ich vermute, die Reset-Einsprungadresse ist ungerade, um den 
Thumb-Instruktionssatz einzuschalten (oder wie wäre die richtige 
Formulierung?)

Jetzt würde ich gerne einen Breakpoint im Reset-Code setzen:
1
(gdb) b *0x3a56
2
Breakpoint 1 at 0x3a56

Aber gdb hält dort nicht an. Was mache ich falsch? Das Programm loopte 
an einer anderen Stelle herum (wie schon mal in einem frühren Thread 
beschrieben). Also unterbrach ich gdb mit ^C.
1
Program received signal SIGINT, Interrupt.
2
0x0000153a in serial_emit ()
3
(gdb) quit
4
A debugging session is active.
5
6
  Inferior 1 [Remote target] will be detached.
7
8
Quit anyway? (y or n) y
9
Detaching from program: /Users/kuku/Downloads/mecrisp-stellaris-2.5.4a/stm32f407/firmware.elf, Remote target
10
Ending remote debugging.


Starte ich jetzt gdb wieder, bekomme ich:
1
GNU gdb (GNU Tools for Arm Embedded Processors 8-2018-q4-major) 8.2.50.20181213-git
2
Copyright (C) 2018 Free Software Foundation, Inc.
3
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
4
This is free software: you are free to change and redistribute it.
5
There is NO WARRANTY, to the extent permitted by law.
6
Type "show copying" and "show warranty" for details.
7
This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi".
8
Type "show configuration" for configuration details.
9
For bug reporting instructions, please see:
10
<http://www.gnu.org/software/gdb/bugs/>.
11
Find the GDB manual and other documentation resources online at:
12
    <http://www.gnu.org/software/gdb/documentation/>.
13
14
For help, type "help".
15
Type "apropos word" to search for commands related to "word".
16
0x0000153a in serial_emit ()
17
(gdb)

Wieso merkt sich gdb die Stelle der letzten Unterbrechung? Ich habe den 
Eindruck, daß gdb dort wieder weitermacht, wenn ich es neu starte und 
c(ontinue) eingebe.

Ich krieg's einfach nicht hin, durch mein Programm zu steppen.

Gebe ich mal s ein, so steppt das Programm gleich mehrfach:

Es folgt noch mal ein Mitschnitt meiner verzweifelten Versuche:
1
GNU gdb (GNU Tools for Arm Embedded Processors 8-2018-q4-major) 8.2.50.20181213-git
2
Copyright (C) 2018 Free Software Foundation, Inc.
3
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
4
This is free software: you are free to change and redistribute it.
5
There is NO WARRANTY, to the extent permitted by law.
6
Type "show copying" and "show warranty" for details.
7
This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi".
8
Type "show configuration" for configuration details.
9
For bug reporting instructions, please see:
10
<http://www.gnu.org/software/gdb/bugs/>.
11
Find the GDB manual and other documentation resources online at:
12
    <http://www.gnu.org/software/gdb/documentation/>.
13
14
For help, type "help".
15
Type "apropos word" to search for commands related to "word".
16
0x0000153a in serial_emit ()
17
(gdb) b *0x08003a56
18
Breakpoint 1 at 0x8003a56
19
(gdb) c
20
Continuing.
21
Note: automatically using hardware breakpoints for read-only addresses.
22
23
^C
24
Program received signal SIGINT, Interrupt.
25
0x0000158c in serial_qemit ()
26
(gdb) s
27
Single stepping until exit from function serial_qemit,
28
which has no line number information.
29
halted: PC: 0x0000158e
30
halted: PC: 0x00001590
31
halted: PC: 0x00001592
32
halted: PC: 0x00001594
33
halted: PC: 0x00001598
34
halted: PC: 0x00001536
35
0x00001536 in serial_emit ()
36
(gdb) s
37
Single stepping until exit from function serial_emit,
38
which has no line number information.
39
halted: PC: 0x00001538
40
halted: PC: 0x0000153a
41
halted: PC: 0x00001532
42
halted: PC: 0x00001580
43
44
^C
45
Program received signal SIGINT, Interrupt.
46
0x00001598 in serial_qemit ()
47
(gdb)

(Anm.: daß ich jetzt versucht hatte, auf 0x08003a56 einen BP zu setzen,
 war ein zusätzlicher Versuch. Ursprünglich hatte ich versucht, den BP 
auf 0x3a56  bzw. 0x3a57 zu setzen.)

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Was hast du denn als Anbindung an deinen STM32?

Ich vermisse da irgendwie ein "target extended-remote ..."-Kommando, mit 
dem dann über den STlink (oder was auch immer du benutzt) auf einen 
GDB-Server zugegriffen werden kann.

Du willst ja schließlich das Programm auf dem Controller debuggen, 
nichts, was irgendwie direkt auf deinem Host läuft.

ps: Wenn du ein ELF-File mit Debuginformationen hast, ist es allemal 
einfacher, symbolisch zu arbeiten, also "b main", damit nur der 
Startupcode bis zum Anfang von main() abgearbeitet wird.

Aber "target extended-remote :<portnummer>" brauchst du schon irgendwie. 
Möglicherweise steckt das aber in deiner .gdbinit?

: Bearbeitet durch Moderator
von Christoph K. (chriskuku)


Lesenswert?

Jörg W. schrieb:
> Was hast du denn als Anbindung an deinen STM32?
>
> Ich vermisse da irgendwie ein "target extended-remote ..."-Kommando, mit
> dem dann über den STlink (oder was auch immer du benutzt) auf einen
> GDB-Server zugegriffen werden kann.
>
> Du willst ja schließlich das Programm auf dem Controller debuggen,
> nichts, was irgendwie direkt auf deinem Host läuft.
>
> ps: Wenn du ein ELF-File mit Debuginformationen hast, ist es allemal
> einfacher, symbolisch zu arbeiten, also "b main", damit nur der
> Startupcode bis zum Anfang von main() abgearbeitet wird.
>
> Aber "target extended-remote :<portnummer>" brauchst du schon irgendwie.
> Möglicherweise steckt das aber in deiner .gdbinit?

Hallo Jörg,

ich habe in ~/.gdbinit:

file firmware.elf
target remote localhost:4242
load firmware.elf

(hatte aber eben die Zeile "load firmware.elf" auskommentiert)

Und openOCD läuft. Kein C sondern Assembler. :) ABer trotzdem danke für 
den Hinweis. Auch der Assembler-Code hat natürlich Symbole und

b Reset funktioniert natürlich bequemer:
1
(gdb) b Reset
2
Breakpoint 1 at 0x3a56
3
(gdb) c
4
Continuing.

Aber er trifft den BP nicht.



Grüße
Christoph

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

OK, das sieht man leider in GDBs Startmeldungen nicht.

GDB "merkt" sich übrigens in diesem Falle nichts, sondern wenn du das 
anhälst, dann ist es einfach die Information aus dem Controller selbst, 
die er dir da anzeigt.

Vor dem "load" mache ich grundsätzlich ein "monitor reset halt", damit 
die CPU erstmal auf Anfang steht. Gestartet wird anschließend (im 
Gegensatz zum Host-GDB) nicht mit "r(un)", sondern mit "c(ontinue)".

Ich würde dir empfehlen, diese Kommandos erstmal nicht per .gdbinit 
auszuführen, sondern manuell, bis alles soweit funktioniert, wie du das 
willst. Das kannst du dann auch beliebig oft bei laufendem GDB neu 
ausführen, also "mon reset halt", "load", "continue". Du kannst auch 
zwischendrin ein "detach" machen, dann den OpenOCD anhalten, neu 
starten, was auch immer, danach ein neues "target extended-remote 
:4242". ("extended-remote" scheint gegenüber "remote" mittlerweile zu 
bevorzugen zu sein, sagte mir jedenfalls mein GDB immer mal wieder.)

Persönliche Feststellung von mir (weiß nicht, ob ich da was falsch 
mache): eine geänderte ELF-Datei (extern neu compiliert) wird nicht 
sauber neu geflasht, wenn ich den GDB nicht zwischendrin mit "file" 
(ohne Argumente) dazu bringe, die alte Datei komplett zu vergessen, um 
sie danach mit "file firmware.elf" neu bekannt zu machen. Habe 
jedenfalls schon ein paarmal bemerkt, dass ansonsten im Flash noch das 
alte Image herum dümpelte.

Ein wichtiger Unterschied zwischen der Steuerung über GDB und dem 
normalen Bootprozess ist übrigens, dass der GDB nach dem Reset beim 
Entrypoint aus dem ELF-File startet. Den sollte man also explizit 
setzen, entweder über den Linkerscript oder über -Wl,--entry=. Wenn der 
Controller ohne GDB bootet, nimmt er dagegen die Adresse aus dem zweiten 
Slot der Vektortabelle.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Christoph K. schrieb:

> Und openOCD läuft. Kein C sondern Assembler. :)

Uff, wer macht denn sowas? :)

Ich kann den Assemblercode vom Cortex-M zwar ganz brauchbar lesen, aber 
das selbst zu schreiben grenzt an Masochismus. ;-)

von Christoph K. (chriskuku)


Lesenswert?

Jörg W. schrieb:
> Christoph K. schrieb:
>
>> Und openOCD läuft. Kein C sondern Assembler. :)
>
> Uff, wer macht denn sowas? :)
>
> Ich kann den Assemblercode vom Cortex-M zwar ganz brauchbar lesen, aber
> das selbst zu schreiben grenzt an Masochismus. ;-)

Ja, das stimmt :) Aber ich habe ein Projekt übernommen, in dem ein 
Freund (†) eine Meßgerätesteuerung komplett in Forth von Grund auf 
hochgezogen hat. Das System beinhaltet multi-threading und 
multi-tasking. Ehe ich mich an das Projekt heranmache, übe ich etwas mit 
mecrisp-stellaris-forth. Bin ja selbst mit Forth aufgewachsen. Hatte 
1982 ein Forth für den 68000 entwickelt (portiert, fig-Forth 83) und 
eigene Meßgerätesteuerungen damit gebaut.

Die -Wl,--entry= Option ist eine gas Anweisung? Ach so, ne, ld.
Besagt, daß kein Entrypoint erzeugt wird?

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

OK, das ist eine FORTH-Umgebung. Gut, das ist natürlich dann nochmal was 
anderes.

Habe ich lange nicht mehr in den Fingern gehabt, das letzte Mal wohl 
beim FreeBSD-Bootloader.

Christoph K. schrieb:
> Die -Wl,--entry= Option ist eine gas Anweisung?

Nein, das war jetzt für den GCC. "-Wl" besagt dabei, dass er das 
nachfolgende direkt an den Linker weitergeben soll, "--entry" ist eine 
Anweisung für den Linker.

> Besagt, daß kein Entrypoint erzeugt wird?

Ja. :)
Eigentlich sollst du natürlich nach dem --entry= das Symbol für den 
Startpunkt angeben, denn das nimmt der GDB beim Start der Firmware nach 
einem Reset.

von Christoph K. (chriskuku)


Lesenswert?

Jörg W. schrieb:
...
> Eigentlich sollst du natürlich nach dem --entry= das Symbol für den
> Startpunkt angeben, denn das nimmt der GDB beim Start der Firmware nach
> einem Reset.


Das wäre in meinem Fall das Label "Reset" bei 0x3a56.
Sollte ich das vielleicht dem ld mitteilen?

Woher nimmt er denn den SP, wenn der Bootprozeß nicht hardwaremäßig 
verläuft?

von Johannes S. (Gast)


Lesenswert?

Christoph K. schrieb:
> Woher nimmt er denn den SP, wenn der Bootprozeß nicht hardwaremäßig
> verläuft?

SP setzen ist üblicherweise der erste Befehl im Reset handler vom 
startup code:
1
Reset_Handler:  
2
  ldr   sp, =_estack         /* set stack pointer */
Und das _estack in diesem Fall kommt aus dem Linkerscript.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Christoph K. schrieb:

> Das wäre in meinem Fall das Label "Reset" bei 0x3a56.
> Sollte ich das vielleicht dem ld mitteilen?

Ja.

> Woher nimmt er denn den SP, wenn der Bootprozeß nicht hardwaremäßig
> verläuft?

Gute Frage. :-)
1
(gdb) mon reset halt
2
(gdb) load
3
Loading section .text, size 0x17214 lma 0x0
4
Loading section .ARM.exidx, size 0x8 lma 0x17214
5
Loading section .relocate, size 0xa80 lma 0x1721c
6
Start address 0x29e8, load size 97436
7
Transfer rate: 9 KB/sec, 12179 bytes/write.
8
(gdb) si
9
0x000029ea in Reset_Handler () at board_cstartup_gnu.c:210
10
210          if (pSrc != pDest) {
11
(gdb) info reg
12
r0             0x601               1537
13
r1             0x3                 3
14
r2             0x1721c             94748
15
r3             0x602               1538
16
r4             0x0                 0
17
r5             0x20000e9b          536874651
18
r6             0x200030cb          536883403
19
r7             0x0                 0
20
r8             0x200000d0          536871120
21
r9             0x20002fec          536883180
22
r10            0x160c8             90312
23
r11            0x1                 1
24
r12            0x8                 8
25
sp             0x20003138          0x20003138
26
lr             0x387d              14461
27
pc             0x29ea              0x29ea <Reset_Handler+2>
28
xPSR           0x1000000           16777216
29
msp            0x20003138          0x20003138
30
psp            0xfffffffc          0xfffffffc
31
primask        0x0                 0
32
basepri        0x0                 0
33
faultmask      0x0                 0
34
control        0x0                 0
35
(gdb) x/32x 0
36
0x0 <exception_table>:  0x20003138  0x000029e9  0x000029e7  0x0000537f
37
0x10 <exception_table+16>:  0x00000000  0x00000000  0x00000000  0x00000000
38
0x20 <exception_table+32>:  0x00000000  0x00000000  0x00000000  0x000029e7
39
0x30 <exception_table+48>:  0x00000000  0x00000000  0x000029e7  0x000029e7
40
0x40 <exception_table+64>:  0x00005355  0x00005357  0x00005359  0x0000535b
41
0x50 <exception_table+80>:  0x00005321  0x0000535d  0x0000535f  0x00005361
42
0x60 <exception_table+96>:  0x00005363  0x00003669  0x0000367d  0x000029e7
43
0x70 <exception_table+112>:  0x00005365  0x00005367  0x000029e7  0x00005369

Der kommt offenbar tatsächlich aus der Vektortabelle. Frag mich nicht, 
auf welche Weise. ;-)

Das mit dem entry point im ELF-File war mir nur aufgefallen, weil wir 
das anfangs nicht hatten, und dann startete der Debugger immer bei 0 …

(Das hier ist jetzt kein STM32, aber ein anderer Cortex-M.)

: Bearbeitet durch Moderator
von Johannes S. (Gast)


Lesenswert?

und es ist der erste Eintrag in der Vectortabelle
1
g_pfnVectors:
2
  .word  _estack
3
  .word  Reset_Handler
4
  .word  NMI_Handler
5
  .word  HardFault_Handler
6
  .word  MemManage_Handler
7
  .word  BusFault_Handler
8
  .word  UsageFault_Handler

auch im startup code.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johannes S. schrieb:
> und es ist der erste Eintrag in der Vectortabelle

Das ist schon klar.

Aber es ist nicht klar, warum der Debugger mit dem entsprechend 
gesetzten SP startet, während er es nicht schafft, den PC aus dem 
zweiten Eintrag der Tabelle zu entnehmen, sondern stattdessen mit dem 
startet, was als Entry im ELF-File steht (oder eben mit 0, wenn es dafür 
nichts gibt).

Vermutlich wird der SP durch die Hardware bereits gesetzt (so wie der PC 
auch beim "richtigen" Booten), aber der PC wird in diesem Falle stets 
durch den Debugger vorgegeben.

Bin zu faul, mir jetzt die Kommunikation zwischen Debugger und 
GDB-Server dahingehend anzusehen.

von Christoph K. (chriskuku)


Lesenswert?

Jörg W. schrieb:
> Christoph K. schrieb:
>
>> Das wäre in meinem Fall das Label "Reset" bei 0x3a56.
>> Sollte ich das vielleicht dem ld mitteilen?
>
> Ja.
>
>> Woher nimmt er denn den SP, wenn der Bootprozeß nicht hardwaremäßig
>> verläuft?
>
> Gute Frage. :-)
>
>
1
> (gdb) mon reset halt
2
> (gdb) load
3
> Loading section .text, size 0x17214 lma 0x0
4
> Loading section .ARM.exidx, size 0x8 lma 0x17214
5
> Loading section .relocate, size 0xa80 lma 0x1721c
6
> Start address 0x29e8, load size 97436
7
> Transfer rate: 9 KB/sec, 12179 bytes/write.
8
> (gdb) si
9
> 0x000029ea in Reset_Handler () at board_cstartup_gnu.c:210
10
> 210          if (pSrc != pDest) {
11
> (gdb) info reg
12
> r0             0x601               1537
13
> r1             0x3                 3
14
> r2             0x1721c             94748
15
> r3             0x602               1538
16
> r4             0x0                 0
17
> r5             0x20000e9b          536874651
18
> r6             0x200030cb          536883403
19
> r7             0x0                 0
20
> r8             0x200000d0          536871120
21
> r9             0x20002fec          536883180
22
> r10            0x160c8             90312
23
> r11            0x1                 1
24
> r12            0x8                 8
25
> sp             0x20003138          0x20003138
26
> lr             0x387d              14461
27
> pc             0x29ea              0x29ea <Reset_Handler+2>
28
> xPSR           0x1000000           16777216
29
> msp            0x20003138          0x20003138
30
> psp            0xfffffffc          0xfffffffc
31
> primask        0x0                 0
32
> basepri        0x0                 0
33
> faultmask      0x0                 0
34
> control        0x0                 0
35
> (gdb) x/32x 0
36
> 0x0 <exception_table>:  0x20003138  0x000029e9  0x000029e7  0x0000537f
37
> 0x10 <exception_table+16>:  0x00000000  0x00000000  0x00000000 
38
> 0x00000000
39
> 0x20 <exception_table+32>:  0x00000000  0x00000000  0x00000000 
40
> 0x000029e7
41
> 0x30 <exception_table+48>:  0x00000000  0x00000000  0x000029e7 
42
> 0x000029e7
43
> 0x40 <exception_table+64>:  0x00005355  0x00005357  0x00005359 
44
> 0x0000535b
45
> 0x50 <exception_table+80>:  0x00005321  0x0000535d  0x0000535f 
46
> 0x00005361
47
> 0x60 <exception_table+96>:  0x00005363  0x00003669  0x0000367d 
48
> 0x000029e7
49
> 0x70 <exception_table+112>:  0x00005365  0x00005367  0x000029e7 
50
> 0x00005369
51
>
>
> Der kommt offenbar tatsächlich aus der Vektortabelle. Frag mich nicht,
> auf welche Weise. ;-)
>
> Das mit dem entry point im ELF-File war mir nur aufgefallen, weil wir
> das anfangs nicht hatten, und dann startete der Debugger immer bei 0 …
>
> (Das hier ist jetzt kein STM32, aber ein anderer Cortex-M.)

Vergleich mit meiner Situation:
1
$ ./GDB
2
GNU gdb (GNU Tools for Arm Embedded Processors 8-2018-q4-major) 8.2.50.20181213-git
3
Copyright (C) 2018 Free Software Foundation, Inc.
4
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
5
This is free software: you are free to change and redistribute it.
6
There is NO WARRANTY, to the extent permitted by law.
7
Type "show copying" and "show warranty" for details.
8
This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi".
9
Type "show configuration" for configuration details.
10
For bug reporting instructions, please see:
11
<http://www.gnu.org/software/gdb/bugs/>.
12
Find the GDB manual and other documentation resources online at:
13
    <http://www.gnu.org/software/gdb/documentation/>.
14
15
For help, type "help".
16
Type "apropos word" to search for commands related to "word".
17
0x0000161c in uart_init ()
18
Unable to match requested speed 2000 kHz, using 1800 kHz
19
Unable to match requested speed 2000 kHz, using 1800 kHz
20
target halted due to debug-request, current mode: Thread 
21
xPSR: 0x01000000 pc: 0x00003a56 msp: 0x20000330
22
Loading section .text, size 0x3bc8 lma 0x0
23
Start address 0x0, load size 15304
24
Transfer rate: 122432 bits in <1 sec, 15304 bytes/write.
25
(gdb) si
26
halted: PC: 0x00000002
27
0x00000002 in ?? ()
28
(gdb)


Ich hatte jetzt auch noch mal im Makefile dem Linker versucht, den entry 
point mitzuteilen:
1
ARMGNU?=arm-none-eabi
2
3
COPS = -Wall  -Os -nostdlib -nostartfiles -ffreestanding -save-temps
4
AOPS = --warn --fatal-warnings
5
6
all : mecrisp-stellaris-stm32f407.bin
7
8
mecrisp-stellaris-stm32f407.o : mecrisp-stellaris-stm32f407.s
9
        $(ARMGNU)-as -al mecrisp-stellaris-stm32f407.s -o mecrisp-stellaris-stm32f407.o >mecrisp-stellaris-stm32f407.lst
10
11
mecrisp-stellaris-stm32f407.bin : memmap mecrisp-stellaris-stm32f407.o
12
        $(ARMGNU)-ld  -e Reset -o mecrisp-stellaris-stm32f407.elf -T memmap mecrisp-stellaris-stm32f407.o
13
        $(ARMGNU)-objdump -D mecrisp-stellaris-stm32f407.elf > mecrisp-stellaris-stm32f407.list
14
        $(ARMGNU)-objcopy mecrisp-stellaris-stm32f407.elf mecrisp-stellaris-stm32f407.bin -O binary
15
        cp *.elf ../../stm32F407/firmware.elf
16
17
clean:
18
        rm -f *.bin
19
        rm -f *.o
20
        rm -f *.list
21
#       rm -f *.elf

Da ändert sich nichts an der Start address 0x0.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Christoph K. schrieb:
> Da ändert sich nichts an der Start address 0x0.

Das ist allerdings seltsam.

Bei uns steht der entry point im Linkerscript:
1
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
2
OUTPUT_ARCH(arm)
3
ENTRY(Reset_Handler)

-e sollte aber eigentlich trotzdem klappen.

Alternativ kannst du den PC auch im GDB direkt setzen:
1
(gdb) set $pc=Reset

Wofür brauchst du denn überhaupt das .bin-File?

von Christoph K. (chriskuku)


Lesenswert?

Jörg W. schrieb:
> Christoph K. schrieb:
>> Da ändert sich nichts an der Start address 0x0.
>
> Das ist allerdings seltsam.
>
> Bei uns steht der entry point im Linkerscript:
>
>
1
> OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
2
> OUTPUT_ARCH(arm)
3
> ENTRY(Reset_Handler)
4
>
>
> -e sollte aber eigentlich trotzdem klappen.
>
> Alternativ kannst du den PC auch im GDB direkt setzen:
>
>
1
> (gdb) set $pc=Reset
2
>
>
> Wofür brauchst du denn überhaupt das .bin-File?

Das bin-File wurde vom Autor des mecrisp-Forth benutzt zum flashen. Den 
ELF-file hatte ich aus dem Make herausgefischt (siehe auskommentierte
Zeile im clean:), um es im gdb verwenden zu können.


Ich soll Zitatzeilen löschen. Vielleicht klappt's auch, wenn ich mehr 
Gehalt hinzufüge :)

: Bearbeitet durch User
von Christoph K. (chriskuku)


Lesenswert?

Christoph K. schrieb:
> Jörg W. schrieb:
>> Christoph K. schrieb:
>>> Da ändert sich nichts an der Start address 0x0.
>>
>> Das ist allerdings seltsam.
>>
1
$ arm-none-eabi-nm mecrisp-stellaris-stm32f407.o | grep Reset
2
00003a56 t Reset


Makefile:
1
ARMGNU?=arm-none-eabi
2
3
COPS = -Wall  -Os -nostdlib -nostartfiles -ffreestanding -save-temps
4
AOPS = --warn --fatal-warnings
5
6
all : mecrisp-stellaris-stm32f407.bin
7
8
mecrisp-stellaris-stm32f407.o : mecrisp-stellaris-stm32f407.s
9
        $(ARMGNU)-as -al mecrisp-stellaris-stm32f407.s -o mecrisp-stellaris-stm32f407.o >mecrisp-stellaris-stm32f407.lst
10
11
mecrisp-stellaris-stm32f407.bin : memmap mecrisp-stellaris-stm32f407.o
12
        $(ARMGNU)-ld  -e Reset -o mecrisp-stellaris-stm32f407.elf -T memmap mecrisp-stellaris-stm32f407.o
13
        $(ARMGNU)-objdump -D mecrisp-stellaris-stm32f407.elf > mecrisp-stellaris-stm32f407.list
14
        $(ARMGNU)-objcopy mecrisp-stellaris-stm32f407.elf mecrisp-stellaris-stm32f407.bin -O binary
15
        cp *.elf ../../stm32F407/firmware.elf
16
17
clean:
18
        rm -f *.bin
19
        rm -f *.o
20
        rm -f *.list
21
#       rm -f *.elf



Die Linkerzeile sagt, es könne das Symbol "Reset" nicht gefunden werden:
1
rm-none-eabi-as -al mecrisp-stellaris-stm32f407.s -o mecrisp-stellaris-stm32f407.o >mecrisp-stellaris-stm32f407.lst
2
arm-none-eabi-ld  -e Reset -o mecrisp-stellaris-stm32f407.elf -T memmap mecrisp-stellaris-stm32f407.o
3
arm-none-eabi-ld: warning: cannot find entry symbol Reset; defaulting to 0000000000000000

>> Bei uns steht der entry point im Linkerscript:
>>
>>
1
>> OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
2
>> OUTPUT_ARCH(arm)
3
>> ENTRY(Reset_Handler)
4
>>
>>
>> -e sollte aber eigentlich trotzdem klappen.
>>
>> Alternativ kannst du den PC auch im GDB direkt setzen:
>>
>>
1
>> (gdb) set $pc=Reset
2
>>


Aber (!):
1
$ arm-none-eabi-nm firmware.elf | grep Reset
2
00003a56 t Reset
3
         U Reset

U - Unknown?
Ach so, das war jetzt die Folge des nicht aufgelösten -e Reset in der 
Linkerzeile. Wegnehmen desselben nimmt das U auch weg.

Gelöst: Füge ein .global Reset in den Assembler Code ein. Dann wird das 
"t Reset" zum "T Reset". Das müssen wir Unix-Hasen doch wissen :)

: Bearbeitet durch User
von Christoph K. (chriskuku)


Lesenswert?

Wollte jetzt nicht noch mal editieren, also hier jetzt Erfolgsmeldung:
1
(gdb) mon reset halt
2
Unable to match requested speed 2000 kHz, using 1800 kHz
3
Unable to match requested speed 2000 kHz, using 1800 kHz
4
target halted due to debug-request, current mode: Thread 
5
xPSR: 0x01000000 pc: 0x00003a56 msp: 0x20000330
6
(gdb) load
7
Loading section .text, size 0x3bc8 lma 0x0
8
Start address 0x3a56, load size 15304
9
Transfer rate: 122432 bits in <1 sec, 15304 bytes/write.
10
(gdb) si
11
halted: PC: 0x0000161a
12
0x0000161a in uart_init ()
13
(gdb) si
14
halted: PC: 0x0000161c
15
0x0000161c in uart_init ()
16
(gdb)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Christoph K. schrieb:
> Gelöst: Füge ein .global Reset in den Assembler Code ein. Dann wird das
> "t Reset" zum "T Reset".

Yup, das wollte ich auch gerade anmerken.

Christoph K. schrieb:
> Das bin-File wurde vom Autor des mecrisp-Forth benutzt zum flashen.

Muss man nicht haben. Das ELF-File geht genauso, kann OpenOCD problemlos 
benutzen (und auch AVRDUDE für AVRs inzwischen seit vielen Jahren).

.bin-Files bauen wir nur noch für Onboard-Bootloader (Laden von Firmware 
beim Kunden direkt von SD-Karten). Da wäre das Parsen eines ELF-Files 
bissel aufwändig.

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.