cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G4: Dual bank Page Erase blocking interrupts from bank 2 to 1 (but not 1 to 2)

pikachu
Associate

Hello,

We've developing an application where interruptions are a bit critical, we can't stop the IRQ for even short times, or the control gets crazy.

We update the device via MODBUS and we use the dual bank for the updates. Initially we had a problem with the ERASE of the bank during runtime, during the erase of the data section the flash the interruptions would stop for a while and we will lose control.

In order to fix that, we decided to move the data to the opposite bank of the active bank. And this actually worked a solution (BUT ONLY IN BANK 1), when we're in the first bank, everything works perfectly, but from Bank 2, the problem still persists and it's even worst now, because we're now erasing page by page instead of the full bank, so erase is slower.

Any idea on why this is only happening in Bank 2? Any way of fixing this for both banks without having to add an external flash?

We also tried to move interruptions, control, and a lot of functions to RAM, but we weren't able to fix the issue, this way.

This is the code we're using right now to erase before and update. The first lines are a workaround we've managed to implement to avoid problems with the control during an update. 

static bool bank_boot_erase(void)
{
    //Stop Converter and turn on battery relay to avoid problem with flash erase during updates
    request_update_stop();
    vTaskDelay(100);
    
    //ERASE CODE
    bool retval                  = false;
    FLASH_EraseInitTypeDef erase = { 0 };
    HAL_StatusTypeDef status     = HAL_OK;

    erase.Banks = active_bank == 1 ? FLASH_BANK_2 : FLASH_BANK_1;

    /* Erase the pages for the application only */
    erase.TypeErase = FLASH_TYPEERASE_PAGES;
    erase.NbPages =
        (FLASH_MAXIMUM_VALID_ADDRESS - BANK_BOOT_START_MAIN) / FLASH_PAGE_SIZE;
    erase.Page           = 0;
    pages_erased         = 0;
    pages_erase_expected = erase.NbPages;
    LOG_WARNING("App erase %lu %lu %lu", erase.Banks, erase.NbPages,
                erase.Page);

    // Call Erase
    operation_requested = FLASH_ERASE;
    HAL_FLASH_Unlock();
    status = HAL_FLASHEx_Erase_IT(&erase);

    if (status != HAL_OK) {
        retval = false;
        LOG_ERROR("%d", status);
        operation_requested = FLASH_NONE;
    } else {
        while (operation_requested == FLASH_ERASE) {
        }
        retval = true;
    }

    /* Erase Counter & Recovery Flags */
    FLASH_EraseInitTypeDef erase2 = { 0 };
    status                        = HAL_OK;

    erase2.Banks = active_bank == 1 ? FLASH_BANK_2 : FLASH_BANK_1;

    erase2.TypeErase = FLASH_TYPEERASE_PAGES;
    erase2.NbPages   = 1;
    erase2.Page      = (APP_COUNTER - BANK_BOOT_START_MAIN) / FLASH_PAGE_SIZE;
    pages_erased     = 0;
    pages_erase_expected = erase2.NbPages;
    LOG_WARNING("Recovery flags erase %lu %lu %lu", erase2.Banks,
                erase2.NbPages, erase2.Page);

    // Call Erase
    operation_requested = FLASH_ERASE;
    HAL_FLASH_Unlock();
    status = HAL_FLASHEx_Erase_IT(&erase2);

    if (status != HAL_OK) {
        retval = false;
        LOG_ERROR("%d", status);
        operation_requested = FLASH_NONE;
    } else {
        while (operation_requested == FLASH_ERASE) {
        }
        retval = true;
    }

    return retval;
}

This second code is used to erase a single page with some data in it, this happens every time we write this data via modbus.

static void erase_page(void)
{
    LOG_DEBUG("Erase page factory");
    uint8_t active_bank = READ_BIT(SYSCFG->MEMRMP, 0x1 <<  == 0 ? 2 : 1;
    FLASH_EraseInitTypeDef erase_init = { .TypeErase = FLASH_TYPEERASE_PAGES,
                                          .Banks     = active_bank,
                                          .Page      = 120,
                                          .NbPages   = 1 };

    uint32_t page_error = 0;
    HAL_FLASH_Unlock();
    HAL_StatusTypeDef retval = HAL_FLASHEx_Erase(&erase_init, &page_error);
    HAL_FLASH_Lock();
    if (retval != HAL_OK) {
        LOG_CRITICAL("Error erase %lu", page_error);
    }
}

I'm running out of ideas, any feedback will be appreciated.

0 REPLIES 0