Forum: Mikrocontroller und Digitale Elektronik gdb und OpenOCD session - memmap


von Christoph K. (chriskuku)


Lesenswert?

Ich versuche gerade noch mal eine OpenOCD-Session mit gdb zum Laufen zu
bekommen. STLinkV2 des Nucleo-Boards ist an das stm32-F407-DIYMORE Board
angeschlossen. Da ich immer noch nicht weiß, wie mein memmap aussehen
soll und mir gesagt wurde, ich solle das rom nach 0x08000000 lagern,
versuche ich also Folgendes:
1
$ cat memmap
2
3
MEMORY
4
{
5
   rom(RX)   : ORIGIN = 0x08000000, LENGTH = 0x4000
6
   ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 0x4000
7
}
8
9
SECTIONS
10
{
11
   .text : { *(.text*) } > rom
12
   .bss  : { *(.bss*) } > ram
13
}
14
15
$ cat DEBUGnucleo
16
#!/bin/sh
17
/Users/kuku/opt/xpack-openocd-0.10.0-14/bin/openocd -f /Users/kuku/opt/xpack-openocd-0.10.0-14/scripts/board/st_nucleo_f4.cfg -c "gdb_port 4242" -c "telnet_port 4444"
18
$ 
19
$ ./DEBUGnucleo 
20
xPack OpenOCD, x86_64 Open On-Chip Debugger 0.10.0+dev-00378-ge5be992df (2020-06-26-12:31)
21
Licensed under GNU GPL v2
22
For bug reports, read
23
  http://openocd.org/doc/doxygen/bugs.html
24
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
25
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
26
27
Info : Listening on port 6666 for tcl connections
28
Info : Listening on port 4444 for telnet connections
29
Info : clock speed 2000 kHz
30
Info : STLINK V2J37M26 (API v2) VID:PID 0483:374B
31
Info : Target voltage: 3.238270
32
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
33
Info : starting gdb server for stm32f4x.cpu on 4242
34
Info : Listening on port 4242 for gdb connections
35
file firmware.elf
36
37
$ cat .gdbinit
38
set mem inaccessible-by-default off
39
target remote localhost:4242
40
41
$ ./GDB
42
GNU gdb (GNU Tools for Arm Embedded Processors 8-2018-q4-major) 8.2.50.20181213-git
43
Copyright (C) 2018 Free Software Foundation, Inc.
44
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
45
This is free software: you are free to change and redistribute it.
46
There is NO WARRANTY, to the extent permitted by law.
47
Type "show copying" and "show warranty" for details.
48
This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi".
49
Type "show configuration" for configuration details.
50
For bug reporting instructions, please see:
51
<http://www.gnu.org/software/gdb/bugs/>.
52
Find the GDB manual and other documentation resources online at:
53
    <http://www.gnu.org/software/gdb/documentation/>.
54
55
For help, type "help".
56
Type "apropos word" to search for commands related to "word".
57
0x00000448 in ?? ()
58
(gdb) 
59
(gdb) load
60
Error erasing flash with vFlashErase packet
61
(gdb) 
62
63
Im openOCD-Fenster erscheint jetzt:
64
65
Error: failed erasing sectors 0 to 0
66
Error: flash_erase returned -304

Mappe ich das rom (memmap) jedoch auf 0x00000000, so habe ich beim
"load" kein Problem.
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
Loop () at simple.s:38
18
38  Loop:    b Loop
19
(gdb) load
20
Loading section .text, size 0x450 lma 0x0
21
Start address 0x440, load size 1104
22
Transfer rate: 8832 bits in <1 sec, 1104 bytes/write.
23
(gdb)
Mein Programm simple.s sieht so aus:
1
        .syntax unified
2
        .cpu cortex-m4
3
        .thumb
4
        .global Reset,Loop
5
        .equ ram,0x20000000
6
        .equ dict,0x188
7
        .equ stack,0x20000300
8
        .text
9
        .align 2
10
        .long stack
11
        .long Reset
12
13
        .skip 0x400
14
Reset:
15
      ldr r1,=dict
16
      ldr r0,=ram+4
17
      str r1, [r0]
18
Loop:    b Loop
19
       .end
