cancel
Showing results for 
Search instead for 
Did you mean: 

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

ZAYN
Associate II

 

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.

4 REPLIES 4

@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?

ZAYN
Associate II

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.

ZAYN
Associate II

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;

}

 

So 632KB

Can you use the FAST + FAST_LAST methods, to fast program pages at a time?

https://github.com/STMicroelectronics/STM32CubeL4/blob/f01b36631d4849e85cff4b99ee7ee0bd01c3f3f2/Projects/NUCLEO-L496ZG/Examples/FLASH/FLASH_FastProgram/Src/main.c#L133

https://www.st.com/resource/en/datasheet/stm32l4r9ag.pdf#page=202

Otherwise you'll need to use faster FLASH memories.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..