Influence Flash Erase on System Performance (SysTick)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
I implemented an CANopen Bootloader running out of PSRAM on a XMC4500 (@60MHz). When I send the CANopen command to erase the application flash (0x0C010000..0x0C07FFFF, 484kB), The 500ms heartbeat messages are not send for about 10s (time to erase flash). The heartbeat messages are triggered by the 250us SysTick Interrupt which handles the whole Task system...
The whole Projekt is a bare metal implementation without a operating system, the Tasks are handled by the SW-Interrupts of the NVIC. When the erase command is received a interrupt with Priority 20 is triggered and the ISR handles the flash erase. The CANopen Task is running with a priority of 10 (higher -> this interrupt will interrupt the flash erase task) which is started by the SysTick (Prio 0, highest).
If I replace the code to erase the flash by a 10s long while-loop within the Flash ISR everything works fine. The code to erase the flash does not disable Interrupts or something similar. It writes only the flash command sequences to the When I toggle a pin within the SysTick task I can see on the Oszilloscope that the toggling stops for about 10s (sometimes one SysTick Interrupt is handled).

Is the CPU/SysTick influenced by the flash erase operation?

Thanks for your help!

Best regards Mario
0 Likes
7 Replies
Not applicable
Hi Mario,

When flash erase in progress, the flash is busy and unable to access.
During this time, if the CPU try to access the flash, it will stalled until the flash is idle again.
So, if your Systick ISR is place on the flash, this means the CPU is unable to service the ISR when the flash erase is in progress.
0 Likes
Not applicable
Hi Jackson,

thanks for your answer. The code runs completely from PSRAM, the exception vector table and all the ISRs are located within PSRAM. The only code which is located to flash is the Reset vector and the startup code to copy the code into the PSRAM.
What happens when the flash is busy and a read access occurs? I thought there is a trap (HardFault, BusFault...) generated... What do you mean with stalled? The CPU (and all timers, Peripherals...) are freezed until the Flash is accessible again?
If there is still a unwanted access to the flash within my code, is there a possibility to locate that code (Memory Access breakpoint with ISR...)?
Is there any other possibility for that behavior? The flash erase has definitly no influence to the rest of the system (data bus, cpu, timers...)?

Thanks for your help!

Best regards

Mario
0 Likes
Not applicable
Hi Jackson,

I found the cause for the Bus Error: The virtual function pointer Tables was still mapped to the flash. I copied the complete section to the RAM, now the Bootloader runs as expected.
Thanks a lot for your help!

Best regards Mario
0 Likes
User8620
Level 2
Level 2
I am having the same problem.
When erasing the flash I must be able to trigger an external watchdog via the SysTick_Handler.
My Systick_Handler and alle the called functions insinde the handler are mapped to SRAM by this command: __attribute__( ( section(".data") ) )

In the main function I copy the vectortable into RAM and set the address of the Systick_Handler:

for (uint32_t i = 0; i < VECTORTABLE_SIZE; i++)
{
vectorTable_RAM = __Vectors; /* copy vector table to RAM */
}
/* replace SysTick Handler */
vectorTable_RAM[SysTick_IRQn + 16] = (uint32_t) SysTick_Handler;

/* relocate vector table */
__disable_irq();
SCB->VTOR = (uint32_t) &vectorTable_RAM;
PPB->VTOR = (uint32_t) &vectorTable_RAM;
__DSB();
__enable_irq();


The Systick_Handler is triggered, but not when the flash is being erased. What did I miss?
0 Likes
lock attach
Attachments are accessible only for community members.
jferreira
Employee
Employee
10 sign-ins 5 sign-ins First like received
Hi,

See the following program

#include "xmc_gpio.h"
#include "xmc_flash.h"

// Example show how to keep running interrupts while flash is being erased
// LED1 will flash with a period of 200ms and the LED2 will indicate the duration of the flash erase
// Changes wrt to default settings:
// 1. Linker file
// The xmc4_flash.o contents have been moved to SRAM
// 2. Compiler options, use -mlong-jumps to avoid usage of veneers in flash to jump to SRAM function


#define TICKS_PER_SECOND 1000
#define LED1 P5_9
#define LED2 P5_8

extern unsigned char __Vectors;

__attribute__((aligned(1024))) volatile uint32_t vector_table[256];

__attribute__((section(".ram_code"))) void SysTick_Handler(void)
{
static uint32_t ticks = 0;

ticks++;
if (ticks == 100)
{
ticks = 0;
XMC_GPIO_ToggleOutput(LED1);
}
}

int main(void)
{
/* relocate vector table */
__disable_irq();

for (int i = 0; i < 256; ++i)
{
vector_table = ((uint32_t *)&__Vectors);
}

SCB->VTOR = (uint32_t)(&vector_table[0]);
__DSB();
__enable_irq();

XMC_GPIO_SetMode(LED1, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);
XMC_GPIO_SetMode(LED2, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);

SysTick_Config(SystemCoreClock / TICKS_PER_SECOND);

XMC_GPIO_SetOutputHigh(LED2);
XMC_FLASH_ErasePhysicalSector(XMC_FLASH_SECTOR_15);
XMC_GPIO_SetOutputLow(LED2);

/* Placeholder for user application code. The while loop below can be replaced with user application code. */
while(1U)
{

}
}
0 Likes
User8620
Level 2
Level 2
Hi,

thanks for the answer. I got it to work, but I had to make some changes to your example:

The way the files were mapped to SRAM did not work for me. So I just added the attribute to every neccessary function.
The compiler option -mlong-jumps is not recognized. I moved the main function to SRAM. Now the veneers are only needed from SRAM to Flash code.
0 Likes
jferreira
Employee
Employee
10 sign-ins 5 sign-ins First like received
Sorry my mistake, the option is -mlong-calls
See https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html
0 Likes