Forum: Mikrocontroller und Digitale Elektronik STM32 unter Linux programmieren und debuggen


von Martin (Gast)


Lesenswert?

Hallo,

ich habe derzeit versucht ein STM32F411RE Nucleo unter Linux mit eclipse 
zu programmieren, bin aber im Moment ein bisschen am verzweifeln.

Ich habe Eclipse mit cdt und arm plugin installiert. Habe aus dem 
repository den arm-none-eabi-gcc Compiler herunter geladen. Konnte dann 
in Eclipse ein Projekt erstellen, wo ich den richtigen Controller 
auswählen konnte und das Testprogramm konnte ich auch kompilieren und 
die Binary hab ich auch erstellt.
Zum Programmieren habe ich ST-link von hier 
https://github.com/texane/stlink heruntergeladen und wie in diesem Video 
installiert https://www.youtube.com/watch?v=HKX12hJApZM habe es dann 
auch so eingerichtet wie es dort gemacht wurde. Doch aus einem Grund den 
ich nicht kenne, kann ich das Programm nicht auf den Controller laden. 
Habe versucht die Binary mit st-flash write test.bin 0x8000000 auf das 
Board zu laden, leider scheiterte dieser Versuch.
1
2015-02-27T10:03:19 INFO src/stlink-common.c: Loading device parameters....
2
2015-02-27T10:03:19 INFO src/stlink-common.c: Device connected is: F4 device (low power) - stm32f411re, id 0x10006431
3
2015-02-27T10:03:19 INFO src/stlink-common.c: SRAM size: 0x20000 bytes (128 KiB), Flash: 0x80000 bytes (512 KiB) in pages of 16384 bytes
4
2015-02-27T10:03:19 INFO src/stlink-common.c: Attempting to write 5784 (0x1698) bytes to stm32 address: 134217728 (0x8000000)
5
EraseFlash - Sector:0x0 Size:0x4000
6
2015-02-27T10:03:19 INFO src/stlink-common.c: Finished erasing 1 pages of 16384 (0x4000) bytes
7
2015-02-27T10:03:19 INFO src/stlink-common.c: Starting Flash write for F2/F4
8
9
Flash page at addr: 0x08000000 erased2015-02-27T10:03:19 INFO src/stlink-common.c: Successfully loaded flash loader in sram
10
2015-02-27T10:03:22 ERROR src/stlink-common.c: flash loader run error
11
2015-02-27T10:03:22 ERROR src/stlink-common.c: run_flash_loader(0x8000000) failed! == -1
12
13
size: 5784
14
stlink_fwrite_flash() == -1
manchmal kommt auch der Fehler:
1
2015-02-27T10:01:51 WARN src/stlink-usb.c: Error -4 (No such file or directory) opening ST-Link/V2 device 003:000


Habs dann mal versucht direkt über OpenOCD zu programmieren, das hat 
aber auch nicht funktioniert. 
http://kfrancois.com/2014/11/28/stm32f4-ide-using-eclipse-openocd-and-gcc-linux/
1
 Open On-Chip Debugger 0.8.0 (2014-04-29-15:41)
2
Licensed under GNU GPL v2
3
For bug reports, read
4
  http://openocd.sourceforge.net/doc/doxygen/bugs.html
5
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
6
Info : This adapter doesn't support configurable speed
7
Error: open failed
8
in procedure 'transport'
9
in procedure 'init'

Ich hoffe mir kann jemand helfen.

Grüße

Martin

von Uwe Bonnes (Gast)


Lesenswert?

Verwende Openocd Git Head!
Nach dem Laden und bauen:
~/devel/openocd> src/openocd -s tcl -f tcl/board/st_nucleo_f4.cfg

und in einer anderen Konsole:
arm-none-eabi-gdb xxx.elf
> tar ext :3333

von Ben W. (ben_w)


Lesenswert?

