Marus / cortex-debug

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

Feature request: Setting port number of stlink gdbserver #752

Closed nono313 closed 1 year ago

nono313 commented 1 year ago

Is it possible to set manually the port to be used by gdbserver when using servertype of "stlink" ? When working with the STM32WL55 dual core, I need to set one gdbserver to some value (like 61234), and the other gdbserver to a value that is at least 4 points above (eg: 61238).

When I start a launch config, I see that the port 50000 is used. I do not see any option available to change this default port in my launch.json file. Would it be possible to implement such feature ?

haneefdm commented 1 year ago

https://github.com/Marus/cortex-debug/blob/master/debug_attributes.md

You can set numberOfProcessors to some value (like 2, 3 or 4) and set targetProcessor to 1.

Is there documentation on how stlink assigns port to processors? With openocd, they go sequential from the first one and thus we reserve numberOfProcessors worth or ports and connect according to targetProcessor. pyOCD is the same.

But no, there is no option to specify a port number.

nono313 commented 1 year ago

This document explains the process starting page 9 : https://www.st.com/resource/en/application_note/an5564-getting-started-with-projects-based-on-dualcore-stm32wl-microcontrollers-in-stm32cubeide-stmicroelectronics.pdf

Thanks for the suggestion with numberOfProcessors and targetProcessor. I guess it should be possible to do what I want but right now I am not getting there.

Here is what I am doing :

{
            "name": "Debug COMFORT CM4 - ST-Link",
            "cwd": "${workspaceFolder}",
            "type": "cortex-debug",
            "executable": "${command:cmake.launchTargetDirectory}/project_CM4", // "${command:cmake.launchTargetPath}",
            "request": "launch",                //Use "attach" to connect to target w/o elf download
            "servertype": "stlink",
            "device": "STM32WL55JC",
            "interface": "swd",
            "serialNumber": "",                 //Set ST-Link ID if you use multiple at the same time
            "runToEntryPoint": "main",
            "svdFile": "${workspaceFolder}/CM4/STM32WL5x_CM4.svd",      //Path to SVD file to see registers
            "v1": false,
            "showDevDebugOutput": "both",
            "serverArgs": [
                "-l", "1",
                "-m", "0",
                "-k",
            ],
            "numberOfProcessors":4,
            "targetProcessor":0,
        },
        {
            "name": "Attach COMFORT CM0 - ST-Link",
            "cwd": "${workspaceFolder}",        //Path from where commands are executed
            "type": "cortex-debug",             //Debug 
            "executable": "${command:cmake.launchTargetDirectory}/project_CM0PLUS", // "${command:cmake.launchTargetPath}",
            "request": "attach",                //Use "attach" to connect to target w/o elf download
            "servertype": "stlink",             //Use stlink setup of cortex-M debug
            "device": "STM32WL55JC",            //MCU used
            "interface": "swd",                 //Interface setup
            "serialNumber": "",                 //Set ST-Link ID if you use multiple at the same time
            // "runToEntryPoint": "main",          //Run to main and stop there
            "svdFile": "${workspaceFolder}/CM0PLUS/STM32WL5x_CM0P.svd",      //Path to SVD file to see registers
            "v1": false,
            "showDevDebugOutput": "both",
            "serverArgs": [
                "-l", "1",
                "-m", "1",
                "-t", "-s",
            ],
            "numberOfProcessors":4,
            "targetProcessor":4,
        },

Looking at the gdbserver commands in the Terminal view, I have :

"ST-LINK_gdbserver.exe" -p 50000 -cp "C:\\ST\\STM32CubeIDE_1.10.1\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.0.301.202207041506\\tools\\bin" --swd --halt -l 1 -m 0 -k
"ST-LINK_gdbserver.exe" -p 50007 -cp "C:\\ST\\STM32CubeIDE_1.10.1\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.0.301.202207041506\\tools\\bin" --swd --attach --halt -l 1 -m 1 -t -s

When I use STM32CubeIDE to debug my project, I am able to debug both cores at the same time with the following gdbserver commands :

"ST-LINK_gdbserver.exe -p 61234 -l 1 -d -t -s -cp C:\ST\STM32CubeIDE_1.10.1\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.0.301.202207041506\tools\bin -m 0 -k --halt
"ST-LINK_gdbserver.exe -p 61238 -l 1 -d -t -s -cp C:\ST\STM32CubeIDE_1.10.1\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.0.301.202207041506\tools\bin -m 1 -g

