cancel
Showing results for 
Search instead for 
Did you mean: 

Can i issue GDB commands post flash while starting a debugging session automatically?

marbel
Associate II

Hi

I am trying to overcome the limitation that M0 cores cant detect if they are running in a debugging session or not.

For an M3/M4, I would have written something like:

bool InDebugMode(void) {
	bool ret_val = false;
	if ( ((CoreDebug->DHCSR) & 1u) == 1u) {
		ret_val = true;
	}
	return ret_val;
}

One way that seems to work is to this instead

First set up a global variable that may not op optimized and then check on that variable

static volatile uint32_t i_n_Debug_Mode = 0u;
 
bool InDebugMode(void) {
	bool ret_val = false;
	if (i_n_Debug_Mode == 0xDEADBEAFu) {
		ret_val = true;
	}
	return ret_val;
}

Then, after the program has been flashed, I switch to the "Debugger console" tab and enter

set variable i_n_Debug_Mode = 0xDEADBEAF

And after that I hit run.

Now I get the desired result.

However it would be nice if I could automate this.

I have tried to enter this command in various places in the Run => Debug configurations of my ST-link GDB server configurations, but so far I have come up empty handed.

Does anyone have a solution to this or know of a better approach?

Best regards

Martin

2 REPLIES 2
mattias norlander
ST Employee

Hi Martin,

From the Armv6-m:

https://developer.arm.com/documentation/ddi0419/latest/

Access to the DHCSR from software running on the processor is IMPLEMENTATION DEFINED.

I will check internally if we (ST) have differences between M0 and M3/M4 products with respect to accessing DHCSR.

A proposal to solve your issue would be as you said to let the debugger check this. You could do this by:

  1. Your embedded code contains a variable like bool in_Debug_Mode = 0;
  2. Upon debug launch or debug restart your can let GDB write in_Debug_Mode = 1. This must be done after Reset_Handler has been executed and before main()
  3. Your application checks the variable to determine in debug or not

Since this variable in_Debug_Mode, is only written to by the debugger it could potentially be removed by optimization so let's place it at an explicit location and use the KEEP parameter in the linker script.

In the C-code you can do this:

__attribute__((section(".debug_mode"))) volatile bool in_Debug_Mode = 0;

In the linker script add the in italic

  *(.RamFunc*)    /* .RamFunc* sections */

KEEP(*(.debug_mode))

In the debug configuration > Startup tab, do this:

  • Uncheck Set breakpoint at: main
  • Uncheck Resume
  • In Run Commands add:

tbreak main

c

set in_Debug_Mode=1

Let your own C code just check if ( 1 == in_Debug_Mode )

Next issue will be if you want to use "Restart" button when debugging. In such case the Run commands are not re-applied, which means Reset_Handler will re-initialize the data section and thereby the in_Debug_Mode to 0. This is not good for your use case.

What do you do about it? You rely on Restart configurations.

  • Define your own restart configuration
  • Choose Type= None
  • Additional commands

monitor reset

tbreak main

set in_Debug_Mode=1

I think this could solve the issues if you want to rely more on the debugger then embedded application logic.

Hi

Thanks for the quick reply.

Regarding access to DHCSR I can atleast say that it is not available for the stm32F072rb, that i am working on right now.

Looking at the correct reference manual (RM0091) it states that the debug access registers is accessed via the debug access port.

Also there are no defines in CMSIS for the CoreDebug block.

Then moving on to the gcc setup to modify the in_Debug_Mode variable, i get the "Run" part of it to work fine, but the restart i have more problems with

For anyone else finding this thread "Restart configurations" is found when you clock the dropdown besides the restart button.

However changing according to the described settings did not work. I also tried to change the default "Reset" one but that also did nothing.

Best regards

Martin