cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleo-L433RC-P: Debug fails on first attempt but works on second

freeflyer
Senior II

I am developing software on the Nucleo-L433RC-P board but have a strange situation when debugging.

The first time I debug, the software does not run and I get the following error...

 

Break at address "0x1fff2ce8" with no debug information available, or outside of program code.

Break at address "0x1fff2cd6" with no debug information available, or outside of program code.

 

As shown in the screenshot below...

Monosnap Voice - Source not found. - STM32CubeIDE 2025-07-16 19-34-31.png

However, the second time I debug it works correctly.

Why does it not work correctly on the first debug, but then works correctly on the second debug ?

I have tried two different boards (one of which is brand new and never been used) but the behaviour is the same, so it must be a software issue.

15 REPLIES 15

I don't see any effect in your code lines 11-15 and would delete it. Would also avoid calling malloc/free for that at all. Can only imagine that you observe a stack overflow by a spurious interrupt or other kind of heap corruption.

Make sure that _Min_Heap_Size and _Min_Stack_Size have realistic values (in .ld file or STM32CubeMX) especially because the issue started to show up only when your code was growing. 

Maybe double-check stack usage by stack painting Measuring Stack Usage the Hard Way | Interrupt 

hth

KnarfB

 

It fails on line 168 of the 'w25qxx_init' function and then the debugger crashes.  When I pause the debugger it appears to go outside the flash area with the error "Break at address "0x1fff2d24" with no debug information available, or outside of program code."

 

freeflyer_0-1752934684286.png

 

freeflyer_1-1752934742329.png

 

 

I did not write the w25qxx driver, I got the driver from here...

https://github.com/mengguang/w25qxx

I do not understand what this line is doing anyway....

    char *version_buffer = malloc(strlen(W25QXX_VERSION) + 1);

 

Its strange how it also happens alternately

First debug flash and it fails, second debug flash and it works and so on....

freeflyer
Senior II

Thanks all, how do I enable Full Chip Erase and ensure my debug configuration includes program loading before starting execution ?

I cant see any options for those in the debugger settings ?

 

freeflyer_0-1752935365969.png

freeflyer_1-1752935387443.png

freeflyer_2-1752935441767.png

 

allocate heap memory to hold a copy of W25QXX_VERSION and freeing that memory immediately afterwards. Don't see that in the github you mentioned. Probably only relics from some deleted debug output ...

hth

KnarfB

freeflyer
Senior II

Thanks michaeljyti, the point at which the program fails when stepping though the code was a red herring.

As my code developed. the program failed at a different points in the program.

The stack size is the default setting, I have not changed this...

_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */

freeflyer_0-1756384017685.png

I have never used stack painting so will need to look further into this.

If the stack size was incorrect, then wouldn't it fail every time ?

The flashing fails the first time but works the next time, it alternatively fails and works.

So why would an incorrect stack size cause this ?

 

 

freeflyer
Senior II

This is driving me crazy, espeically as I am trying to get a custom bootloader to work too.

I checked the stack and its well within the limits....

freeflyer_0-1757262349718.png

Below is the code snipet to check the stack...

static uint32_t stack_used;
static uint32_t stack_free;
static uint32_t stack_used_max;
static uint32_t stack_free_max;

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  Stack_Paint();
...
...
...
}


void Stack_Paint(void) {
    uint32_t *p = &_stack_end;
    while (p < &_estack) {
        *p++ = 0xA5A5A5A5;  // fill with pattern
    }
}

uint32_t Stack_GetUsage(void) {
    extern uint32_t _stack_end;
    extern uint32_t _estack;
    uint32_t *p = &_stack_end;
    while (p < &_estack && *p == 0xA5A5A5A5) {
        p++;
    }
    stack_used = (&_estack - p) * sizeof(uint32_t);  // bytes used
    if (stack_used > stack_used_max)
    {
    	stack_used_max = stack_used;
    }
}

uint32_t Stack_GetFree(void) {
    extern uint32_t _stack_end;
    extern uint32_t _estack;
    uint32_t *p = &_stack_end;
    while (p < &_estack && *p == 0xA5A5A5A5) {
        p++;
    }
    stack_free = (p - &_stack_end) * sizeof(uint32_t);  // free space in bytes
    if (stack_free > stack_free_max)
    {
    	stack_free_max = stack_used;
    }
}

 

Stack_GetUsage and Stack_GetFree is called in a 100ms task and the program is left to run for several minutes.

I've written a custom bootloader and a simple application that flashes an LED, I can successfully flash the application using the bootloader.

 

However, when I try to flash the application for this project, although it flashes successfully it does not run the application.  I don't know whether the application has the same issue, where it does not work the first time its flashed but does work the second time its flash.  However, I cant test this because the application is used to call the bootloader, so when it does not work the flash then its not possible to go back to the bootloader.