Skip to main content
Explorer II
January 23, 2025
Question

memory backup within strict time limit (10s max) on STM32L4R9

  • January 23, 2025
  • 4 replies
  • 1029 views

 

Hello everyone,

I’m currently working on developing a bootloader, and I’m trying to implement a memory backup function. My goal is to copy 158 pages of 4 KB from BANK1 to BANK2.

I’ve written software that uses the standard copy function with FLASH_TYPEPROGRAM_DOUBLEWORD (64 bits at a time). However, this process takes more than 10 seconds because after each write, I check the data integrity: I read the data from BANK1, write it to BANK2, then read it again from BANK2 and compare to verify the data.

The main issue I’m facing is that after writing the 158 pages, I need to send a response via CAN. This results in a timeout error on the diagnostic application because the 10-second limit is exceeded.

I’m looking for a solution to perform the memory backup operation faster, ideally in under 8 seconds, while still ensuring data integrity.

I’ve tried using DMA, and although it works, I believe it’s not the best solution for my scenario due to some limitations.

If you have any ideas or suggestions to optimize this operation, I would greatly appreciate your help!

Thank you in advance for your feedback.

    This topic has been closed for replies.

    4 replies

    Super User
    January 23, 2025

    @ZAYN wrote:

    I check the data integrity: I read the data from BANK1, write it to BANK2, then read it again from BANK2 and compare to verify the data..


    Do you really need to do a byte-by-byte compare?

    Could you not use use a CRC or similar?

     


    @ZAYN wrote:

    I need to send a response via CAN. This results in a timeout error on the diagnostic application because the 10-second limit is exceeded..


    What sets this 10-second value?

    Can you not send a "working" response (or responses) to keep the CAN alive?

     


    @ZAYN wrote:

    I’ve tried using DMA, and although it works, I believe it’s not the best solution for my scenario due to some limitations.


    What limitations, exactly?

    ZAYNAuthor
    Explorer II
    January 23, 2025

    Hello Andrew,

    Thank you for your feedback.

    Do you really need to do a byte-by-byte compare?

    -> No, there's no need to compare byte by byte. The function that takes a lot of time is the one used to copy the entire binary application to the backup section.

    Could you not use a CRC or similar?

    -> Yes, I am using the hardware CRC component.

    What sets this 10-second value?

    -> This value is defined in the diagnostic application on the PC. The diagnostic application expects a specific response indicating that the backup has been completed before it starts sending a new binary.

    I know that in other types of microcontrollers, it's possible to map the write functions to Flash into faster RAM to speed up the process, but I’m not sure if this is possible on STM32, for example, using PSPR memory on TC3 Aurix from Infineon.

    Thank you for your help.

    Super User
    January 24, 2025

    @ZAYN wrote:

    What sets this 10-second value?

    -> This value is defined in the diagnostic application on the PC. .


    Are you able to modify that PC app so that it can accept a "working" response to reset its timeout?

     

    Please see How to insert source code.

     

    ZAYNAuthor
    Explorer II
    January 24, 2025

    Hello Andrew,

    To use the fast programming mode, I believe it is mandatory to perform a mass erase of the entire flash memory, not just a defined number of pages.
    Could I, for example, perform an erase of only Bank 2 and then use the fast mode?

    Alternatively, I could update the diagnostic application on the PC to adjust the timeout for the process.

    Thank you for your feedback.

    ZAYNAuthor
    Explorer II
    January 23, 2025

    I’ve tried using DMA, and while it seems to work, I believe it’s not the best solution for my scenario due to certain limitations.

    What limitations, exactly?

    Sorry, what I meant to say is that I tried using DMA for the write operation, but it doesn't work. I’m not sure why—it doesn't give any errors, but when I check the content of the backup memory, it’s empty. I’m not sure what’s going wrong.

     

    that the function : 

    static bool_t BL_Copy_Memory_DMA(uint32_t FromStartAddr, uint32_t FromEndAddr,

    uint32_t ToStartAddr, uint32_t ToEndAddr) {

    uint32_t currentAddrFrom = FromStartAddr;

    uint32_t currentAddrTo = ToStartAddr;

    HAL_StatusTypeDef status = HAL_OK;

    uint32_t err = 0;

    bool_t bLocRetFunction = TRUE;

    bool_t CopyStatus = TRUE;

     

    __HAL_RCC_DMA1_CLK_ENABLE();

     

    /* Erase destination memory sectors */

    CopyStatus = BL_Erase_Memory(ToStartAddr, ToEndAddr);

     

    if (CopyStatus != FALSE) {

     

    /* Allocate RAM buffer */

    uint32_t buffer[FLASH_PAGE_SIZE / sizeof(uint32_t)]; // Buffer to hold data in RAM

     

    /* Configure DMA for memory transfer */

    DMA_HandleTypeDef hdma = {0};

    hdma.Instance = DMA1_Channel1;

    hdma.Init.Direction = DMA_MEMORY_TO_MEMORY; // Memory-to-memory

    hdma.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;

    hdma.Init.MemInc = DMA_MINC_ENABLE;

    hdma.Init.Mode = DMA_NORMAL;

    hdma.Init.PeriphInc = DMA_PINC_DISABLE; // Peripherals are not involved, so no increment

    hdma.Init.Priority = DMA_PRIORITY_HIGH; // Set priority level

     

    if (HAL_DMA_Init(&hdma) != HAL_OK) {

    err = 5;

    bLocRetFunction = FALSE;

    }

     

    /* Disable interrupts during transfer */

    //__disable_irq();

    if( HAL_FLASH_Unlock() != HAL_OK)

    {

    bLocRetFunction = FALSE;

    }

     

    while (currentAddrFrom < FromEndAddr) {

    uint32_t transferSize = (FromEndAddr - currentAddrFrom > FLASH_PAGE_SIZE)

    ? FLASH_PAGE_SIZE

    : (FromEndAddr - currentAddrFrom);

     

    /* Step 1: Copy data from Flash to RAM */

    memcpy(buffer, (void*)currentAddrFrom, transferSize); // Read Flash to RAM buffer

     

    /* Step 2: Start DMA transfer to Flash memory */

    status = HAL_DMA_Start(&hdma, (uint32_t)buffer, currentAddrTo, (transferSize / 4));

    if (status != HAL_OK) {

    err = 1;

    return FALSE;

    }

     

    /* Wait for DMA transfer complete */

    status = HAL_DMA_PollForTransfer(&hdma, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);

    if (status != HAL_OK) {

    err = 2;

    return FALSE;

    }

     

    currentAddrFrom += transferSize;

    currentAddrTo += transferSize;

    }

     

    if( HAL_FLASH_Lock() != HAL_OK)

    {

    bLocRetFunction = FALSE;

    }

    // __enable_irq();

    }else

    {

    bLocRetFunction = FALSE;

    }

    return bLocRetFunction;

    }

     

    Graduate II
    January 23, 2025