Skip to main content
Radoslav Mar
Associate II
June 18, 2018
Solved

Can not erase flash memory page using HAL Drivers

  • June 18, 2018
  • 10 replies
  • 2701 views
Posted on June 18, 2018 at 12:23

Hello All.

MCU: STM32F031G6U6

IDE: System Workbench

API: STM32F0 HAL and low-layer drivers

I am trying to erase page in the flash memory at address: 0x8002000.

Here is the code:

https://community.st.com/tags♯/?tags=code

‌

FLASH_EraseInitTypeDef EraseInitStruct;

uint32_t SECTORError = 0;;

bool result = true;

/* Unlock the Flash to enable the flash control register access *************/

HAL_FLASH_Unlock();

//addr = 0x08007800 just for testing

/* Erase the user Flash area

(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/

/* Fill EraseInit structure*/

EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;

EraseInitStruct.PageAddress = Address; // start address

EraseInitStruct.NbPages = 1;

if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)

{

/*

Error occurred while sector erase.

User can add here some code to deal with this error.

SECTORError will contain the faulty sector and then to know the code error on this sector,

user can call function 'HAL_FLASH_GetError()'

*/

/* Infinite loop */

while (1)

{

;// error, BALAGAN!!!

}

}

The program crashes at this line 

if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)

Nothing after this function call is executed.

Any Ideas?

#code #code::blocks
    This topic has been closed for replies.
    Best answer by Tesla DeLorean
    Posted on June 18, 2018 at 15:12

    https://community.st.com/0D50X00009XkWCsSAN

    Are you erasing memory your code is residing in currently? Do the routines need to be run from RAM?

    10 replies

    Tesla DeLorean
    Tesla DeLoreanBest answer
    Guru
    June 18, 2018
    Posted on June 18, 2018 at 15:12

    https://community.st.com/0D50X00009XkWCsSAN

    Are you erasing memory your code is residing in currently? Do the routines need to be run from RAM?

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    turboscrew
    Senior III
    June 18, 2018
    Posted on June 18, 2018 at 20:17

    No. It says in the manual that pipelines are stalled during the flashing operations (erase, write).

    I'm not sure, but I think it means the flash buffers, and when the instruction pipeline is exhausted, and nothing is coming in from the flash, also the instruction pipeline gets stalled.

    I guess I'll find out in the near future. (I need to implement a flasher inside a SW). :D

    Note that erasing a sector can take seconds.

    From RM0091:

    On the contrary, during a program/erase operation to the Flash memory, any attempt to read

    the Flash memory will stall the bus. The read

    operation will proceed

    correctly once the

    program/erase operation has completed. This means that code or data fetches cannot be

    made while a program/erase operation is ongoing.

    turboscrew
    Senior III
    June 18, 2018
    Posted on June 18, 2018 at 20:29

    (It seems to be impossible to continue writing afret quote as the last item.)

    So you should be able to erase the program you're running. :D

    areify
    Associate III
    May 6, 2020

    Sorry for refloating but I have the same issue.

    While debugging this problem I saw that, inside this function (HAL_FLASHEx_Erase) is the following block:

    /* Page Erase requested on address located on bank1 */
     /* Wait for last operation to be completed */
     if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
     {
     /*Initialization of PageError variable*/
     *PageError = 0xFFFFFFFFU;
     
     /* Erase page by page to be done*/
     for(address = pEraseInit->PageAddress;
     address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
     address += FLASH_PAGE_SIZE)
     {
     FLASH_PageErase(address);
     
     /* Wait for last operation to be completed */
     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
     
     /* If the erase operation is completed, disable the PER Bit */
     CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
     
     if (status != HAL_OK)
     {
     /* In case of error, stop erase procedure and return the faulty address */
     *PageError = address;
     break;
     }
     }
     }

    Here, all the process of erasing starts only if FLASH_WaitForLastOperation (...) returns HAL_OK (which is defined as zero). But if we dive into this function we can see in the comments:

     * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
     * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
     */

    An overview of this function prove that this is actually true. And those enum values are defined as:

    typedef enum
    { 
     FLASH_BUSY = 1,
     FLASH_ERROR_PG,
     FLASH_ERROR_WRP,
     FLASH_COMPLETE,
     FLASH_TIMEOUT
    }FLASH_Status;

    As you can see, any of that values is equal to zero, so... how is expected to work this function? Is this a bug or am I misusing this library?

    Thank you and excuse my english.