Any idea on how to get the same behavior as CubeIDE but with Cortex-Debug ?

haneefdm commented 1 year ago

targetProcessor must be less than numberOfProcessors

nono313 commented 1 year ago

Thanks, I think I'm getting closer now.

I have changed the launch for the Cortex-M4 to this :

            "numberOfProcessors":5,
            "targetProcessor":0,

And the Cortex-M0 (second core) to this :

            "numberOfProcessors":5,
            "targetProcessor":4,

This is the error I get when I try to start the second debug session (attach to Cortex-M0) :

Failed to launch GDB: localhost:50012: Connection timed out. (from target-select extended-remote localhost:50012)

The two gdb server instances start respectively on port 50000 and 50008 so I don't know where the 50012 comes from.

haneefdm commented 1 year ago

In Eclipse (or VSCode), can you enable the LOG file and see where all the ports are going. What is stlink doing with the four ports per processor?

haneefdm commented 1 year ago

How are you launching both configs?

haneefdm commented 1 year ago

The numberOfProcessors and targetProcessor will not work. with STLink. That only works for cases where you have one server serving multiple cores and sharing is happening at the server level. Here (like JLink), we have multiple servers serving each gdb client and sharing is happening at the HW Link level.

Depending on how you are launching the configs, it may already work. So, I need to know how you are launching the configs in launch.json

nono313 commented 1 year ago

In CubeIDE, I start a first debug session on port 61234 for the M4, I run the program and then after some time, I start the second debug session (61238 for M0).

In VS Code, I select the Debug CM4 launch config on the "Execute and Debug" tab and then click the green 'Play' arrow to start the debug session. Once It is started and I run the code (continue button), I select the Attach CM0 debug session and click on the Run arrow. This is where I get the 50012 port error message.

So in this case what I think is needed is two different gdbserver, one on each port and each connected to a core.

If I remove the numberOfProcessors and targetProcessor, I am able to debug either the M4 or the M0 as long as I only have one debug session in progress. The problem only occure when I try to start debugging both cores.

haneefdm commented 1 year ago

If I remove the numberOfProcessors and targetProcessor, I am able to debug either the M4 or the M0 as long as I only have one debug session in progress. The problem only occure when I try to start debugging both cores.

We should be able to do this with both cores. The way you are starting each session. Each session will have its own gdb-server.

But the serverArgs for both should be correct and looks like you already do. Remove the numberOfProcessors/targetProcessor and let me know what error(s) you are seeing. Cortex-Debug automatically avoids ports taken by the first session, so not sure what is going on.

haneefdm commented 1 year ago

For each server launched, we create a gdb-server item in the TERMINAL tab. You can see the output of each gdb-server. Can you show me what is going on there. You will see messages from the gdb-server about ports being created, etc.

nono313 commented 1 year ago

I have changed a bit my launch.json. Here is the latest version :

 {
            "name": "Debug COMFORT CM4 - ST-Link",
            "cwd": "${workspaceFolder}",
            "type": "cortex-debug",
            "executable": "${command:cmake.launchTargetDirectory}/project-comfort_CM4", // "${command:cmake.launchTargetPath}",
            "request": "launch",                //Use "attach" to connect to target w/o elf download
            "servertype": "stlink",
            "device": "STM32WL55JC",
            "interface": "swd",
            "serialNumber": "",                 //Set ST-Link ID if you use multiple at the same time
            "runToEntryPoint": "main",
            "svdFile": "${workspaceFolder}/CM4/STM32WL5x_CM4.svd",      //Path to SVD file to see registers
            "v1": false,
            "showDevDebugOutput": "both",
            "serverArgs": [
                "-l", "1",
                "-m", "0",
                "-k",
                "-t","-s"
            ],
        },
        {
            "name": "Attach COMFORT CM0 - ST-Link",
            "cwd": "${workspaceFolder}",        //Path from where commands are executed
            "type": "cortex-debug",             //Debug 
            "executable": "${command:cmake.launchTargetDirectory}/project-comfort_CM0PLUS", // "${command:cmake.launchTargetPath}",
            "request": "attach",                //Use "attach" to connect to target w/o elf download
            "servertype": "stlink",             //Use stlink setup of cortex-M debug
            "device": "STM32WL55JC",            //MCU used
            "interface": "swd",                 //Interface setup
            "serialNumber": "",                 //Set ST-Link ID if you use multiple at the same time
            // "runToEntryPoint": "main",          //Run to main and stop there
            "svdFile": "${workspaceFolder}/CM0PLUS/STM32WL5x_CM0P.svd",      //Path to SVD file to see registers
            "v1": false,
            "showDevDebugOutput": "both",
            "serverArgs": [
                "-l", "1",
                "-m", "1",
                "-t", "-s",
            ],
        },

