3

I am using a self-built embedded IDE with Eclipse and GDB - pretty much what this website describes: https://gnu-mcu-eclipse.github.io/

When I use OpenOCD or any other Debug Config (like SEGGER JLink) to flash my STM32F407 hardware, it breaks at the first line of my main.c. Nothing unusual.

// ----- main() ---------------------------------------------------------------
int main(void)
{

    //Initialization, if unsuccessful -> quit
    if (!INIT_bInit())
        return 0;

    //infinite Loop
    while (0x1337)
    {
        //Nothing
    }

    //Must not end here
    return 0;
}

//main() 

This might be due to the behaviour setup in the Eclipse OpenOCD debug console.

However, I'd like to have an automatic breakpoint mecahnism as well which halts the program in case there is a

  • hard fault or a
  • hardware reset

As my software generally bases on automatic tasks with void function pointers, I'd like to know when there is a hardfault occurring due to a problem with the function to be called,

But as of now, the only time I notice a HardFault is when I pause my program after a while and check if it ends up in my (custom) Default_FaultHandler (which implements the HardFault_Handler and others).

void Default_FaultHandler(void)
{
  while(0xDEAD){} 
}

Same thing with hardware reset. No indication, not even an automated (re-)break at main.c.

I know from eclipse-based IDEs like NXP's MCUXpresso or Atollic Studio that it is possible to automatically break the program when any fault handler or a hardware reset is called.

Any ideas on how to automate the debugging behaviour with my own-built OpenOCD/Eclipse solution?

Your help is warmly welcome

Cheers

-Henni

  • 1
    regarding: `if (!INIT_bInit()) return 0;` in general, a return of 0 indicates success. Typically a return of 1 (or -1) indicates a failure. In the posted code, both a success exit and a failure exit are returning 0 Suggest replacing the first `return` statement with: `exit( EXIT_FAILURE );` Note `exit()` and `EXIT_FAILURE` are exposed via the statement: `#include ` – user3629249 Dec 29 '19 at 12:59

3 Answers3

4

To analyze your hardfaults you can write a more sophisticated handler, cf https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html :

The implementation of prvGetRegistersFromStack() is shown below. prvGetRegistersFromStack() copies the register values from the stack into the C variables, then sits in a loop. The variables are named to indicate the register value that they hold. Other registers will not have changed since the fault occurred, and can be viewed directly in the debugger’s CPU register window.

Also cf How do I debug unexpected resets in a STM32 device?

You can not detect hardware resets because they erase entire memory. When booting up again you can find what caused the hardware reset, this is in STM32 how to get last reset status. Possibly store the result on some permanent memory that is not erased during next hardware reset

ralf htp
  • 9,149
  • 4
  • 22
  • 34
  • Ralf, dankeschoen, however it is more about automatically breaking when one of these events occurs, not so much about analyzing what goes wrong in the exact moment of the failure/event. The question should therefore direct more at the issue of: how do I tell GDB/Eclipse by ether code or debug options/configuration that they shall break Eclipse and halt the program!? – hendrikschnack Dec 28 '19 at 12:36
  • 1
    You mean hardware breakpoints ? https://electronics.stackexchange.com/questions/28593/hardware-breakpoints-on-the-stm32 , https://processors.wiki.ti.com/index.php/How_Do_Breakpoints_Work Grüße aus Berlin – ralf htp Dec 28 '19 at 12:42
  • Oh that sounds promising. I’ll check it later. Danke – hendrikschnack Dec 28 '19 at 12:55
1

If you want to place breakpoint in the suspiciuus function or handler just use

__BKPT();

or if you do not use ARM CMSIS just

#define __BKPT(value)                       __ASM volatile ("bkpt "#value)

Example:

void Default_FaultHandler(void)
{
  __BKPT();
  while();
}

When this intrinsic is hit, your debugger will take the controll :)

0___________
  • 60,014
  • 4
  • 34
  • 74
0

I figured out that I haven't offically resolved my problem due to NYE holidays :)

Thanks to ralf htp I was able to solve my initial problem of pre-loaded breakpoints resulting from GDB console options.

To sum the whole thing up: The last link posted solves the OpenOCD version. https://electronics.stackexchange.com/questions/28593/hardware-breakpoints-on-the-stm32

For SEGGER j-link it is

break main
break Default_FaultHandler

Both can be added for GDB in Eclipse Debug Configuration (in Startup tab) as follows

GDB startup settings

Works like a charm...

Thanks!

  • It is a very good method because you waste hardware breakpoints and you have a very limited number of them. Just place `__BKPT()` intrinsic – 0___________ Jan 03 '20 at 22:06
  • `__BKPT()` does not work with J-Link GDB and is limited to a number of 255, too. It may be suitable in some cases for OpenOCD where you have less HW breakpoints. – hendrikschnack Jan 04 '20 at 06:51
  • `__BKPT() does not work with J-Link GDB.` It is not the truth. I use J-Link for years. You just do something wrong. Type of gdbserver does not matter in this case. Number of bkpt instructions in the code is not limited (do not be fooled by the optional parameter - it is not needed, and breakpoints patameters do not have do be distinct). JLink "unlimited" bereakpoints are just bkpt instruction placed in the code. Hardware breakpoint are limited by Cortex core not debugging software. Generally - nothing you wrote is correct. – 0___________ Jan 04 '20 at 10:50
  • To be honest, I do not know exactly. I remember trying it in the past. It did not work out and I found this forum post which resulted in me not further trying: https://forum.segger.com/index.php/Thread/2135-SOLVED-Unable-to-continue-past-bkpt-instruction/. If or if not SEGGER has implemented the BKPT() compatibility after all, is beyond my knowledge – hendrikschnack Jan 04 '20 at 16:13