hast du bei openocd auch stlink and stm32f4 als targets angegeben?`

z.b. müsstest du in eine openocd config foglendes mit einbinden:

source [find interface/stlink-v2.cfg]
source [find target/stm32f4_stlink.cfg]

von drama (Gast)


Lesenswert?

Ich kann von texane stlink generell nur abraten. Lief nie ordentlich. 
Buggy und langsam. OpenOCD ist dagegen solide, auch mit dem neuen 
ST-Link/V2-1.

Wichtig: das neueste Firmware-Update für das ST-Link einspielen! Geht 
leider m.W. auf offiziellen Wegen nur mit Windows.

von Martin (Gast)


Angehängte Dateien:

Lesenswert?

Vielen Dank für die Antworten,

im Anhang findet ihr einen Screenshoot meiner Einstellungen in Eclipse. 
Die openocd.cfg Datei habe ich im Projekt Ordner drin:
1
source [find interface/stlink-v2.cfg]
2
3
source [find target/stm32f4x_stlink.cfg]
4
5
reset_config srst_only srst_nogate

von Martin (Gast)


Lesenswert?

Habe jetzt mal in Eclipse die Datei "st_nucleo_f4.cfg"  als Argument 
übergeben. Blieb aber erfolglos

von Uwe Bonnes (Gast)


Lesenswert?

source [find interface/stlink-v2.cfg]
muss
source [find interface/stlink-v2-1.cfg]
lauten. V2 sind fast alle Discovery boards, Nucleo und die neuesten 
Discovery Boards, wie L0538-Disco sind V2-1.

von Bernd K. (prof7bit)


Lesenswert?

Martin schrieb:
> Habe jetzt mal in Eclipse

Machs doch erst mal von der Kommandozeile bevor Du gleichzeitig noch 
eine zweite Front mit Eclipse-Konfigurationsproblen aufmachst.

Mach eins nach dem anderen: Erst wenn Du auf der Kommandozeile mit 
openocd einen erfolgreichen connect hinbekommst versuchst Du es mit den 
selben Optionen in Eclipse zu reproduzieren.

von Martin (Gast)


Lesenswert?

Uwe Bonnes schrieb:
> Openocd Git Head

Was ist damit gemeint? Habe jetzt openocd 0.8. Wenn ich dann den Befehl 
von Uwe ausführe kommt:
1
 openocd-0.8.0]$ openocd -s tcl -f tcl/board/st_nucleo_f4.cfg 
2
Open On-Chip Debugger 0.8.0 (2015-02-27-19:19)
3
Licensed under GNU GPL v2
4
For bug reports, read
5
  http://openocd.sourceforge.net/doc/doxygen/bugs.html
6
Runtime Error: tcl/target/stm32f4x.cfg:51: jtag newtap stm32f4x bs -irlen 5 -expected-id 0x06413041 -expected-id 0x06419041: command requires more arguments
7
in procedure 'script' 
8
at file "embedded:startup.tcl", line 58
9
at file "tcl/board/st_nucleo_f4.cfg", line 11
10
in procedure 'jtag' called at file "tcl/target/stm32f4x.cfg", line 51

von Uwe Bonnes (Gast)


Lesenswert?

Die OpenOCD Quellen werden mit GIT verwaltet:
http://openocd.sourceforge.net/repos/
Du arbeitest mit "released" Version, die zu einer Zeit herauskam, als 
der F411 noch nicht bekannt war. Du musst also aus den neusten Quellen 
(Git Head) bauen, oder mit einer Version, die neuer als 6. November 2014 
ist. Zu dem Zeitpunk kamen die Aenderungen fuer den F411 naemlich in den 
Baum.

von Martin (Gast)


Lesenswert?

Hab openocd jetzt aus GIT gebaut. Immer noch gleiche Fehlermeldung:
1
 
2
openocd -f /usr/share/openocd/scripts/board/st_nucleo_f4.cfg
3
Open On-Chip Debugger 0.8.0 (2015-02-27-19:19)
4
Licensed under GNU GPL v2
5
For bug reports, read
6
  http://openocd.sourceforge.net/doc/doxygen/bugs.html
7
Runtime Error: /usr/local/share/openocd/scripts/target/stm32f4x.cfg:51: jtag newtap stm32f4x bs -irlen 5 -expected-id 0x06413041 -expected-id 0x06419041: command requires more arguments
8
in procedure 'script' 
9
at file "embedded:startup.tcl", line 58
10
at file "/usr/share/openocd/scripts/board/st_nucleo_f4.cfg", line 11
11
in procedure 'jtag' called at file "/usr/local/share/openocd/scripts/target/stm32f4x.cfg", line 51

von Uwe Bonnes (Gast)


Lesenswert?

Irgendwas erscheint da noch komisch. Ich erhalte hier:

> src/openocd  -s tcl -f tcl/board/st_nucleo_f4.cfg
Open On-Chip Debugger 0.9.0-dev-00314-g90ae846 (2015-02-28-15:45)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The 
results might differ compared to plain JTAG/SWD
adapter speed: 2000 kHz
adapter_nsrst_delay: 100
none separate
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : clock speed 1800 kHz
Info : STLINK v2 JTAG v23 API v2 SWIM v7 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 0.007890
Error: target voltage may be too low for reliable debugging
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
...

Warum meldet sich Dein Executable mit 0.8.0 und bei mit mit 0.9.0-dev? 
Das mit der Targetspannung hat seine Richtigkeit, ich habe einige 
Widerstaende abgeloetet, um den F411 auch mit Batterie zu betreiben.

Welches Repository hast Du verwendet?
> git remote -v
origin  git://git.code.sf.net/p/openocd/code (fetch)

von Martin (Gast)


Lesenswert?

Ich hab das paket aus dem AUR repository.

von Bernd K. (prof7bit)


Lesenswert?

Martin schrieb:
> Ich hab das paket aus dem AUR repository.

Oben hast Du geschrieben Du hast es aus git gebaut.

von Martin (Gast)



Lesenswert?

AUR hat es aus Git gebaut.

von noreply@noreply.com (Gast)


Lesenswert?

echo $PATH
und
find / -name openocd
könnten helfen. Vielleicht existieren mehrere Runables.

von Martin M. (murmele)


Lesenswert?

Hier die Ausgabe der zwei Befehle:

find / -name openocd
1
/root/.local/share/Trash/files/openocd-0.8.0/src/openocd
2
/root/.local/share/Trash/files/openocd
3
/usr/share/openocd
4
/usr/local/share/openocd
5
/usr/local/bin/openocd
6
/usr/bin/openocd

echo $PATH
1
  
2
/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/opt/opencascade/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl

von noreply@noreply.com (Gast)


Lesenswert?

Martin M. schrieb:
> /usr/local/bin/openocd
> /usr/bin/openocd

Schaut nach zwei Binaries aus. Mit absoluten Fileangabe und -version 
schauen, welches gebraucht wird. /usr/bin/openocd könnte aus einer 
Distribution ein. Wenn nicht benötigt, dann über die Distribution 
deinstallieren.

Schaut aus, wie wenn der root eine 0.8 Version zusätzlich installiert. 
hat. Bezüglich Versionen nochmal oben lesen, welche für den Controller 
benötigt wird.

> root.local/share/Trash/files/openocd-0.8.0/src/openocd

von Martin M. (murmele)


Lesenswert?

Entschuldigung für die späte Antwort. Hier die ausgabe:
1
[martin@martin2 ~]$ /usr/local/bin/openocd -version
2
Open On-Chip Debugger 0.8.0 (2015-02-27-19:19)
3
Licensed under GNU GPL v2
4
For bug reports, read
5
  http://openocd.sourceforge.net/doc/doxygen/bugs.html
6
/usr/local/bin/openocd: invalid option -- 'e'
7
/usr/local/bin/openocd: invalid option -- 'r'
8
9
[martin@martin2 ~]$ /usr/bin/openocd -version
10
Open On-Chip Debugger 0.9.0-dev-00314-g90ae846 (2015-02-28-15:33)
11
Licensed under GNU GPL v2
12
For bug reports, read
13
  http://openocd.sourceforge.net/doc/doxygen/bugs.html
14
/usr/bin/openocd: invalid option -- 'e'
15
/usr/bin/openocd: invalid option -- 'r'

von noreply@noreply.com (Gast)


Lesenswert?

Martin schrieb:
> openocd -f /usr/share/openocd/scripts/board/st_nucleo_f4.cfg
> Open On-Chip Debugger 0.8.0 (2015-02-27-19:19)
> Licensed under GNU GPL v2

Aufräumen.

Es sind zwei openocd installiert und der obige Befehl mischt das Binary 
der einen Version mit den Konfig-Dateien der anderen Version.

/usr/bin/openocd -f /usr/share/openocd/scripts/board/st_nucleo_f4.cfg
könnte wieder gültig sein.

von Martin M. (murmele)


Lesenswert?

noreply@noreply.com schrieb:
> /usr/bin/openocd -f /usr/share/openocd/scripts/board/st_nucleo_f4.cfg

Ok das funktioniert mal sehr gut. Vielen Dank! Aber wie bekomm ich das 
alte wieder runter, den ich hab die Version 0.8 nicht über den 
Paketmanager installiert.

von noreply@noreply.com (Gast)


Lesenswert?

Martin M. schrieb:
> Aber wie bekomm ich das
> alte wieder runter,

rm ?

von Martin M. (murmele)


Lesenswert?

Also das verbinden über GDB funktioniert scheinbar:
1
/usr/bin/openocd -f /usr/share/openocd/scripts/board/st_nucleo_f4.cfg
2
Open On-Chip Debugger 0.9.0-dev-00314-g90ae846 (2015-02-28-15:33)
3
Licensed under GNU GPL v2
4
For bug reports, read
5
  http://openocd.sourceforge.net/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
adapter speed: 2000 kHz
8
adapter_nsrst_delay: 100
9
none separate
10
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
11
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
12
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
13
Info : clock speed 1800 kHz
14
Info : STLINK v2 JTAG v22 API v2 SWIM v5 VID 0x0483 PID 0x374B
15
Info : using stlink api v2
16
Info : Target voltage: 3.261538
17
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
18
Info : accepting 'gdb' connection on tcp/3333
19
Info : device id = 0x10006431
20
Info : flash size = 512kbytes
21
undefined debug reason 7 - target needs reset
1
arm-none-eabi-gdb test2.elf 
2
GNU gdb (GDB) 7.9
3
Copyright (C) 2015 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.  Type "show copying"
7
and "show warranty" for details.
8
This GDB was configured as "--host=x86_64-unknown-linux-gnu --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
For help, type "help".
15
Type "apropos word" to search for commands related to "word"...
16
Reading symbols from test2.elf...done.
17
(gdb) tar ext :3333
18
Remote debugging using :3333
19
0x00000000 in ?? ()
20
(gdb)

Verbindet sich hier der GDB mit openOcd welches mit dem Controller 
kommuniziert oder?

von Bernd K. (prof7bit)


Lesenswert?

Martin M. schrieb:
> Verbindet sich hier der GDB mit openOcd welches mit dem Controller
> kommuniziert oder?

Ja, genau so ist es. OpenOCD fungiert hier als sogenannter 
gdb-debugserver.

Hättest Du stattdessen zum Beispiel einen Segger Jlink gekauft dann 
hättest Du statt openocd den JLinkGDBServerCL gestartet und gdb würde 
sich dann mit diesem verbinden, selbes Prinzip.

Jeder Hersteller eines JTag-Adapters sollte entweder einen gdb 
debugserver mitliefern oder sicherstellen daß sein Adapter 
vollumfänglich mit OpenOCD funktioniert, andernfalls wäre es nicht 
möglich mit gdb zu debuggen und der Adapter wäre nicht viel mehr wert 
als ein Ziegenstein. Solltest Du Dir irgendwann mal einen eigenständigen 
Jtag-Adapter kaufen wollen dann achte bitte auf dieses kleine Detail!

: Bearbeitet durch User
von Sepp (Gast)


Angehängte Dateien:

Lesenswert?

Versuchs mal so

von Sepp (Gast)


Lesenswert?


von Bernd K. (prof7bit)


Lesenswert?

Martin M. schrieb:
> Verbindet sich hier der GDB mit openOcd welches mit dem Controller
> kommuniziert oder?

Und der Vollständigkeit halber: Du kannst bei OpenOCD auch noch 
zusätzlich auf port 4444 mit Telnet connecten (telnet localhost 4444) 
und bekommst dann eine Kommandozeile an der Du selbst direkt mit OpenOCD 
sprechen kannst.

Probiers mal aus!

: Bearbeitet durch User
von Uwe Bonnes (Gast)


Lesenswert?

Martin M. schrieb:

> undefined debug reason 7 - target needs reset

Jetzt fehlt noch ein "mon reset halt"...

von Martin M. (murmele)


Lesenswert?

Bernd K. schrieb:
> Solltest Du Dir irgendwann mal einen eigenständigen
> Jtag-Adapter kaufen wollen dann achte bitte auf dieses kleine Detail!

Vielen Dank für den Tipp! ;)

Bernd K. schrieb:
> Und der Vollständigkeit halber: Du kannst bei OpenOCD auch noch
> zusätzlich auf port 4444 mit Telnet connecten (telnet localhost 4444)
> und bekommst dann eine Kommandozeile an der Du selbst direkt mit OpenOCD
> sprechen kannst.

Jop hat funktioniert. Aber debuggen kann man doch trotzdem nur über GDB 
oder versteh ich da was falsch?


Sepp schrieb:
> Versuchs mal so

Hat so nicht in Eclipse funktioniert.
1
/bin/bash: /home/martin/workspace/test2/Debug/test2.elf: Kann die Binärdatei nicht ausführen: Fehler im Format der Programmdatei
2
/bin/bash: /home/martin/workspace/test2/Debug/test2.elf: Erfolg

Wird durch OpenOcd auch die Software in den Controller geflasht? Diese 
ist eine andere als wenn ich die Release flashe, wegen der Nutzung von 
Breakpoints,... oder?
1
(gdb) tar ext :3333
2
Remote debugging using :3333
3
0x00000000 in ?? ()
4
(gdb) mon reset halt
5
target state: halted
6
target halted due to debug-request, current mode: Thread 
7
xPSR: 0x01000000 pc: 0xfffffffe msp: 0x20020000
8
(gdb)
Es scheint, dass das Programm durchlaufen wird, da mit dem Befehl list 
immer ein anderer Codeausschnitt angezeigt wird.
Habe versucht einen Breakpoint zu setzen, doch bei diesem wird nicht 
angehalten.

von drama (Gast)


Lesenswert?

Martin M. schrieb:
> Wird durch OpenOcd auch die Software in den Controller geflasht? Diese
> ist eine andere als wenn ich die Release flashe, wegen der Nutzung von
> Breakpoints,... oder?

Probier es mal mit "load" im gdb. Das flasht den Code. Ich verwende i.A. 
diese Initialisierungssequenz für "flashen und dann debuggen":
1
monitor reset halt
2
load
3
monitor reset init
4
thbreak main
5
continue

von Martin M. (murmele)


Lesenswert?

drama schrieb:
> monitor reset halt
> load
> monitor reset init
> thbreak main
> continue

es schein so dass es Programmiert wird. aber nur wenn ich load 
HelloWorld.elf anstatt nur load schreibe
1
 (gdb) tar ext :3333
2
Remote debugging using :3333
3
0x00000000 in ?? ()
4
(gdb) monitor reset halt
5
target state: halted
6
target halted due to debug-request, current mode: Thread 
7
xPSR: 0x01000000 pc: 0x080002b8 msp: 0x20020000
8
(gdb) load HelloWorld.elf 
9
Loading section .isr_vector, size 0x344 lma 0x8000000
10
Loading section .inits, size 0x28 lma 0x8000344
11
Loading section .text, size 0x1601 lma 0x800036c
12
Loading section .data, size 0x78 lma 0x8001970
13
Start address 0x80001e4, load size 6629
14
Transfer rate: 12 KB/sec, 1657 bytes/write.
15
(gdb) monitor reset init
16
target state: halted
17
target halted due to debug-request, current mode: Thread 
18
xPSR: 0x01000000 pc: 0x08000314 msp: 0x20020000
19
(gdb) thbreak main
20
Hardware assisted breakpoint 1 at 0x8000f8c: file ../src/main.c, line 38.
21
(gdb) list
22
warning: Source file is more recent than executable.
23
24  
24
25  // Sample pragmas to cope with warnings. Please note the related line at
25
26  // the end of this function, used to pop the compiler diagnostics status.
26
27  #pragma GCC diagnostic push
27
28  #pragma GCC diagnostic ignored "-Wunused-parameter"
28
29  #pragma GCC diagnostic ignored "-Wmissing-declarations"
29
30  #pragma GCC diagnostic ignored "-Wreturn-type"
30
31  
31
32  int main(int argc, char* argv[])
32
33  {
33
(gdb) continue
34
Continuing.

Es bleibt aber so und bleibt nicht bei der main Funktion stehen.

von Martin M. (murmele)


Lesenswert?

Was brauch ich alles, um auf dem Controller die LED (Port A5) 
einzuschalten?

RCC->AHB1ENR |= (1<<0); //Clock für PortA einschalten
GPIOA->MODER |= (1<<10); //PA5 als Ausgang definieren
GPIOA->ODR |= (1<<5);  //PA5 auf 1 setzen

von drama (Gast)


Lesenswert?

Martin M. schrieb:
> es schein so dass es Programmiert wird. aber nur wenn ich load
> HelloWorld.elf anstatt nur load schreibe

Normalerweise gibt man gdb beim Start als Parameter die elf-Datei mit, 
die debuggt, geflasht und/oder ausgeführt werden soll. Versuche das mal. 
Keine Ahnung, wie andere Szenarien unterstützt werden.

von S. R. (svenska)


Lesenswert?

Martin M. schrieb:
> Was brauch ich alles, um auf dem Controller die LED (Port A5)
> einzuschalten?

Ja, das sollte eigentlich reichen. Je nachdem, wie dein Board 
verschaltet ist, könnte die LED auch invertiert sein, oder einen aktiven 
Pullup/Pulldown benötigen. Ansonsten prüfe mal deine Bitmasken, der 
CMSIS-Header enthält dafür auch Konstanten.

Schaue mal mit einem Debugger rein, ob du vielleicht im 
HardFault-Handler steckst. Das passiert, wenn man nicht ordentlich 
Thumb-Code generiert und kann gut verwirren.

von Martin M. (murmele)


Lesenswert?

S. R. schrieb:
> Schaue mal mit einem Debugger rein, ob du vielleicht im
> HardFault-Handler steckst. Das passiert, wenn man nicht ordentlich
> Thumb-Code generiert und kann gut verwirren.
Ich habs jetzt mal nach dieser Anleitung probiert, und da lande ich im 
HardFault-Handler.
http://vedder.se/2012/12/debugging-the-stm32f4-using-openocd-gdb-and-eclipse/
1
 Remote debugging using localhost:3333
2
target remote localhost:3333
3
HardFault_Handler () at ../system/src/cortexm/exception_handlers.c:61
4
61      }
5
monitor reset
6
monitor halt
7
target state: halted
8
target halted due to debug-request, current mode: Handler HardFault
9
xPSR: 0x61000003 pc: 0x08000320 msp: 0x2001fe18
10
monitor flash protect 0 0 11 off
11
ERROR: last sector must be <= 7
12
in procedure 'flash'
13
monitor flash write_image erase "Debug/HelloWorld.hex" 0 ihex
14
auto erase enabled
15
couldn't open Debug/HelloWorld.hex
16
in procedure 'flash'
17
disconnect
18
Ending remote debugging.
19
target remote localhost:3333
20
Remote debugging using localhost:3333
21
HardFault_Handler () at ../system/src/cortexm/exception_handlers.c:61
22
61      }
23
monitor reset
24
monitor halt
25
target state: halted
26
target halted due to debug-request, current mode: Handler HardFault
27
xPSR: 0x61000003 pc: 0x08000320 msp: 0x2001fe18

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

> Ich habs jetzt mal nach dieser Anleitung probiert, und da lande ich im
HardFault-Handler.

Dann schau jetzt mal in den Callstack wie Du da hingekommen bist.

von Martin M. (murmele)


Angehängte Dateien:

Lesenswert?

Im Anhang findest du einen Screenshot

: Bearbeitet durch User
von Martin M. (murmele)


Lesenswert?

Leider kann ich mit dem Callstack nichts anfangen.

von Bernd K. (prof7bit)


Lesenswert?

Also einen hab ich noch: Bei meinen frühen Versuchen mit einem Nucleo 
401 Board hatte ich mal einen Zustand in dem er scheinbar aus heiterem 
Himmel einen Sprungbefehl völlig falsch interpretiert und ins Nirvana 
gesprungen ist (müsste sogar ein Thread darüber hier irgendwo im Forum 
existieren), ein paar Takte später war er dann im Hardfault Handler und 
es war nicht einzusehen oder nachzuvollziehen wie er dort auf normalem 
Wege jemals hätte hin kommen sollen.

Erst als ich ein paar Breakpoints früh in der Initialisierung gesetzt 
und im Einzelschritt durchgegangen bin konnte ich die Stelle einkreisen 
an der er plötzlich begann verrückt zu spielen: Es war unmittelbar nach 
der Initialisierung der PLL!

Ich hatte versehentlich eine SystemClockInit()-Funktion aus einen 
anderen Beispielprogramm für eins der anderen STM32 Boards welches ich 
als Grundgerüst genommen hatte in mein Programm eingebaut 
(beziehungsweise versehentlich noch nicht aus diesem entfernt und gegen 
die richtige ausgetauscht) und der (vermutlich zu hohe) Takt hat ihn 
dann beim nächsten Sprungbefehl an eine ungültige Adresse springen 
lassen obwohl der besagte Sprungbefehl eigentlich vollkommen korrekt 
war.

Nachdem ich die Systemtakt-PLL richtig konfiguriert hatte war der Spuk 
vorbei.

von Martin M. (murmele)


Lesenswert?

Bei mir kommt noch der Fehler:
1
target halted due to debug-request, current mode: Thread 
2
xPSR: 0x81000000 pc: 0x08002fc6 msp: 0x2001ffe0
3
ERROR: last sector must be <= 7

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Wann kommt der Fehler? Was hast Du vorher gemacht?

von Martin M. (murmele)


Angehängte Dateien:

Lesenswert?

Im Terminal habe ich openocd laufen: openocd -f 
/usr/share/openocd/scripts/board/st_nucleo_f4.cfg
und in eclipse habe ich nache dieser Anleitung: 
http://vedder.se/2012/12/debugging-the-stm32f4-using-openocd-gdb-and-eclipse/
Zylin installiert.

Den Fehler konnte ich leider nicht rekonstruieren. Aber es bleibt immer 
im startup hängen (siehe Anhang)

von Uwe Bonnes (Gast)


Lesenswert?

"Hardfault" deutet auf einen Programierfehler, naemlich ein Zugriff auf 
eine nicht vorhandene Speicherzelle. Das hat nichts mit dem debugger zu 
tun...

von Bernd K. (prof7bit)


Lesenswert?

Uwe Bonnes schrieb:
> Das hat nichts mit dem debugger zu
> tun...

Aber mit dessen Hilfe findet er die Stelle wo es kracht.

von Martin M. (murmele)


Lesenswert?

Wie kann ich aber vor der _start(void) Funktion einen Breakpoint setzen, 
habe es im Assembler Code versucht, doch dieser wird einfach 
übersprungen.

von Bernd K. (prof7bit)


Lesenswert?

Martin M. schrieb:
> Wie kann ich aber vor der _start(void) Funktion einen Breakpoint setzen,
> habe es im Assembler Code versucht, doch dieser wird einfach
> übersprungen.

Also bei mir klappt das einwandfrei. Ich kann einen Breakpoint irgendwo 
in der startup.s Datei nah am Einsprungpunkt setzen und der wird 
ordnungsgemäß berücksichtigt. Hab das selbst mal durchexerziert aus ganz 
ähnlichen Gründen (oben beschrieben), allerdings an einem 
stm32401RE-Nucleo-Board mit openocd, Eclipse, der toolchain von 
Launchpad, gnuarm-Plugin und unter Linux.

Allerdings ohne Zylin (was auch immer das ist) denn bei der 
arm-none-eabi-* Toolchain und dem GnuARM-Plugin ist eigentlich schon 
alles fix und fertig dabei was man zum Debuggen braucht.

Die Toolchain hab ich übrigens installiert indem ich einfach deren PPA 
in meine Paketquellen (Ubuntu) aufgenommen habe. So einfach und 
unkompliziert hab ich noch keine cross toolchain am Start gehabt wie 
diese. Und das verrückteste war daß entgegen aller Unkenrufe der erste 
Versuch unter Linux mit diesem Nucleo-Board und openocd auf Anhieb 
geklappt hat, am nächsten Tag unter Windows bin ich fast verzweifelt an 
den üblichen Windows-Problemen (dort gehts aber mittlerweile auch).

: Bearbeitet durch User
von Martin M. (murmele)



Lesenswert?

Ich hab auch openocd, das arm plugin, arm-none-eabi- gcc und gdb 
installiert. Was hast du für Einstellungen im "GDB OpenOCD Debugging" in 
Eclipse eingestellt? Im Anhang findest du meine Einstellungen. Aber nur 
mit dem OpenOCD Debugger in Eclipse komm ich noch weniger weiter

von Bernd K. (prof7bit)



Lesenswert?

$ openocd -v
Open On-Chip Debugger 0.8.0 (2014-05-10-23:20)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.sourceforge.net/doc/doxygen/bugs.html

$ which openocd
/usr/bin/openocd

Oben sieht man wie ich einen Breakpoint direkt im Reset-Handler gesetzt 
habe, angehalten hat er eine Instruktion später. Danach kann ich normal 
im Einzelschrittmodus weitergehen.

Ich habe auch mal mein eigenes Minimal-Projekt angehängt (genau das aus 
dem Screenshot), es ist allerdings für ein STM32F401 Nucleo.

Ich verwende keine HAL-Library und ich habe das startup.s so modifiziert 
daß ich den Aufruf von __libc_init_array nicht ausführen muss (weil ich 
kein C++ mache). Ich springe dann direkt nach main().


Zu dem angehängten Projekt:

EDIT: Wirf das .d und das .o file aus dem src-Ordner raus, ich weiß 
nicht wie die da reingekommen sind, die gehören da nicht hin, lösch die 
einfach. Aller Build-Output wird ins build-Verzeichnis gehen.

Das angehängte Projekt sollte sich auf der Konsole mit

make all

bauen lassen und mit

make clean

wieder reinigen. Die Dateien in stm_inc sind alle aus den CubeMX zip 
files zusammengesucht und nur die die wirklich absolut notwendig sind 
für ein Blinky ohne HAL, evtl kannst Du die austauschen gegen solche für 
Deinen Prozessor und das somit passend machen. Du wirst auch das 
startup_*.s file austauschen müssen (da sind die Interrupt-Vektoren 
definiert) und Du wirst wahrscheinlich auch system_*.c anpassen müssen 
für die korrekte PLL Konfiguration für Deinen Prozessor. Ferner musst Du 
auch im Makefile evtl. die defines anpassen.

Wenn Du das Projekt in Eclipse importierst dann stell sicher daß Eclipse 
es als makefile-Projekt behandelt, also nicht versucht sich on-the-fly 
sein eigenes Makefile zu bauen.

: Bearbeitet durch User
von Martin M. (murmele)


Angehängte Dateien:

Lesenswert?

Ketzt kann ich schon mal Debuggen. Doch er bleibt in einer while 
Schleife hängen (Siehe Screenshot).

von Bernd K. (prof7bit)


Lesenswert?

Martin M. schrieb:
> Ketzt kann ich schon mal Debuggen. Doch er bleibt in einer while
> Schleife hängen (Siehe Screenshot).

Setz mal einen Breakpoint eine Zeile tiefer und dann starte ihn (kein 
Einzelschritt sondern ungebremst mit dem grünen Pfeil), wenn er aus der 
While() draussen ist wird er wieder anhalten.

von Martin M. (murmele)


Lesenswert?

Habe schon probiert einen Breakpoint unter der Whileschleife zu setzten, 
doch das Programm verlässt diese Whileschleife nie.

von Martin M. (murmele)


Lesenswert?

Der Fehler mit der While Schleife war, da ich den Takt beim erstellen 
des Projektes nicht geändert habe, da ich dachte ich müsste die Register 
dafür setzten, aber dies hat wahrscheinlich der startup Code für mich 
erledigt. Habe jetzt den Takt auf 32.768.000Hz gestellt (Nucleo externer 
Quarz)

Kann ich mir über SWD den Inhalt der Register nicht anschauen? Wie sehe 
ich, wie viel Speicher das Programm verbraucht? Was ist eigentlich genau 
der Unterschied zwischen Release und Debug? Werden beim Realease die 
Sachen die der Controller zum debugen braucht nicht mitgeschrieben?

An alle die mir geholfen haben nochmals ein großes Dankeschön

von Bernd K. (prof7bit)


Lesenswert?

Martin M. schrieb:
> Kann ich mir über SWD den Inhalt der Register nicht anschauen?

Doch. Mit dem "Packs-Manager" installierst Du das "Pack" für den 
betreffenden Controller: 
http://gnuarmeclipse.livius.net/blog/packs-manager/ und danach wird der 
Reiter "Peripherals" funktionieren.

> Wie sehe
> ich, wie viel Speicher das Programm verbraucht?

Baue noch einen arm-none-eabi-size Aufruf in Deinen Build ein.

> Was ist eigentlich genau
> der Unterschied zwischen Release und Debug?

Das sind einfach zwei so benannte Konfigurationen die unterschiedliche 
Compilereinstellungen haben. Du kannst auch noch mehr verschiedene 
Build-Configurationen erstellen und für jede kannst Du unterschiedliche 
Compileroptionen angeben oder unterschiedliche Symbole definieren so daß 
Du sogar den selben Code in verschiedenen Varianten bauen könntest.

Im einfachsten Fall hast Du nur die Konfigurationen Release und Debug 
und die unterscheiden sich nur geringfügig in den Compilereinstellungen.

> Werden beim Realease die
> Sachen die der Controller zum debugen braucht nicht mitgeschrieben?

Der Controller braucht keine "Sachen", der Compiler kann Debug-Symbole 
in die .elf-Datei schreiben die der gdb lesen kann und er verzichtet auf 
ein paar tiefgreifende, code-umsortierende Optimierungen die das 
Debuggen schwierig bis unmöglich machen würden. Das kannst Du auf dem 
Reiter "Project properties -> C/C++ build-> Settings" einstellen, oben 
kann man auswählen für welche Konfiguration (Debug oder Release) man 
jetzt gerade die Einstellungen ändert und unten ändert man sie.

Das obige gilt aber alles nur wenn Du das Projekt von Eclipse bauen 
lässt, also der Build-Vorgang von Eclipse gesteuert wird. Wenn Du ein 
selbst geschriebenes Makefile hast mach Eclipse nicht anderes als "make 
all" aufzurufen und du musst alle Einstellungen im Makefile vornehmen. 
Du kannst aber auch in diesem Falle verschiedene Konfigurationen anlegen 
und dort dem make-Aufruf noch jeweils andere Argumente übergeben.

von Martin M. (murmele)


Lesenswert?

Danke für die ausführliche Antwort.
1
arm-none-eabi-size --format=berkeley "STM32_Uart.elf"
2
   text     data      bss      dec      hex  filename
3
   7709      160      416     8285     205d  STM32_Uart.elf

Sind das 8285 Bytes was das Programm an Flash verbraucht?

von Bernd K. (prof7bit)


Lesenswert?

Martin M. schrieb:
> Danke für die ausführliche Antwort.arm-none-eabi-size
> --format=berkeley "STM32_Uart.elf"
>    text     data      bss      dec      hex  filename
>    7709      160      416     8285     205d  STM32_Uart.elf
> Sind das 8285 Bytes was das Programm an Flash verbraucht?

text ist all der vom Compiler erzeugte Maschinencode.

bss liegt im RAM, das sind all Deine globalen und statischen Variablen 
und data sind die Daten mit denen sie vor Beginn des Programms 
initialisiert werden.

Wenn Du sowas hast:
1
uint32_t foo = 0;
2
uint32_t bar = 0;
3
uint32_t baz = 42;
4
5
void foo() {
6
    static uint32_t bla = 0;
7
    static uint32_t blub = 23;
8
9
    uint32_t local_blub = 99;   // <-- das liegt auf dem Stack, das existiert erst wenn die Funktion aufgerufen wird
10
    [...]

Dann wäre bss=40 und data=8 denn bss (also RAM) brauchen alle 5 
Variablen aber initialisiert mit anderen Daten als 0 werden nur 2 davon 
also insgesamt 8 Byte. Beachte daß die lokale Variable local_blub nicht 
dazu zählt, der Platz dafür wird erst später bei Aufruf der Funktion auf 
dem Stack reserviert und bei Verlassen der Funktion wieder freigegeben, 
das wird auch nicht aus "data" initialisiert sondern von der Funktion 
selbst jedesmal wenn sie diese Variable anlegt bei jedem Aufruf.

Die 0 wird im startup mit ner simplen Loop in alle globalen und 
statischen Variablen reingeschrieben welche mit 0 initialisiert werden, 
die 42 und die 23 werden aus dem Flash ins RAM kopiert. Dazu werden ganz 
geschickter weise vom Linker die Variablen so angeordnet dass das in 
einem Rutsch geschehen kann, also alle initialisierten Variablen an 
aufeinander folgenden Adressen zu liegen kommen so daß er einfach nur 
einen Block am Stück aus dem Flash ins RAM kopieren kann, dieser Block 
ist "data".

Also wird Dein Programm mindestens text + data im Flash verbrauchen und 
darüberhinaus noch evtl ein bisschen mehr weil noch andere Dinge im 
Flash liegen, zum Beispiel gibts Controller da beginnt zwar die 
Vektortabelle bei 0 aber das Programm erst bei 0x0400 und dazwischen ein 
"Loch". Du könntest Dir im Zweifel auch mal die Größe des erzeugten .bin 
Files anschauen, das entspricht aufs Byte genau dem Speicherabbild das 
letztendlich an einem Stück ins Flash gebrannt wird.

von Martin M. (murmele)


Lesenswert?

Vielen vielen Dank für die Ausführliche Antwort.
Danke!

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.