FreeRTOS tick halts during PFLASH write, resumes after ~40 sec (STM0_TIM0 match) on AURIX TC3xx

Hi all,

We’re using FreeRTOS on an Infineon AURIX TC3xx (TriCore) device. Our application has periodic tasks running at 5ms, 10ms, and 20ms, and we also perform PFLASH memory operations (erase/write) from a task.

Here’s the issue we’re seeing:

  • After a PFLASH operation (e.g., eraseMultipleSectors()), the FreeRTOS xTickCount stops updating.

  • All periodic tasks that depend on vTaskDelay() or vTaskDelayUntil() also halt.

  • However, the Idle Task continues to run, which means the system is not entirely stalled.

  • After approximately 40 seconds, the tick and periodic tasks resume automatically.

  • We observed that STM0_TIM0 (system timer) reaches 0x10000000 right before the system resumes.


System Configuration:

#define configCPU_CLOCK_HZ              ( ( unsigned long ) 300000000UL ) // 300 MHz
#define configSTM_CLOCK_HZ              ( 100000000 )                     // 100 MHz
#define configTICK_RATE_HZ              ( ( TickType_t ) 1000UL )         // 1 kHz (1 ms tick)

#define configCONTEXT_INTERRUPT_PRIORITY    1
#define configTIMER_INTERRUPT_PRIORITY      2

How to resolve this task should not halt?

Where does this function eraseMultipleSectors() come from? If it is from Infineon driver, I’d suggest reaching out to them.

Hi,

We’re using FreeRTOS on an Aurix TC3xx microcontroller with the following configuration:

  • 3 periodic tasks: 5ms, 10ms, and 20ms

  • All tasks have the same priority (2)

  • configUSE_PREEMPTION = 1, configUSE_TIME_SLICING = 1

  • Tick rate = 1ms

  • System tick source = STM0 CMP0 interrupt


:red_exclamation_mark: Issue

During a Flash erase + write, we disable interrupts for safety:

boolean interruptState = IfxCpu_disableInterrupts();

status = FlashDriver_EraseFlash(...);
status = FlashDriver_WriteFlash(...);

IfxCpu_restoreInterrupts(interruptState);

This blocks the STM0 tick interrupt, so FreeRTOS misses ticks, and periodic tasks (5ms/10ms/20ms) may drift or get delayed.


:white_check_mark: Temporary Workaround

To compensate, we manually update the STM0 compare value after Flash operations:

IfxStm_updateCompare(
    &MODULE_STM0,
    IfxStm_Comparator_0,
    IfxStm_getLower(&MODULE_STM0) + 0x00000100);  // Advance ~1ms

This prevents tick ISR from being delayed indefinitely, and resumes the system tick timing.

:red_question_mark: What We’re Looking For

  • Is there a better or more accurate way to handle missed ticks due to critical sections like Flash operations?

  • Is this a valid and safe approach for real-time task timing?

During flash operations with interrupts disabled, FreeRTOS’s time effectively pauses since it relies on tick interrupt. However, once you re-enable interrupts, the tick interrupt should start firing and FreeRTOS should continue normal task scheduling.

Does this 40 seconds time include flash operations for which interrupts are disabled?

This is specific to the Infineon hardware and therefore, I’d suggest reaching out to them for most accurate answers.

Maybe a better solution would be to ”fix” the tick timer ISR. With STM0 timer configured in compare mode, the ISR must make sure it sets the next compare value to a value in the future. Right now, your ISR is apparently not doing that. Before your fix, you were having to wait for the 32-bit timer to wrap all the way around. A 100 MHz clock on a 32-bit timer rolls over every ~43 seconds.

Another alternative is to configure the timer to reset its count value at each tick interrupt.

With either of those fixes, you’ll be able to tolerate long interrupt making no matter why you do it.

1 Like

Thanks for the explanation — that makes sense.

Just to add, we are currently updating the compare value using:

IfxStm_updateCompare(
    &MODULE_STM0,
    IfxStm_Comparator_0,
    IfxStm_getLower(&MODULE_STM0) + 0x00000100);  // Advance ~1ms

So we’re advancing the compare value relative to the current timer count, but we’re not resetting STM0_TIM0 in the ISR.

do you see any potential impact on the software with this approach…?

I’m assuming this code runs after you’re done with your long interrupt masking.

One problem with this approach is that the problem will return if you ever add anything else in the future that masks interrupts for longer than 1 msec. Same goes if you ever have a combination of interrupt handlers that happen to execute back to back for longer than 1 msec and block the STM0 ISR for longer than 1 msec.