cancel
Showing results for 
Search instead for 
Did you mean: 

HardFault_Handler

Hi, I have a problem with HardFault_Handler.

Sometimes, when I'm writing into the flash it happens.

After many days on searching still I don't understand why it happens and what it means.

Has someone got a suggestiom for me?

15 REPLIES 15

Does your HardFault_Handler output any useful diagnostics? With actual data you might be able to make some specific determination.

Unaligned writes

Rewriting

Writing out of scope

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
AvaTar
Lead

Or a stack overflow, perhaps interrupt-related.

> Sometimes, when I'm writing into the flash it happens.

For investigating/testing, you could try to write to the Flash more often, to provoke the issue.

You can cool down (faster Flash writes) or heat up the board (slower Flash writes) - Flash write is temperature-sensitive.

Either investigate the SCB registers in the debugger once you hit the hardfault handler, or add instrumentation/diagnostics code as Clive2.0 suggested.

Really I don't know how to resolve. Going slowly the problem doesn't happen.

On reading, fastly or slowly everything works well.

MFend
Associate III

I'm having the same problem.

I'm trying to write data to an area of the internal Flash that is not being used by the running application.

I'm using STM32L451VE.

There are no alignment or paging problems and the flash was erase previous to the write.

I disabled all interrupts using __disable_irq();

If I step with the debugger, I can program many 8 byte DWORDS to the flash without any errors.

But if I try to let the code run by itself, I get stuck immediately in HardFault_Handler.

I'm using the Atollic TS. I will try to implement the Handler mentioned in a previous post - but i'm not sure about the assembly code in the *.s file.

Any other ideas would be appreciated.

Thanks,

Mechi

> I'm having the same problem.

Meaning a hardfault ?

Flash writes use to cause execution stalls and a disruption of your timing, but no hardfault per se.

Clive2.0 mentioned usual reasons for hardfaults.

Without details about the code, it is almost impossible to give specific recommendations.

> I'm using the Atollic TS. I will try to implement the Handler mentioned in a previous post - but i'm not sure about the assembly code in the *.s file.

You can try a different approach. Let the code run, with a breakpoint in the hardfault handler. Then investigate the SCB register values for the fault reasons. Better try more than once.

Another approach is to add telemetry code (GPIO toggle in the simplest case), and drill down to the offending function/code where the fault occurs.

MFend
Associate III

HardFault_Handler:

TST  LR, #4

ITE  EQ

MRSEQ R0, MSP

MRSNE R0, PSP

MOV  R1, LR

bl   HardFault_Handler_C

How do I "convert" this assembly code (from the code example mentioned in http://www.keil.com/appnotes/files/apnt209.pdf) to code for the Atollic TS?

Thanks,

Mechi

Well here's the code:

	for (cntr = 0; cntr*8 < len; cntr++)
	{
	   dataf = *(p64 + cntr);
 
	   printf("CopyFWtoFlash b4: %lu bytes addr 0x%0X\n", (cntr*8), (unsigned int)addressToBurn);
 
	   ret = Bootloader_FlashNext(STORE_AREA, addressToBurn, dataf);
 
	   if(ret == HAL_OK)
	   {
		   //cntr++;
		   addressToBurn += 8; /* Increment Flash destination address */
	   }
	   else
	   {
		   break;
	   }
	}// while (cntr < (len / 8));

and the function called is:

uint8_t Bootloader_FlashNext(uint8_t area, uint32_t flash_ptr, uint64_t dataf)
{
	uint8_t ret = BL_WRITE_ERROR;
	uint32_t *tmp32 = (uint32_t *)&dataf;
 
	switch (area)
	{
	case APP_AREA:
		if((flash_ptr < APP_ADDRESS) || (flash_ptr > END_APP_FW_ADDRESS))
		{
			HAL_FLASH_Lock();
			return BL_WRITE_ERROR;
		}
		break;
 
	case STORE_AREA:
		if((flash_ptr < STORE_ADDRESS) || (flash_ptr > END_STORE_FW_ADDRESS))
		{
			HAL_FLASH_Lock();
			return BL_WRITE_ERROR;
		}
		break;
 
	case APP_INFO_AREA:
		if((flash_ptr < APP_INFO_PAGE) || (flash_ptr >= APP_CRC_ADDRESS))
		{
			HAL_FLASH_Lock();
			return BL_WRITE_ERROR;
		}
		break;
 
	case STORE_INFO_AREA:
		if((flash_ptr < STORE_INFO_PAGE) || (flash_ptr >= STORE_CRC_ADDRESS))
		{
			HAL_FLASH_Lock();
			return BL_WRITE_ERROR;
		}
		break;
 
	default:
		HAL_FLASH_Lock();
		return BL_WRITE_ERROR;
	}
 
	RefreshExtWD();
    if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, flash_ptr, dataf) == HAL_OK)
    {
    	RefreshExtWD();
        /* Check the written value */
        if(*(uint32_t *)flash_ptr != tmp32[0] || *(uint32_t *)(flash_ptr+4) != tmp32[1])
        {
            /* Flash content doesn't match source content */
            HAL_FLASH_Lock();
            ret = BL_WRITE_ERROR;
        }
        else
        {
			ret = BL_OK;
        }
    }
    else
    {
        /* Error occurred while writing data into Flash */
        HAL_FLASH_Lock();
        ret = BL_WRITE_ERROR;
    }
    
    return ret;
}

I'm using the HAL flash function - which works fine in the bootloader, but when called from the application, while all peripherals and clocks are initialized, it crashes.

In the bootloader, flash memory is copied from one section of the flash to another - and this works well.

In the application, swaths of code (6144 bytes - 3 pages worth) are sent and saved after 0x8044000.

I'd appreciate any ideas.

I do not use HAL/Cube, because of it's insolent resource grab (like SysTick), and it's permissive use of suspect coding techniques like busy-waits.

And AFAIK, it uses to enable HW watchdogs without your consent. Watchdog & Flash programming do not get along so well.

MFend
Associate III

Here are the SCB registers and the output of the Handler (not much, because i don't have the assembler code)