Skip to main content
Graduate II
October 7, 2021
Solved

Erasing flash during RTOS task execution on STM32F4

  • October 7, 2021
  • 12 replies
  • 8148 views

Hi ..

I am using this function to erase some sectors on the flash

bool FLASH_EraseSectors(uint32_t starting_sector , uint8_t number_of_sectors)
{
	FLASH_EraseInitTypeDef erase_init;
	uint32_t page_error;
 
 /* Erase the user Flash area */
	erase_init.Banks = FLASH_BANK_1;
	erase_init.TypeErase 	= FLASH_TYPEERASE_SECTORS;
	erase_init.NbSectors 	= number_of_sectors;
	erase_init.Sector 	= starting_sector;
	erase_init.VoltageRange = FLASH_VOLTAGE_RANGE_3;
 
	/* Unlock the Flash to enable the flash control register access *************/
	FLASH_Unlock();
 
	if (HAL_FLASHEx_Erase(&erase_init, &page_error) != HAL_OK)
	{
		FLASH_Lock();
		return false;
	}
	if (HAL_FLASHEx_Erase(&erase_init, &page_error) == HAL_OK)
	{
		FLASH_Lock();
		return true;
	}
 
}

I would like to erase some sectors without breaking the 2 tasks running...

The point is that it seems to destroy the tasks...

Is there a safe way to delete the sectors in flash during a task execution in FREERTOS ?

Thanks a lot

    This topic has been closed for replies.
    Best answer by Manny

    @SGasp.1​ , flashing 8 bytes will not take much time, the time taker is the sector erase process that need to be done before writing any byte in that sector.

    For your uart data, if you disable interrupts, the uart receive interrupts will also disable and thus you will loss data as uart can only hold a single byte at a time, case is different if you are using DMA(I don't have experience with DMA). You can implement a strategy to ensure that no data is loss on the communication side. For example you wait for an acknowledgment for the mcu before sending the next byte of data to be programed.

    See the DFU(Device firmware update) protocol application note to use as a reference to design your own bootloader protocol.

    link:

    https://www.st.com/resource/en/application_note/cd00264342-usart-protocol-used-in-the-stm32-bootloader-stmicroelectronics.pdf

    12 replies

    SGasp.1Author
    Graduate II
    October 21, 2021

    Thanks AHarm.. your help was very useful... Not i am able to flash the bytes coming from the uart..

    it is a hex file... you can see it in the attachments..

    Just a question ..

    Should I have to write the bytes in the flash starting from line 2 of the file ?

    Can I skip it the first line ?

    Can I also skip line 1726?

    Thanks a lot again for your support

    Visitor II
    October 28, 2021

    0693W00000FDzveQAD.jpgI am not sure, but I can share some info about the hex file, hex file a text(ASCII) file that have information about binary data. It can and is used for programming(your mcu e.g). You can should take a look at the generated .bin file, in my opinion it is more clear. You just need to know where the user code memory is, in the mcu.

    As .bin file is a binary file, simple text editor would not be a good option for viewing, use a hex viewer softer(I use FlexHex).

    See the attached file, it is a bliki code for the stm32f103(blue pill), note that the file start from address 0x00000000, this data is to be programmed at the address 0x08000000 in the blue pill. Also see the attached stm32cubeProgrammer view of the code when inside the mcu. The stm32cubeprorammer is shows the address little differently. The STVP would have made it clear but currently I don't have a ST-Link at the movement.

    0693W00000FDzviQAD.jpg 

    Visitor II
    October 21, 2021

    Hi @SGasp.1​ ,

    your functions look fine just fine, the thing is that every sector erase is atomic and cannot be interrupted and so it's the write.

    To not block the write operation and let te UART communication work every time a packet is received, you can add a semaphore or a simple flag.

    here some pseudocodes.

    Uart IT Callback:

    StopWriteFlag = TRUE;
    MessageReceived =TRUE;

    UART task:

    if(MessageReceived == TRUE)
    {
     ParseReceivedMessage();
     
     StopWriteFlag = FALSE;
     MessageReceived =FALSE;
    }

    write task:

    if (StopWriteFlag != TRUE)
    {
     __disable_irq();
     while (FlashWriteData(address_to_write, &HEX_array[0], bytes_to_flash/2) == -1)
     {
     }
     __enable_irq();
    }