Lasse ich das Programm laufen, passieren merkwürdige Dinge:
Zunächst scheint alles normal.
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
Loop () at simple.s:18
18
18  Loop:    b Loop
19
(gdb) load
20
Loading section .text, size 0x418 lma 0x0
21
Start address 0x408, load size 1048
22
Transfer rate: 8384 bits in <1 sec, 1048 bytes/write.
23
(gdb) x /10x 0
24
0x0:  0x20000300  0x00000408  0x00000000  0x00000000
25
0x10:  0x00000000  0x00000000  0x00000000  0x00000000
26
0x20:  0x00000000  0x00000000
27
(gdb) 
28
(gdb) s
29
halted: PC: 0x0000040c
30
16        ldr r0,=ram+4
31
(gdb) s
32
halted: PC: 0x0000040e
33
17        str r1, [r0]
34
(gdb) s
35
halted: PC: 0x00000410
36
Loop () at simple.s:18
37
18  Loop:    b Loop
38
(gdb) x /10x 0
39
0x0:  0x20000300  0x00000188  0x00000000  0x00000000
40
0x10:  0x00000000  0x00000000  0x00000000  0x00000000
41
0x20:  0x00000000  0x00000000
42
(gdb)
Ab hier wird's komisch. Zunächst: warum schreibt das Programm auf die
Location 00000004 und überschreibt den Reset-Vektor mit der 0x0188?
Das sollte ins RAM (0x20000000) geschrieben werden, wo ich es übrigens
auch finde:
1
(gdb) x /10x 0x20000000
2
0x20000000:  0x20000300  0x00000188  0x00000000  0x00000000
3
0x20000010:  0x00000000  0x00000000  0x00000000  0x00000000
4
0x20000020:  0x00000000  0x00000000
5
(gdb)
Wenn ich dann nach Zeile 18 weiter steppe, geht gdb in eine Schleife und
hält nicht mehr an. Macht also keinen Step sondern loopt ewig. Ich kann
es allerdings dann mit ^C anhalten:
1
(gdb) s
2
halted: PC: 0x00000410
3
halted: PC: 0x00000410
4
halted: PC: 0x00000410
5
halted: PC: 0x00000410
6
halted: PC: 0x00000410
7
halted: PC: 0x00000410
8
halted: PC: 0x00000410
9
halted: PC: 0x00000410
10
halted: PC: 0x00000410
11
... usw. hört nicht mehr auf. (Im OpenOCD-Fenster dasselbe)

Mag sein, daß das normal ist, weil die Loop: nur den branch auf sich
selbst enthält und gdb da nicht mehr steppen kann (?!).

Aber was mich wirklich irritiert, ist das Verhalten hinsichtlich des
Vektorbereiches.

Auch, wenn ich den Reset-Button am target drücke, muß ich doch wieder
sauber durchstarten können.

von A. B. (Gast)


Lesenswert?

Christoph K. schrieb:

> bekommen. STLinkV2 des Nucleo-Boards ist an das stm32-F407-DIYMORE Board
> Im openOCD-Fenster erscheint jetzt:
>
> Error: failed erasing sectors 0 to 0
> Error: flash_erase returned -304
>
> Mappe ich das rom (memmap) jedoch auf 0x00000000, so habe ich beim
> "load" kein Problem.

Ähm, je nach Zustand der BOOT-Pins liegt ab 0x0 das RAM gespiegelt. Da 
OpenOCD davon aber nichts weiß, wird der Bereich als "normaler" Speicher 
behandelt, sprich RAM. In der cfg für STM32F4x steht auch nur:

flash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME
flash bank $_CHIPNAME.otp stm32f2x 0x1fff7800 0 0 0 $_TARGETNAME

Die 0 bei der ersten Bank steht für "default", also 0x08000000. Weitere 
Flash-Bänke gibt's nicht, auch keine Alias für den Bereich ab 0x0.

Auch wenn über die BOOT-Pins z. B. der Flash bei 0x0 eingeblendet wird:
Da OpenOCD eben nichts davon weiß, wird beim 'load' per normalem 
Schreibzugriff (wie bei RAM) dorthin geschrieben, was beim Flash aber 
keinerlei Wirkung hat. Entsprechend wird vorher auch kein Erase gemacht, 
der kann also auch nicht fehl schlagen. Nur bei Adress-Bereich ab 
0x08000000 wird der Flash-Controller überhaupt angesprochen.

