cancel
Showing results for 
Search instead for 
Did you mean: 

Automatically set DBGMCU when debugging starts.

PWint
Associate III

I am debugging my software on STM32L452CCU6 and it is mostly in sleep mode. By default, this disables clocks to the debug port, and the debugger (using STMCube) prints out the message "Target is not responding, retrying...". After a couple of times, I lose the debugger.

Setting the correct bits in DBGMCU keeps the clocks running in sleep mode so that debugging can continue. I am able to do this in my code, but I do not want to accidentally leave it in my compiled code as this could increase power consumption.

How do I set DBGMCU using the debugger so that it is always set when I start to debug, but it is never part of my code?

1 ACCEPTED SOLUTION

Accepted Solutions

Yes, just it doesn't work quite right in CubeIDE.

Tried putting

set DBGMCU->CR = DBGMCU_CR_DBG_SLEEP

in the Run Commands field, and it worked only when Set program counter (hex) was active, otherwise there was an unknown symbol error.

But writing it without symbols, just as

set *(uint32_t *)0xE0042004 = 1

seems to be working.

View solution in original post

10 REPLIES 10
Pavel A.
Evangelist III

Debugger initialization scripts exist precisely for this.

-- pa

berendi
Principal

The debug launcher can be configured to start execution at a custom address, different from the reset vector, so it's possible to execute some function instead of (or before) the reset handler when debugging, but still jumping to the reset handler when the device is reset.

The custom startup address entry field can be found under Run / Debug Configurations / Startup / Set program counter at (hex). It requires a fixed address, so you have to arrange a fixed address for the custom startup function. You can put it right after the vector table, as it is at a fixed address, and its length is not likely to change.

Open the linker script (STM32L4*_FLASH.ld), find the .isr_vector section, duplicate and rename the copy both inside and outside. You should get something like this

.isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH
 
  .debug_in_sleep :
  {
    . = ALIGN(4);
    KEEP(*(.debug_in_sleep))
    . = ALIGN(4);
  } >FLASH
 
  /* The program code and other data into "FLASH" Rom type memory */
  .text :

Now write the function to set DBGMCU

void __attribute__((used, section(".debug_in_sleep"))) debug_in_sleep(void) {
	DBGMCU->CR |= DBGMCU_CR_DBG_SLEEP;
	asm volatile("ldr pc, [%[vectors],4]"
			:
			:[vectors]"r"(0x08000000)
			);
}

The used attribute tells the linker not to drop this function even if it isn't referenced anywhere in the code. The section attribute puts it in the linker section created above. The inline asm code jumps to the real reset handler. (Simply calling Reset_Handler() instead would work, but it makes the compiler save some registers on the stack before. Having a different value in the stack pointer while debugging would make debugging a stack corruption issue more challenging as it is already.)

Build the project, and open the .map file generated by the linker. (No .map file? Enable it in Project / Properties / C/C++ Build / Settings / Linker / General.) Find the address of the function in the .map file, and copy it into the Set program counter field in the debug launcher configuration dialog. Hitting the debug button now should start execution at debug_in_sleep().

TShus.1
Associate

Good afternoon! Happy New Year!

 My name is Tatyana.

 I want to install the X-CUBE-SBSFU software for MSPF407 remote secure flashing. To do this, registered on the site. Can I download this software today? Thanks.

Yes, just it doesn't work quite right in CubeIDE.

Tried putting

set DBGMCU->CR = DBGMCU_CR_DBG_SLEEP

in the Run Commands field, and it worked only when Set program counter (hex) was active, otherwise there was an unknown symbol error.

But writing it without symbols, just as

set *(uint32_t *)0xE0042004 = 1

seems to be working.

Thanks, that is an interesting approach that I have not considered before. I may not use it for this case, but I will certainly make use of this for some other purpose in the future. It gives some very powerful and flexible options.

Thanks, this is what I was looking for.

Where can I find more information on the initialisation scripts. I've used tcl on other projects (not ST) before, but could only find the command line "help" in STMCube. Is there any more formal documentation available somewhere?

This is not tcl, but the gdb command line interface.

https://sourceware.org/gdb/current/onlinedocs/gdb/

Uwe Bonnes
Principal III

As far as my understanding goes, DBGMCU can already be written under reset.So if you start from reset, write DBGMCU with the needed value. and only then release reset.

Piranha
Chief II

Just to inform - Segger J-Link sets DBGMCU bits automatically.