Marus / cortex-debug

Visual Studio Code extension for enhancing debug capabilities for Cortex-M Microcontrollers
MIT License
987 stars 238 forks source link

Timeout issue with Openocd #27

Closed Hecatron closed 6 years ago

Hecatron commented 6 years ago

Hi, I've recently been trying this out with Visual Studio Code I'm currently using a LPC1769 test board

However I've been experiencing timeout errors when starting the debug session using openocd

Failed to launch OpenOCD GDB server: Timeout

So far I've tried

So far I've managed to get this working with a JLink Segger okay, using the following config This seems to work fine:

        {
            "name": "Debug (JLink Segger)",
            "type": "cortex-debug",
            "request": "attach",
            "servertype": "jlink",
            "cwd": "${workspaceRoot}",
            "executable": "./BUILD/LPC1768/GCC_ARM/GBD.Dlang.MbedBlinkyTest.elf",
            "device": "LPC1769",
            "interface": "swd",
        }

However using the inbuilt CMSIS-DAP / USB adapter that's built into the board, results in the timeout error

        {
            "name": "Debug (OpenOCD USB)",
            "type": "cortex-debug",
            "request": "launch",
            "device": "LPC1769",
            "servertype": "openocd",
            "cwd": "${workspaceRoot}",
            "executable": "./BUILD/LPC1768/GCC_ARM/GBD.Dlang.MbedBlinkyTest.elf",
            "configFiles": [
                "./scripts/openocd_configs/usb_boardconf.cfg"
            ]
        },

usb_boardconf.cfg

source [find interface/cmsis-dap.cfg]
source [find target/lpc17xx.cfg]
adapter_khz 500

# Make the initial connection and halt the board
init
targets
reset halt

I have managed to connect via openocd / gdb using the command line fine which suggests a problem with the plugin

openocd -f scripts\openocd_configs\usb_boardconf.cfg
arm-none-eabi-gdb.exe --eval-command="target remote localhost:3333"

It would be nice if you could just specify a gdb instance running on a specific port to connect to since I think the attach mode, still launches it's own gdb instance

Marus commented 6 years ago

Can you post a copy of all the output that is collected in the “Adapter Output” view in the VSCode output tab - and perhaps the output you get when running OpenOCD with your board.

Also, what operating system, as well as the versions for OpenOCD, VSCode and your OS.

The timeout error would mean that it wasn’t able to detect the the server is running and accepting GDB connections in a reasonable amount of time. Since your configuration looks to be reasonable (assuming all your paths are correct) I expect that some of the output is different (either as a result of your configuration file or OS versions).

I am considering at some point adding support for an externally launched - but the request type actually serves a different purpose (launch will flash/restart the microcontroller while attach should only halt the core without restarting/flashing - so that you can examine the state of a system, for example, if it ended up in an error condition).

Hecatron commented 6 years ago

Software Versions

The versions should all be the latest

I've got my setup here if your interested

I've been experimenting with getting Dlang to work although in this case I avoided that and just tested with some basic cpp code for blinking an LED

Running OpenOCD from the command line

This is the output I get from running openocd on the command line

OpenOCD Server

First start the openocd server

openocd -f scripts\openocd_configs\usb_boardconf.cfg

The config file usb_boardconf.cfg is:

# ARM CMSIS-DAP compliant adapter
# http://www.keil.com/support/man/docs/dapdebug/
source [find interface/cmsis-dap.cfg]

# Add the cpu
source [find target/lpc17xx.cfg]

# Set the Speed
adapter_khz 500

# Make the initial connection and halt the board
init
targets
reset halt

Output