Fazit: Im Linker-File MUSS der Bereich ab 0x08000000 angegeben werden.

Warum das Löschen des Sektors 0 nicht klappt, ist eine ganz andere 
Frage. Da würde ich OpenOCD mal direkt via Telnet ansprechen und Erase 
"händisch" probieren. Wenn es so auch nicht geht, kann man unmittelbar 
danach im FLASH_SR nachsehen, welches Fehler-Flag gesetzt ist ...

> Ab hier wird's komisch. Zunächst: warum schreibt das Programm auf die
> Location 00000004 und überschreibt den Reset-Vektor mit der 0x0188?
> Das sollte ins RAM (0x20000000) geschrieben werden, wo ich es übrigens

Nein, das ist doch klar. Der Speicher ab 0x0 ist exakt derselbe wie ab 
0x20000000. Was man in Adresse 0x20000000 schreibt, kann man unter 
Adresse 0x0 auslesen und umgekehrt. Dass das etwas Durcheinander gibt, 
versteht sich von selbst ;-)

von Christoph K. (chriskuku)


Lesenswert?

Danke für die Antwort.
Zum Mapping im Loader file:

Die Adresse, die da angegeben wird, ist ja die Adresse, auf die das 
Programm reloziert wird. Adressen werden auf 0x08000000 umgerechnet, so, 
daß es in 0x08000000 lauffähig wäre. Es soll aber relativ zu 0x00000000 
laufen. Die 0x08000000 ist ja nur die äußere Adresse der „Schublade“, in 
die es in den STM32 geschoben wird.

Die BOOT0 und BOOT1 pins sind beide unbelegt, also auf 0.

Wenn ich die 0 (statt der 0x08000000) im memmap file habe, und dann das 
generierte .BIN file nach 0x08000000 in den STM32F411 des Nucleo flashe 
und es ohne gdb/OpenOCD starte, läuft es.
(dabei handelt es sich um ein ansonsten völlig gleich strukturiertes 
Programm)

Mir ist klar, daß das BIN file nicht mehr reloziert werden kann. Aber 
wird das nach 0x08000000 relozierte .elf im STM32 noch mal reloziert? 
Doch wohl nicht. Und für openOCD muß ich es ja nicht nach 0x08000000 
relozieren? Warum denn?

Und warum wird das RAM (im Normalbetrieb/gdb auf 0 gemappt)?


Ach so, und noch was: Wieso bekomme ich den Fehler -304 bzw. vFlashErase 
Fehler, wenn ich das Programm auf 0x80000000 mappe?
1
(gdb)
2
(gdb) load
3
Error erasing flash with vFlashErase packet
4
(gdb)
5
6
Im openOCD-Fenster erscheint jetzt:
7
8
Error: failed erasing sectors 0 to 0
9
Error: flash_erase returned -304

von A. B. (Gast)


Lesenswert?

Christoph K. schrieb:
> Die Adresse, die da angegeben wird, ist ja die Adresse, auf die das
> Programm reloziert wird. Adressen werden auf 0x08000000 umgerechnet, so,
> daß es in 0x08000000 lauffähig wäre. Es soll aber relativ zu 0x00000000
> laufen. Die 0x08000000 ist ja nur die äußere Adresse der „Schublade“, in
> die es in den STM32 geschoben wird.

Das trifft nicht den Kern der Sache: Das ist nicht nur die Adresse, auf 
die reloziert wird, sondern AUCH die Adresse, wohin geladen wird. Wenn 
man da unterschiedliche haben will:

aus https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_chapter/ld_3.html

"AT ( ldadr )
    The expression ldadr that follows the AT keyword specifies the load 