Oh and actually now it works fine ! I see port 50000 and 50004 being used. Is this the expected behavior ?

When I compare with the previous launch, I see that I was missing some options, like the -t on the M4 side for shared ST-LINK. Could that be the reason why it did not work before ?

haneefdm commented 1 year ago

Oh and actually now it works fine ! I see port 50000 and 50004 being used. Is this the expected behavior ?

After the first launch, the second launch will automatically avoid any port that is already in use until it finds some unused ones. This way, you can have multiple sessions going with multiple boards and we will try to find unused ports.

Yes, the -t enables sharing of the HW link. And, the -m is required to select the appropriate debug access port (which is defined by the silicon vendor). These two options were needed and we can't figure those out. (we could have enabled sharing by default -- maybe in the next release).

In case you did not know, we can launch the second launch config for you and save you a couple of steps.

https://github.com/Marus/cortex-debug/wiki/Multi-core-debugging

You would need something like

    "chainedConfigurations": {
        "enabled": true,
        "waitOnEvent": "postInit",
        "detached": true,
        "lifecycleManagedByParent": true,   // Can be true or false in your case.
        "launches": [                              // Array of launches. Order is respected
            {
                "name": "Attach COMFORT CM0 - ST-Link",     // Name of another configuration
                "folder": "${workspaceFolder}"
            }
        ]
    }
nono313 commented 1 year ago

I noticed the 'chainedConfigurations' option but did not know how to use it.

I just tried it and it looks nice indeed. I do have one issue though : I need my firmware on the M4 to run or at least reach a specific point in the firmware before I can connect to the M0. Is it possible to have some delay after a "Continue" comment for the waitOnEvent ?

EDIT : Oh and with the chainConfiguration added to the M4 config, I get gdbserver launched on port 50002 instead of 5004 for the M0. Is this expected ? I added the chainedConfiguration inside the M4 launch config.

haneefdm commented 1 year ago

The waitOnEvent can be used in conjunction with a delay. See that wiki page. But no, there is no event for a continue or any other gdb operation.

However, you can define what postInit means by having enough gdb-commands in your launch.json to accomplish what you want. See the Wiki page.

EDIT : Oh and with the chainConfiguration added to the M4 config, I get gdbserver launched on port 50002 instead of 5004 for the M0. Is this expected ? I added the chainedConfiguration inside the M4 launch config.

Turns out that STLInk gdb-server only uses two ports. Not four.

nono313 commented 1 year ago

So if I run manually the M4, click continue, then start the M0, I get ports 50000 and 50004, but if I try to use chainedConfig, I get 50000 and 50002 ? I struggle to see why the chainedConfig should act differently here.

Ok I will have a look at the postInit for the delay thanks.

haneefdm commented 1 year ago

Can you attach the output from TERMINAL gb-server tab? Without that, I cannot tell what is going on. It will look something like this...

image
haneefdm commented 1 year ago

So if I run manually the M4, click continue, then start the M0, I get ports 50000 and 50004, but if I try to use chainedConfig, I get 50000 and 50002

That means, gdb-server is allocating more ports but not sure why and for what. This is why we need to look at the TERMINAL tab I mentioned above.

nono313 commented 1 year ago

Here is the first gdbserver window :

[2022-10-04T15:51:10.225Z] SERVER CONSOLE DEBUG: onBackendConnect: gdb-server session connected. You can switch to "DEBUG CONSOLE" to see GDB interactions.
"C:\\ST\\STM32CubeIDE_1.10.1\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.win32_2.0.300.202203231527\\tools\\bin\\ST-LINK_gdbserver.exe" -p 50000 -cp "C:\\ST\\STM32CubeIDE_1.10.1\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.0.301.202207041506\\tools\\bin" --swd --halt -l 1 -m 0 -k -t -s

STMicroelectronics ST-LINK GDB server. Version 7.0.0
Copyright (c) 2022, STMicroelectronics. All rights reserved.