Open On-Chip Debugger 0.10.0 (2017-08-21) [https://github.com/sysprogs/openocd]
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
adapter speed: 10 kHz
adapter_nsrst_delay: 200
cortex_m reset_config sysresetreq
adapter speed: 500 kHz
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : CMSIS-DAP: FW Version = 1.0
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 500 kHz
Info : SWD DPIDR 0x2ba01477
Info : lpc17xx.cpu: hardware has 6 breakpoints, 4 watchpoints
    TargetName         Type       Endian TapName            State
--  ------------------ ---------- ------ ------------------ ------------
 0* lpc17xx.cpu        cortex_m   little lpc17xx.cpu        running
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x1fff0080 msp: 0x10001ffc

GDB Server

Next starting GDB to connect to the openocd server

arm-none-eabi-gdb.exe --eval-command="target remote localhost:3333"

Output:

GNU gdb (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 8.0.50.20171128-git
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-w64-mingw32 --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Remote debugging using localhost:3333
warning: No executable has been specified and target does not support
determining executable automatically.  Try using the "file" command.
0x1fff0080 in ?? ()

At this point I can run commands like monitor resume, monitor halt etc to start and stop the led blinking

Hecatron commented 6 years ago

Thanks for pointing me towards the "Adapter Output" view, this is what I was looking for before but didn't know the name of it

openocd realtive path to config file

it looks as if the first problem is that it was having issues finding the configuration file for openocd with respect to relative paths

Open On-Chip Debugger 0.10.0 (2017-08-21) [https://github.com/sysprogs/openocd]
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
embedded:startup.tcl:60: Error: Can't find ./scripts/openocd_configs/usb_boardconf.cfg
in procedure 'script' 
at file "embedded:startup.tcl", line 60

It's finding the executable file fine with a relative path

"executable": "./BUILD/LPC1768/GCC_ARM/GBD.Dlang.MbedBlinkyTest.elf",

But for the openocd configuration I had to change it from relative to absolute to get it past that point

./scripts/openocd_configs/usb_boardconf.cfg
# Changed to
D:/SourceControl/GitRepos/GBD.Dlang.MbedBlinkyTest/scripts/openocd_configs/usb_boardconf.cfg
# Edit I also found this works
"${workspaceRoot}/scripts/openocd_configs/usb_boardconf.cfg"

This might just be a case of changing the examples on the site to use ${workspaceRoot} instead of ./ when specifying paths

unable to change server port after init

The next problem seems to be the following in Adapter Output:

Open On-Chip Debugger 0.10.0 (2017-08-21) [https://github.com/sysprogs/openocd]
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
adapter speed: 10 kHz
adapter_nsrst_delay: 200
cortex_m reset_config sysresetreq
adapter speed: 500 kHz
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : CMSIS-DAP: FW Version = 1.0
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 500 kHz
Info : SWD DPIDR 0x2ba01477
Info : lpc17xx.cpu: hardware has 6 breakpoints, 4 watchpoints
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* lpc17xx.cpu        cortex_m   little lpc17xx.cpu        halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x1fff0080 msp: 0x10001ffc
Warn : unable to change server port after init

Debug Console:

Reading symbols from d:\SourceControl\GitRepos\GBD.Dlang.MbedBlinkyTest\BUILD\LPC1768\GCC_ARM\GBD.Dlang.MbedBlinkyTest.elf...
done.
"monitor" command not supported by this target.
"monitor" command not supported by this target.

With the following prompt

Falied to launch GDB: localhost: 50000: No connection could be made because the target machine actively refused it
(from target-select extended-remote localhost:50000)

I tried turning off windows firewall, and trying older versions of openocd but that didn't seem to work

Hecatron commented 6 years ago

Just to narrow things down a bit I tried using the vanilla gdb plugin and this seems to work okay

launch.conf

        {
            "name": "Debug (OpenOCD USB) - Attach to GDB",
            "type": "gdb",
            "request": "attach",
            "executable": "${workspaceRoot}/BUILD/LPC1768/GCC_ARM/GBD.Dlang.MbedBlinkyTest.elf",
            "target": ":3333",
            "remote": true,
            "cwd": "${workspaceRoot}",
            "gdbpath": "arm-none-eabi-gdb.exe",
            "autorun": [
                "monitor reset halt",
                "load ${workspaceRoot}/BUILD/LPC1768/GCC_ARM/GBD.Dlang.MbedBlinkyTest.elf"
             ]
        },

But of course I need to launch openocd separately first

openocd -f scripts\openocd_configs\usb_boardconf.cfg

And it's probably lacking a few features specific to the cortex-m processor

Marus commented 6 years ago

I do know OpenOCD can be a little bit strange sometimes with it's pathing for configuration files - so not terribly surprising to me that it was having that issue with not finding the script and you had to specify the full path (fortunately you can use the ${workspaceRoot} variable as you noticed to keep it sort of relative). I'll try to see if I can figure out why OpenOCD isn't properly getting the CWD.

As for the followup issue - I think where you're running into issues is that your OpenOCD configuration file does a number of things that standard OpenOCD files do not do (namely the init, targets and reset halt commands. These are preventing the normal initialization that the extension performs from functioning (for example cannot set a port to use for the GDB server; the extension also takes care of halting, flashing, restarting the CPU at the appropriate times as well). I expect if you remove those last three commands from your OpenOCD configuration that it may work.

Hecatron commented 6 years ago

okay I tried removing the last 3 lines as you've said. There's some activity (the green light for the CMSIS-DAP adapter flashes for a bit) which means ether it's flashing, or running openocd server for a short while

But it then drops out with the below error

Error prompt

Failed to launch GDB: Remote communication error. Target disconnected. Target disconnected.: Success.
(from target-select extended-remote localhost:50000)

Adapter Output

Open On-Chip Debugger 0.10.0 (2017-08-21) [https://github.com/sysprogs/openocd]
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
adapter speed: 10 kHz
adapter_nsrst_delay: 200
cortex_m reset_config sysresetreq
adapter speed: 500 kHz
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : CMSIS-DAP: FW Version = 1.0
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 500 kHz
Info : SWD DPIDR 0x2ba01477
Info : lpc17xx.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : accepting 'gdb' connection on tcp/50000
Error: Target not halted
Error: auto_probe failed
Error: Connect failed. Consider setting up a gdb-attach event for the target to prepare target for GDB connect, or use 'gdb_memory_map disable'.
Error: attempted 'gdb' connection rejected

Thanks for all your help btw

Hecatron commented 6 years ago

Edit I now have it working thanks to this link https://mcuoneclipse.com/2016/04/09/solution-for-openocd-cannot-communicate-target-not-haltet/

The above 3 lines mentioned before are removed and I just needed to add the below lines to the bottom of the configuration file I was using this triggers a halt on gdb connecting to openocd This seems to allow single stepping / debugging the code, woohoo

$_TARGETNAME configure -event gdb-attach {
   halt
}
$_TARGETNAME configure -event gdb-attach {
   reset init
}
Marus commented 6 years ago

Glad you got it figured out. Unfortunately I’m not terribly familiar with OpenOCD, as I mostly use J-Link or the Black Magic Probe myself, but wanted to try to support it as it is fairly popular in the hobbyist community. So I couldn’t give you too much advice with writing your own configuration in a manner that would work, just knew it should be possible - as I was able to use it with about 10 or so of their supplied configuration files across a number of chip manufacturers / boards. Glad you found the right combination and posted the details, as it may help others with similar problems in the future.

You mentioned that you are experimenting with Dlang - at the moment I don’t believe you’ll be able to set breakpoints for D as I haven’t listed it in the accepted languages for VSCode. If you let me know what extension you’re using for D in vscode I can add the laungauge identifier to the allowed breakpoints. That should at least allow you to step through code and set breakpoints in D (although some features such as the disassembly view and the global/static scopes of the variables view may not function properly in D)

Hecatron commented 6 years ago

I've tried using Dlang with breakpoints and it appears to work already as is. I'm currently able to breakpoint both cpp and .d files and hit the breakpoints in both at the same time

The D plugins I'm using for VSCode is https://github.com/Pure-D/code-d (webfreak.code-d and webfreak.dlang-bundle) This appears to be the more popular one at the moment

Marus commented 6 years ago

Ok - interesting that I don’t have it listed as a language I can accept breakpoints for but it is still allowing it - might be something in the language definition that says breakpoints in D are compatible with ones in C/CPP that causes it to allow it.

Samonitari commented 6 years ago

Well, the thing is, Rust breakpoints also worked before you explicitly enabled them

Marus commented 6 years ago

Hum, that’s very interesting - strange that the VS Code package.json has a setting for “enableBreakpointsFor” if they will let you set them anyway without the language being listed.

Marus commented 6 years ago

Just read something about it - apparently the breakpoints will be enabled if any debug provider or language provider says that a language should have breakpoints; seems like an odd decision to me that this isn’t dependent on the current debug session provider.

So I guess in this case you have another extension (probably the language definition) that says D/rust should have breakpoints.

Hecatron commented 6 years ago

I think I noticed with this one which is an older plugin, that breakpoints wern't possible https://github.com/dlang-vscode/dlang-vscode

But with this one, you could add breakpoints (this one seems to have a lot more downloads) https://github.com/Pure-D/code-d