[nRF Connect for VS Code][BUG?] Debugging in vscode does not restore target state when stopping a debug session

Hi,

as mentioned in the title, when using the official vscode extension (nRF Connect for VS Code) for debugging and stopping a debug session, the target state does not get restored. Apparently the debugging interface is just left powered on even after the debug session is stopped, which leads to a high power consumption. That's actually the reason why I discovered this (at the time of writing this, not yet confirmed) bug.

Background on the power consumption observation: I have a stripped down board here with essentially nothing but a nrf52840 on it. I'm running a zephyr based firmware on it to get it to consume as little current as possible at 3V. The firmware just does a `k_sleep(K_FOREVER);`, that's it. All peripherals should be disabled. I get a current draw of about 5,2 uA (measured with KEITHLEY and ROHDE&SCHWARTZ power supply) that way. With the debugger connected the current draw is around 30 uA. So Far everything is normal and as expected.

When I start a debug session via the vscode plugin, of course the current consumption goes significantly up, to 1.5 mA. After stopping the debugging session the (button with red square in vscode), the current consumption rises a bit more to 1.6 mA and stays there. I found this post:  Resetting DIF to reduce interface current on nRF52 

It explains how to turn off the debugging interface with commands via JLinkExe:


```
SWDSelect
SWDWriteDP 1 0x04000000
exit
```

After doing this, I'm back to the expected 30 uA as before. Therefore I think that the extension is just not resetting the target state.

In contrast here is what happens with Cortex-Debug extension for vscode (https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug) in the gdb-server terminal that pops up:

```
GDB closed TCP/IP connection (Socket 13)
Restoring target state and closing J-Link connection...
Shutting down..
```

and the current consumption goes back to 30 uA as expected.


With the nrf-connect extension when stopping the debugging session I only see in the debug console:

```

Kill the program being debugged? (y or n) [answered Y; input not from terminal]
[Inferior 1 (Remote target) killed]
JLinkGDBServerCLExe: GDB closed TCP/IP connection (Socket 12)
The program '/home/alex/workspace/window-sensor-new/firmware/application_firmware/sample/button-led/build_maco_contact_type1/zephyr/zephyr.elf' has exited with code 0 (0x00000000).

```

But no trace of "Restoring target state and closing J-Link connection...".

After investigating a bit more, it seems to me that the cortex-debug extension simply uses the JLinkGDBServerCLExe underneath. If I manually do:

`nrfjprog --reset &&  JLinkGDBServerCLExe -if swd -device NRF52840_xxaa -speed 4000 -nogui -nohalt -noir`

 

I see the same current draw increase to 1.5 mA. After closing the gdb server (ctrl+c) I see:

```

Waiting for GDB connection...^CRestoring target state and closing J-Link connection...
Shutting down...

```

So the target state seems to be restored here as well. 

What does the nRF Connect for VS Code do differently? Does it not use `JLinkGDBServerCLExe` underneath? Does it stop/kill it differently so that it does not do the "Restoring target state and closing J-Link connection..."? Is this a bug?

  • Hello sorry about the wait, things are a bit busy these days.

    Thanks for reporting this! :) I'll forward it to the relevant R&D team.

    One thing I do not understand though, is how this is a problem for you. Would it make a difference for you and your workflow if it turns out that there that the target state won't get restored when stopping a debugging session? Do you need to use the debuggere while measuring current consumption?

    Regards,

    Elfving

  • Hi Elfving, thank you for your reply. It is a problem, because if I didn't find that the excessive current draw is caused by the extension not turning of the debug interface off after stopping the debug session, I would be left not understanding what is happening. I would be searching the problem in my code/setup.

    Another problem caused by not resetting target state is this: when setting breakpoints apparently they are set by patching the flash. Since the extension does not reset these when disconnecting a debug session, the breakpoints remain active. Now when I power cycle the board it hits a hard fault because of running into a breakpoint instruction with no debugger attached. This is also not intuitive. If the developer does not know what causes this and if the breakpoiint is only hit under certain conditions then it is very hard to find out what is happening.

    Alex

  • I've forwarded this suggestion to the relevant team Slight smile

    One thing they did mention though is that you should typically reset the device before the power consumption goes back to normal, that is the only way to make 100% sure everything goes back to base line. I'm not sure about that, but if that is the case, even if we were to add the few lines of code you provided to make sure it resets I guess it might not be enough. So maybe this isn't a bug per se, as I am not sure if the current consumption going back to the baseline was even something they aimed for. If you stopped the debug session, and got a current draw of 50µA, I guess that would be confusing to some degree as well. 

    Either way, I understand that this has been confusing for you, and I am sorry about that.

    Regards,

    Elfving

  • One thing they did mention though is that you should typically reset the device before the power consumption goes back to normal, that is the only way to make 100% sure everything goes back to base line.

    With regard to turning off the debug interface, this is correct, but not with regard to breakpoints. As mentioned, the breakpoints remain active even after stopping the debug session. When you power cycle the board and have no debugger attached, the device will hit the breakpoints that the extension did not remove on disconnect and will run into a hard fault.

    I'm not sure about that, but if that is the case, even if we were to add the few lines of code you provided to make sure it resets I guess it might not be enough.

    Ok, that seems to confirm that the extension is not using JLinkGDBServerCLExe under the hood and therefore not using its "Restoring target state and closing J-Link connection..."-feature. But yes, you are right that this is probably not enough. I randomly found these commands here on devzone and I don't know exactly what they are doing, but they seem to turn off the debug interface. They don't reset the breakpoints.

    So maybe this isn't a bug per se, as I am not sure if the current consumption going back to the baseline was even something they aimed for. If you stopped the debug session, and got a current draw of 50µA, I guess that would be confusing to some degree as well. 

    From my point of view if it is not a bug, then at least it is very unexpected and undocumented behavior: after stopping a debug session ran by the extension, the device state is left tampered with. Why should I expect that the extension leaves breakpoint instructions that it injected into the code active after I stopped the debugging session? Looks like a bug to me. Then after debugging I'm left wondering why the device is "bricked" and only continues working after re-flashing it.

    Either way, I understand that this has been confusing for you, and I am sorry about that.

    No worries, all good, that's why I'm here to annoy you guys with my questions Slight smile

    Best regards

    Alex

  • lx_brz said:

    With regard to turning off the debug interface, this is correct, but not with regard to breakpoints. As mentioned, the breakpoints remain active even after stopping the debug session. When you power cycle the board and have no debugger attached, the device will hit the breakpoints that the extension did not remove on disconnect and will run into a hard fault.

    Well that is strange. I see now that you mentioned this in your previous response as well, I didn't notice that before.

    Are you seeing this with a DK as well? I just tried it here, with a few breakpoints on a Blinky sample, and restarting it seemed to do the trick. I didn't think the debugger actually patched the flash itself. How are you testing this on your side?

    lx_brz said:
    No worries, all good, that's why I'm here to annoy you guys with my questions Slight smile

    Hehe sounds good Thumbsup Keep them coming!

    Regards,

    Elfving

Related