Starting server with the following options:
        Persistent Mode            : Disabled
        Logging Level              : 1
        Listen Port Number         : 50000
        Status Refresh Delay       : 15s
        Verbose Mode               : Disabled
        SWD Debug                  : Enabled
        InitWhile                  : Enabled

Waiting for debugger connection...
Debugger connected
Waiting for debugger connection...
      -------------------------------------------------------------------
                       STM32CubeProgrammer v2.11.0                  
      -------------------------------------------------------------------

Log output file:   C:\Users\XXX\AppData\Local\Temp\STM32CubeProgrammer_a25300.log
ST-Link Server is running on port : 7184
ST-LINK SN  : 001B00163156501920323443
ST-LINK FW  : V3J10M3B5S1
Board       : STLINK-V3SET
Voltage     : 3.28V
SWD freq    : 24000 KHz
Connect mode: Under Reset
Reset mode  : Hardware reset
Device ID   : 0x497
Revision ID : Rev Y
Device name : STM32WLxx
Flash size  : 256 KBytes
Device type : MCU
Device CPU  : Cortex-M4
BL Version  : 0xc4

Memory Programming ...
Opening and parsing file: ST-LINK_GDB_server_a25300.srec
  File          : ST-LINK_GDB_server_a25300.srec
  Size          : 127.59 KB 
  Address       : 0x08004000 

Erasing memory corresponding to segment 0:
Erasing internal memory sectors [8 71]
Download in Progress:

File download complete
Time elapsed during download operation: 00:00:03.405

Verifying ...

Download verified successfully 

And here is the second :

[2022-10-04T15:51:20.269Z] SERVER CONSOLE DEBUG: onBackendConnect: gdb-server session connected. You can switch to "DEBUG CONSOLE" to see GDB interactions.
"C:\\ST\\STM32CubeIDE_1.10.1\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.win32_2.0.300.202203231527\\tools\\bin\\ST-LINK_gdbserver.exe" -p 50004 -cp "C:\\ST\\STM32CubeIDE_1.10.1\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.0.301.202207041506\\tools\\bin" --swd --attach --halt -l 1 -m 1 -t -s

STMicroelectronics ST-LINK GDB server. Version 7.0.0
Copyright (c) 2022, STMicroelectronics. All rights reserved.

Starting server with the following options:
        Persistent Mode            : Disabled
        Logging Level              : 1
        Listen Port Number         : 50004
        Status Refresh Delay       : 15s
        Verbose Mode               : Disabled
        SWD Debug                  : Enabled

Target unknown error 32

Error in initializing ST-LINK device.
Reason: Unknown. Please check power and cabling to target.
[2022-10-04T15:51:20.774Z] SERVER CONSOLE DEBUG: onBackendConnect: gdb-server session closed
GDB server session ended. This terminal will be reused, waiting for next session to start...

Actually here I do have 50004 because I have used postInit. It is with postStart that I get 50002 :

[2022-10-04T15:53:50.818Z] SERVER CONSOLE DEBUG: onBackendConnect: gdb-server session connected. You can switch to "DEBUG CONSOLE" to see GDB interactions.
"C:\\ST\\STM32CubeIDE_1.10.1\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.win32_2.0.300.202203231527\\tools\\bin\\ST-LINK_gdbserver.exe" -p 50002 -cp "C:\\ST\\STM32CubeIDE_1.10.1\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.0.301.202207041506\\tools\\bin" --swd --attach --halt -l 1 -m 1 -t -s

STMicroelectronics ST-LINK GDB server. Version 7.0.0
Copyright (c) 2022, STMicroelectronics. All rights reserved.

Starting server with the following options:
        Persistent Mode            : Disabled
        Logging Level              : 1
        Listen Port Number         : 50002
        Status Refresh Delay       : 15s
        Verbose Mode               : Disabled
        SWD Debug                  : Enabled

Target unknown error 32

Error in initializing ST-LINK device.
Reason: Unknown. Please check power and cabling to target.
[2022-10-04T15:53:51.269Z] SERVER CONSOLE DEBUG: onBackendConnect: gdb-server session closed
GDB server session ended. This terminal will be reused, waiting for next session to start...

I have not tried to add a delay after starting the first M4 config so I am not expecting this to work (even with proper port) as the M0 is not started.

nono313 commented 1 year ago

I tried adding this to the M4 config :

            "postLaunchCommands":[
                "shell sleep 30"
            ],

