cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_FLASH_Program crashing my MCPU - but not in debug mode

jgauthier
Senior

I'm not completely sure where to start. But, I have 20k of data and I want to write to to flash.

I'm using this function to do it (Start address is Bank2 of this processor 0x08080000)

page size is 256 bytes, for this MCPU. (StM32L471)

void Save_to_Flash(uint32_t *data) {
 
	uint32_t src_addr = (uint32_t) data;
	uint32_t Address;
	uint32_t start_time;
	HAL_StatusTypeDef HAL_STATUS;
	uint16_t bytes=0;
	uint16_t page_size = FLASH_ROW_SIZE * sizeof(uint64_t);
 
	if (!Erase_Flash()) {
		return;
	}
		
	HAL_FLASH_Unlock();
 
	Address = FLASH_USER_START_ADDR;
	
	while (Address <= FLASH_USER_START_ADDR + (DATA_VOL * sizeof(uint16_t))) {
		printf("Writing to address: %#x (%i)", Address, bytes);
		HAL_STATUS = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FAST, Address, (uint64_t) src_addr);
		if (HAL_STATUS == HAL_OK) {
			printf("Wrote to address: %#x (%i)", Address, bytes);
			Address = Address + page_size;
			src_addr = src_addr +  page_size;
			bytes+=page_size; 
		} else {
			printf("Flash write error at address %#x", Address);
		}
	}
	HAL_FLASH_Lock();
	printf("Flash (%i) written in %ims", bytes, HAL_GetTick()-start_time);
}

If I put a break point at the first printf() line, and then "continue" for each iteration the data is written perfectly, every time.

If I run the data outside of the debugger it crashes the MCPU every time.

Now, when I say "crash" I mean it. Not just the fault handler. I can no longer program the MCPU, and I have to power it off and on.

While analyzing this I've captured the following data.

First, I'm using Keil's ARM MDK, and the debug window shows this:

0693W00000LydNXQAZ.pngThe "Internal command error" occurs after the MCPU crashes.

My output shows writing is occurring, at east for the first page:

0693W00000LydP4QAJ.pngAnd when I look at the memory:

0693W00000LydPPQAZ.pngI can see it has stopped just several bytes into the page (the bytes written are correct)

I've been fighting with this for awhile and I don't know what else to try.

Even inserting a HAL_Delay(1000) between writes does not make a different.

(and I wouldn't want that solution)

4 REPLIES 4
Piranha
Chief II

RM0351 section 3.3.7, Fast programming:

If the flash is attempted to be written in Fast programming mode while a read operation is on going in the same bank, the programming is aborted without any system notification (no error flag is set).

...

The 32 double word must be written successively. The high voltage is kept on the flash for all the programming. Maximum time between two double words write requests is the time programming (around 20us). If a second double word arrives after this time programming, fast programming is interrupted and MISSERR is set.

So remove those printf() calls. And basically this means that the whole sequence for a single row must be done with interrupts disabled.

jgauthier
Senior

Nothing else was writing to the bank, that I am sure of.

However, the problem seems to eliminated.

I ported the project over to STM32CubeIDE and it worked perfectly every time. (with the printf()s)

I then swapped back to Keil, and changed the compiler from version 6 to version 5.

Version 5 complained about something - so I fix that. But then it was hard faulting somewhere else and I didn't want to diagnose it anymore.

So, I flipped back to 6 and built it again. After that I cannot make the problem happen any more.

Inexplicable

Piranha
Chief II

> Nothing else was writing to the bank, that I am sure of.

The cited note says reading from the same bank is enough. Basically that means one cannot do fast programming on the same bank the code is running from!

Turns out HAL actually disables and even correctly restores (Wow!) interrupts during the fast programming process.

https://github.com/STMicroelectronics/STM32CubeL4/blob/5223f4b55990987748dfc523ed751bc0c938650e/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c#L734

jgauthier
Senior

Oops. I meant nothing else is READING from the bank. The code is on bank1 and my data is being written to bank 2. Pretty cool that is disabled the interrupts too.