address of the section. The default (if you do not use the AT keyword) 
is to make the load address the same as the relocation address. This 
feature is designed to make it easy to build a ROM image. For example, 
this SECTIONS definition creates two output sections: one called 
`.text', which starts at 0x1000, and one called `.mdata', which is 
loaded at the end of the `.text' section even though its relocation 
address is 0x2000. The symbol _data is defined with the value 0x2000:"

> Die BOOT0 und BOOT1 pins sind beide unbelegt, also auf 0.

Das ist nicht gut. BOOT0 hat keinen internen Pull-up/-down, und bei 
BOOT1
ist der während Reset nicht eingeschaltet. Zustand also absolut unklar.

> Wenn ich die 0 (statt der 0x08000000) im memmap file habe, und dann das
> generierte .BIN file nach 0x08000000 in den STM32F411 des Nucleo flashe
> und es ohne gdb/OpenOCD starte, läuft es.

Bei einem Binärfile sind nur die "nackten" Daten drin, ohne jeglichen 
Adressbezug. Ob es an verschiedenen Adressen läuft, hängt davon ab, ob 
nur 'position independend code' erzeugt wurde. Wenn aber BOOT0 
tatsächlich auf 0 liegt, wird das Flash ja zunächst auch bei 0x0 
eingeblendet, es ist dann also egal, ob auf 0x0 oder 0x08000000 
reloziert wurde und ob positionsunabhängiger Code erzeugt wurde (solange 
nicht in SYSCFG_MEMRMP rum gefummelt wird).

> Mir ist klar, daß das BIN file nicht mehr reloziert werden kann. Aber
> wird das nach 0x08000000 relozierte .elf im STM32 noch mal reloziert?
> Doch wohl nicht. Und für openOCD muß ich es ja nicht nach 0x08000000
> relozieren? Warum denn?

Nochmal: Relocation und Placement Address sind zwei unterschiedliche 
Sachen. Für das Programmieren des Flashs muss in den Bereich ab 
0x08000000 platziert werden. Das muss also so in der elf-Datei drin 
stehen, wenn man damit flashen will. Die Reloation Address ist dabei(!) 
völlig egal. Bei einer Binärdatei dagegen kann/muss man die Adresse ja 
explizit angegeben.

> Und warum wird das RAM (im Normalbetrieb/gdb auf 0 gemappt)?

Wird es das tatsächlich schon beim Reset? Das hängt halt von den 
BOOT-Pins ab, außerdem kann das ja auch noch nachträglich vom Programm 
in SYSCFG_MEMRMP umkonfiguriert worden sein.

> Ach so, und noch was: Wieso bekomme ich den Fehler -304 bzw. vFlashErase
> Fehler, wenn ich das Programm auf 0x80000000 mappe?
> Error: flash_erase returned -304

src/target/target.h:#define ERROR_TARGET_NOT_HALTED (-304)

Der Controller läuft also schon/noch, müsste also zunächst angehalten 
werden: Es ist unfein, dem Prozessor das laufende Programm wegzulöschen 
...

von Christoph K. (chriskuku)


Lesenswert?

A. B. schrieb:
>> Ach so, und noch was: Wieso bekomme ich den Fehler -304 bzw. vFlashErase
>> Fehler, wenn ich das Programm auf 0x80000000 mappe?
>> Error: flash_erase returned -304
>
> src/target/target.h:#define ERROR_TARGET_NOT_HALTED (-304)
>
> Der Controller läuft also schon/noch, müsste also zunächst angehalten
> werden: Es ist unfein, dem Prozessor das laufende Programm wegzulöschen
> ...

BOOT0 Jumper - mein Fehler - war open, so wie das DIYMORE Baord 
geliefert wurde. Hatte mir da keine Gedanken drum gemacht. Jetzt 
korrigiert und man sieht auch nach dem Reset, daß das vorherige Programm 
noch geflasht ist. (das machte die User LED an)
Wie halte ich nun das target an um den flash (load) Befehl erfolgreich 
abzusetzen? Hier noch mal frisch gestartet, openOCD und GDB:
1
$ ./DEBUGnucleo 
2
xPack OpenOCD, x86_64 Open On-Chip Debugger 0.10.0+dev-00378-ge5be992df (2020-06-26-12:31)
3
Licensed under GNU GPL v2
4
For bug reports, read
5
  http://openocd.org/doc/doxygen/bugs.html
6
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
7
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
8
9
Info : Listening on port 6666 for tcl connections
10
Info : Listening on port 4444 for telnet connections
11
Info : clock speed 2000 kHz
12
Info : STLINK V2J37M26 (API v2) VID:PID 0483:374B
13
Info : Target voltage: 3.235125
14
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
15
Info : starting gdb server for stm32f4x.cpu on 4242
16
Info : Listening on port 4242 for gdb connections
17
Info : accepting 'gdb' connection on tcp/4242
18
target halted due to debug-request, current mode: Thread 
19
xPSR: 0x61000000 pc: 0x000015c2 msp: 0x20000308
20
Info : device id = 0x10076413
21
Info : flash size = 1024 kbytes
22
Info : flash size = 512 bytes
23
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
24
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
25
Error: timed out while waiting for target halted
26
TARGET: stm32f4x.cpu - Not halted
27
Error: Target not halted
28
Error: failed erasing sectors 0 to 0
29
Error: flash_erase returned -304
30
Dazugehörende GDB-Session:
31
32
$ ./GDB
33
GNU gdb (GNU Tools for Arm Embedded Processors 8-2018-q4-major) 8.2.50.20181213-git
34
Copyright (C) 2018 Free Software Foundation, Inc.
35
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
36
This is free software: you are free to change and redistribute it.
37
There is NO WARRANTY, to the extent permitted by law.
38
Type "show copying" and "show warranty" for details.
39
This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi".
40
Type "show configuration" for configuration details.
41
For bug reporting instructions, please see:
42
<http://www.gnu.org/software/gdb/bugs/>.
43
Find the GDB manual and other documentation resources online at:
44
    <http://www.gnu.org/software/gdb/documentation/>.
45
46
For help, type "help".
47
Type "apropos word" to search for commands related to "word".
48
0x000015c2 in ?? ()
49
(gdb) mon reset halt
50
Unable to match requested speed 2000 kHz, using 1800 kHz
51
Unable to match requested speed 2000 kHz, using 1800 kHz
52
timed out while waiting for target halted
53
TARGET: stm32f4x.cpu - Not halted
54
(gdb) load
55
Error erasing flash with vFlashErase packet
56
(gdb)
(habe im Moment target extended-remote localhost:4242 angegeben).
Und noch mal der Setup:

STLINK-V2 vom nucleo-Board über SWD-Connector mit stm32-f407-DIYMORE 
board
verbunden. Pin 2 vom SWD (SWCLK) an PA14, pin 4 vom SWD an PA13. Vcc 
(5V)/GND vom nucleo-Board abgegriffen.

von A. B. (Gast)


Lesenswert?

Wenn "mon reset halt" nicht hilft, stimmt die Reset Konfiguration wohl 
nicht.
Bzw. die Reset-Leitung vom STlink ist nicht am Target angeschlossen???

Im Zweifel Reset-Taste vom Target beim Start gedrückt halten.

von Christoph K. (chriskuku)


Lesenswert?

A. B. schrieb:
> Wenn "mon reset halt" nicht hilft, stimmt die Reset Konfiguration wohl
> nicht.
> Bzw. die Reset-Leitung vom STlink ist nicht am Target angeschlossen???
>
> Im Zweifel Reset-Taste vom Target beim Start gedrückt halten.

Am Target ist kein Reset herausgeführt, es sei denn über den Resetknopf.
Beim Start von GDB? Das hilft auch nichts.
1
$ ./DEBUGnucleo 
2
xPack OpenOCD, x86_64 Open On-Chip Debugger 0.10.0+dev-00378-ge5be992df (2020-06-26-12:31)
3
Licensed under GNU GPL v2
4
For bug reports, read
5
  http://openocd.org/doc/doxygen/bugs.html
6
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
7
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
8
9
Info : Listening on port 6666 for tcl connections
10
Info : Listening on port 4444 for telnet connections
11
Info : clock speed 2000 kHz
12
Info : STLINK V2J37M26 (API v2) VID:PID 0483:374B
13
Info : Target voltage: 3.225688
14
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
15
Info : starting gdb server for stm32f4x.cpu on 4242
16
Info : Listening on port 4242 for gdb connections
17
Info : accepting 'gdb' connection on tcp/4242
18
Info : Halt timed out, wake up GDB.
19
Error: timed out while waiting for target halted
20
Error executing event gdb-attach on target stm32f4x.cpu:
21
22
Info : device id = 0x10076413
23
Info : flash size = 1024 kbytes
24
Info : flash size = 512 bytes
25
Warn : negative reply, retrying
26
Warn : negative reply, retrying
27
28
$ ./GDB
29
GNU gdb (GNU Tools for Arm Embedded Processors 8-2018-q4-major) 8.2.50.20181213-git
30
Copyright (C) 2018 Free Software Foundation, Inc.
31
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
32
This is free software: you are free to change and redistribute it.
33
There is NO WARRANTY, to the extent permitted by law.
34
Type "show copying" and "show warranty" for details.
35
This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi".
36
Type "show configuration" for configuration details.
37
For bug reporting instructions, please see:
38
<http://www.gnu.org/software/gdb/bugs/>.
39
Find the GDB manual and other documentation resources online at:
40
    <http://www.gnu.org/software/gdb/documentation/>.
41
42
For help, type "help".
43
Type "apropos word" to search for commands related to "word".
44
0x00003a6a in ?? ()
45
(gdb)

von A. B. (Gast)


Lesenswert?

Kein NRST herausgeführt??? Grummel, was hat sich der Entwickler dabei 
gedacht? Naja, einen Draht an die eine Seite vom Reset-Taster kann man 
ja aber doch anlöten ...

Nein, beim Start von OpenOCD bzw. während der Ausführung von "mon reset 
halt". Wenn OpenOCD die CPU nicht anhalten kann, geht natürlich wenig.

von Christoph K. (chriskuku)


Lesenswert?

A. B. schrieb:
> Kein NRST herausgeführt??? Grummel, was hat sich der Entwickler dabei
> gedacht? Naja, einen Draht an die eine Seite vom Reset-Taster kann man
> ja aber doch anlöten ...
>
> Nein, beim Start von OpenOCD bzw. während der Ausführung von "mon reset
> halt". Wenn OpenOCD die CPU nicht anhalten kann, geht natürlich wenig.

So, läuft jetzt hinsichtlich des  Flashens. Aber der Code ist ja auch 
nach 0x08000000 reloziert.
1
(gdb) x /10x 0
2
0x0:  0x20000300  0x08000408  0x00000000  0x00000000
3
0x10:  0x00000000  0x00000000  0x00000000  0x00000000
4
0x20:  0x00000000  0x00000000
5
6
(gdb) s
7
halted: PC: 0x0800040c
8
Reset () at simple.s:16
9
16        ldr r0,=ram+4
10
(gdb)
Das ist doch nicht das, was man will? Aber wahrscheinlich muß ich damit 
leben :) Es funktioniert jedenfalls das erste mal zuverlässig.
1
$ ./DEBUGnucleo 
2
xPack OpenOCD, x86_64 Open On-Chip Debugger 0.10.0+dev-00378-ge5be992df (2020-06-26-12:31)
3
Licensed under GNU GPL v2
4
For bug reports, read
5
  http://openocd.org/doc/doxygen/bugs.html
6
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
7
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
8
9
Info : Listening on port 6666 for tcl connections
10
Info : Listening on port 4444 for telnet connections
11
Info : clock speed 2000 kHz
12
Info : STLINK V2J37M26 (API v2) VID:PID 0483:374B
13
Info : Target voltage: 3.228834
14
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
15
Info : starting gdb server for stm32f4x.cpu on 4242
16
Info : Listening on port 4242 for gdb connections
17
Info : accepting 'gdb' connection on tcp/4242
18
target halted due to debug-request, current mode: Thread 
19
xPSR: 0x61000000 pc: 0x00001658 msp: 0x20000308
20
Info : device id = 0x10076413
21
Info : flash size = 1024 kbytes
22
Info : flash size = 512 bytes
23
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
24
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
25
target halted due to debug-request, current mode: Thread 
26
xPSR: 0x01000000 pc: 0x00003a6a msp: 0x20000330
27
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
28
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
29
target halted due to debug-request, current mode: Thread 
30
xPSR: 0x01000000 pc: 0x00003a6a msp: 0x20000330
31
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
32
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
33
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
34
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
35
target halted due to debug-request, current mode: Thread 
36
xPSR: 00000000 pc: 0x08000408 msp: 0x20000300
37
38
$ ./GDB
39
GNU gdb (GNU Tools for Arm Embedded Processors 8-2018-q4-major) 8.2.50.20181213-git
40
Copyright (C) 2018 Free Software Foundation, Inc.
41
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
42
This is free software: you are free to change and redistribute it.
43
There is NO WARRANTY, to the extent permitted by law.
44
Type "show copying" and "show warranty" for details.
45
This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi".
46
Type "show configuration" for configuration details.
47
For bug reporting instructions, please see:
48
<http://www.gnu.org/software/gdb/bugs/>.
49
Find the GDB manual and other documentation resources online at:
50
    <http://www.gnu.org/software/gdb/documentation/>.
51
52
For help, type "help".
53
Type "apropos word" to search for commands related to "word".
54
0x00001658 in ?? ()
55
(gdb) mon reset halt
56
Unable to match requested speed 2000 kHz, using 1800 kHz
57
Unable to match requested speed 2000 kHz, using 1800 kHz
58
target halted due to debug-request, current mode: Thread 
59
xPSR: 0x01000000 pc: 0x00003a6a msp: 0x20000330
60
(gdb) load
61
Loading section .text, size 0x420 lma 0x8000000
62
Start address 0x8000408, load size 1056
63
Transfer rate: 1 KB/sec, 1056 bytes/write.
64
(gdb)

von A. B. (Gast)


Lesenswert?

Christoph K. schrieb:
> (gdb) x /10x 0
> 0x0:  0x20000300  0x08000408  0x00000000  0x00000000
> 0x10:  0x00000000  0x00000000  0x00000000  0x00000000
> 0x20:  0x00000000  0x00000000
>
> (gdb) s
> halted: PC: 0x0800040c
> Reset () at simple.s:16
> 16        ldr r0,=ram+4
> (gdb)
>
> Das ist doch nicht das, was man will? Aber wahrscheinlich muß ich damit
> leben :) Es funktioniert jedenfalls das erste mal zuverlässig.

Doch. Wo ist da das Problem? Für das interne Flash sollte man bei 
0x08000000 bleiben. So ist das einheitlich über alle(!) STM32 hinweg. Es 
ist wichtig, dass beim Booten ab 0x0 Flash liegt (wegen des 
Reset-Vektors nötig), danach aber dort RAM liegten kann: Sonst läge die 
Vektor-Tabelle für alle Interrupts ja im Flash, man könnte also zur 
Laufzeit die Interrupts schlecht umbiegen. S. RM0091 für die F0xx:

"Physical Remap

Once the boot mode is selected, the application software can modify the 
memory accessible in the code area. This modification is performed by 
programming the MEM_MODE bits in the SYSCFG configuration register 1 
(SYSCFG_CFGR1). Unlike Cortex® M3 and M4, the M0 CPU does not support 
the vector table relocation. For application code which is located in a 
different address than 0x0800 0000, some additional code must be added 
in order to be able to serve the application interrupts. A solution will 
be to relocate by software the vector table to the internal SRAM:
• Copy the vector table from the Flash (mapped at the base of the 
application load address) to the base address of the SRAM at 0x2000 
0000.
• Remap SRAM at address 0x0000 0000, using SYSCFG configuration register 
1.
• Then once an interrupt occurs, the Cortex ® -M0 processor will fetch 
the interrupt handler start address from the relocated vector table in 
SRAM, then it will jump to execute the interrupt handler located in the 
Flash."

von Christoph K. (chriskuku)


Lesenswert?

Ich komme noch mal auf die Relozierung zurück.

Ich habe zum einen dieses mecrispStellarisForth-Paket jetzt einmal als 
.elf file kompiliert und auf den UART1 angepaßt. Das Paket läuft jetzt 
auf dem DIYMORE-breakout-board. Mit folgendem memmap Eintrag:
1
MEMORY
2
{
3
   rom(RX)   : ORIGIN = 0x08000000, LENGTH = 0x4000
4
   ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 0x4000
5
}
6
7
SECTIONS
8
{
9
   .text : { *(.text*) } > rom
10
   .bss  : { *(.bss*) } > ram
11
}

Lasse dann openOCD und gdb laufen. Mache ein load und c(ontinue)
und Programm läuft. Dann schaue ich mir die Location 0x08000004 an
im Falle des .ELF files, den ich via openOCD/gdb geflasht habe:

08000000 @ . 8003A7B  ok.

Nun nehme ich den memmap file, wie ihn der Autor des FORTH Pakets für 
alle seine .BIN Files benutzt (mapped auf 0x00000000, nicht 0x08000000)


1
mecrisp-stellaris-stm32-407-DIY-MORE.bin : memmap mecrisp-stellaris-stm32-407-DIY-MORE.o
2
        $(ARMGNU)-ld  $(DEBUG) -e Reset -o mecrisp-stellaris-stm32-407-DIY-MORE.elf -T memmap mecrisp-stellaris-stm32-407-DIY-MORE.o
3
        $(ARMGNU)-objdump -D mecrisp-stellaris-stm32-407-DIY-MORE.elf > mecrisp-stellaris-stm32-407-DIY-MORE.list
4
        $(ARMGNU)-objcopy mecrisp-stellaris-stm32-407-DIY-MORE.elf mecrisp-stellaris-stm32-407-DIY-MORE.bin -O binary
5
        cp mecrisp-stellaris-stm32-407-DIY-MORE.elf ../../stm32-407-DIY-MORE/firmware.elf
6
7
MEMORY
8
{
9
   rom(RX)   : ORIGIN = 0x00000000, LENGTH = 0x4000
10
   ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 0x4000
11
}
12
13
SECTIONS
14
{
15
   .text : { *(.text*) } > rom
16
   .bss  : { *(.bss*) } > ram
17
}

und flashe den mit

st-flash mecrisp-stellaris-stm32-407-DIY-MORE.bin 0x08000000

Nun schaue ich mir den Flash-Bereich an:

08000004 @ . 3A7B  ok.

Was sehen wir: andere Adressen (!). Das gleiche Programm. Welcher 
Mechanismus sorgt dafür, daß das Programm einmal im Adressraum 0, ein 
andermal im Adressraum 0x08000000 arbeitet, also dorthin reloziert ist?

von A. B. (Gast)


Lesenswert?

Das macht der Linker. Wenn man ihm sagt, dass die text-Section ins "rom" 
gehört und das ab 0x08000000 liegt, werden die einzelnen Häppchen der 
Reihe nach dort abgelegt und alle absoluten Adressen entsprechend 
berechnet und ersetzen die dort zunächst nur symbolisch hinterlegten 
Adressen mit den finalen Adressen.

Bei der zweiten Variante halt ab 0x0. Da eine Binärdatei keine 
Adressangaben beinhaltet, kann/muss man dem st-flash aber sagen, dass 
das ab 0x08000000 "gebrannt" werden soll. Das geht bei OpenOCD übrigens 
auch in ähnlicher Weise.

Die zweite Variante hat aber den Nachteil, dass sie nur lauffähig ist, 
wenn das Mapping "Flash -> 0x0" aktiv ist, denn alle absoluten Sprünge 
und auch die Interrupt-Vektoren verweisen dann in den Bereich ab 0x0. 
Auch späteres Aktivieren des FSMC geht dann nicht mehr so ganz 
uneingeschränkt.

Die erste Variante dagegen läuft auch dann, wenn z. B. vom RAM (ab 0x0 
gemapped) gebootet wird und im RAM dann einfach ein Sprung an die bei 
0x08000004 hinterlegte Adresse gemacht wird (naja, vorausgesetzt, man 
hat nicht vorher an irgendwelchen Einstellungen gedreht, die nach einem 
Reset nur einmal gemacht werden können).

von Christoph K. (chriskuku)


Lesenswert?

Ist mir schon klar, daß der Linker (ld, loader) den zu dem Zeitpunkt des 
Linkens noch relozierbaren Code neu berechnet für die jeweilige 
Map-Adresse.

Aber im Chip selbst stehen ja zwei unterschiedliche Programme. Da hat 
der Linker ja nichts mehr mit zu tun. Wer weiß denn nun, daß es dasselbe 
ist, wenn mein Reset-Vektor auf 0x00003A7B bzw. 0x08003A7B zeigt.

Sind einfach im Chip beide Adressräume äquivalent? Oder wird im Chip 
etwas in der Flash- oder Systemkonfiguration anders programmiert 
(OpenOCD vs. st-flash)?

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.