But I still get a GDB server quit unexpectedly error with the following log on the M0 gdbserver:

[2022-10-04T16:11:03.324Z] SERVER CONSOLE DEBUG: onBackendConnect: gdb-server session connected. You can switch to "DEBUG CONSOLE" to see GDB interactions.
"C:\\ST\\STM32CubeIDE_1.10.1\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.win32_2.0.300.202203231527\\tools\\bin\\ST-LINK_gdbserver.exe" -p 50004 -cp "C:\\ST\\STM32CubeIDE_1.10.1\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.0.301.202207041506\\tools\\bin" --swd --attach --halt -l 1 -m 1 -t -s

STMicroelectronics ST-LINK GDB server. Version 7.0.0
Copyright (c) 2022, STMicroelectronics. All rights reserved.

Starting server with the following options:
        Persistent Mode            : Disabled
        Logging Level              : 1
        Listen Port Number         : 50004
        Status Refresh Delay       : 15s
        Verbose Mode               : Disabled
        SWD Debug                  : Enabled

Target unknown error 32

Error in initializing ST-LINK device.
Reason: Unknown. Please check power and cabling to target.
[2022-10-04T16:11:03.725Z] SERVER CONSOLE DEBUG: onBackendConnect: gdb-server session closed
GDB server session ended. This terminal will be reused, waiting for next session to start...

The exact same setup without the chaindConfiguration works fine if clock manually on the second debug session so it's not a big issue.

haneefdm commented 1 year ago

postInit is the default and almost always the better way. In most cases, postStart is way too early.

While what you did might work, to delay (did you miss this in the Wiki page), you should be doing...

image

Did you notice the following? This is why the server is closing and terminating the session.

Target unknown error 32

Error in initializing ST-LINK device.
Reason: Unknown. Please check power and cabling to target.

Something may be missing from the command-line args for the M0 session. Can you compare carefully with the Eclipse version...

nono313 commented 1 year ago

Yes I did miss the delayMs sorry.

Thank you so much. it's working great ! I now have two stacks in the stack view : one for the M4 and one for the M0, which is of course different than if I start manually both launches.

Thanks again for your help, I'm closing the issue.

haneefdm commented 1 year ago

Would you mind editing the Wiki Page and adding your example? It will help out many people and especially myself as my bandwidth is becoming impossible.

Anyone can edit our Wiki pages. I created a section for you.

https://github.com/Marus/cortex-debug/wiki/Multi-core-debugging#st-link-notes

nono313 commented 1 year ago

Yes I'll add my use case.

Not sure if it's relevant for any STM32 as I think most of my issues are with the dual core setup but I see how I can integrate that to the wiki.

haneefdm commented 1 year ago

That entire page is for multi-core debug. Nothing else.

Scroll all the way down and you will find an empty section for 'ST-Link notes'

nono313 commented 1 year ago

Oh right, yes thanks I'll add it, specifying i'm on an STM32WL. It should work the same witht he STM32WB, don't know for other dual cores of ST (I'll explain all)

haneefdm commented 1 year ago

Are you sure you needed two SVD fies? One for each core? svd files are heavy and can slow down debug processes. Generally, an MCU has all the peripherals in one SVD file. But there are those that can use different ones because generally, the CPUSS and other ARM specific stuff will be different.

If ST provided different SVD files (content-wise) for each core, then that is totally legit.

nono313 commented 1 year ago

ST does provide two SVD files. They seem pretty similar but there are some distinctions.

nono313 commented 1 year ago

I have updated the wiki. Don't hesitate to tell me if you think some info are missing

haneefdm commented 1 year ago

One thing I would do differently even in your situation is deciding what to program. For instance, for the "Debug CM4+CM0 - ST-Link" config, I would use "loadFiles" to program both cores.

"loadFiles": [    // Programs to load/program
    "${workspaceFolder}/build/project_CM0PLUS",
    "${workspaceFolder}/build/project_CM4"
],

I am not sure if the order matters. When you use loadFiles, the executable is only used for symbols and not for programming.

This way, the CM0 program will always be up-to-date.

haneefdm commented 1 year ago

Oh, and thanks for editing the Wiki

nono313 commented 1 year ago

Oh nice. So I don't need to have the prelaunchtask to flash the M0+, I can just put both M4 and M0° in loadFiles. I'll do that, test it and update the wiki then