fix(interrupt): fixed exit critical section on P4/C5

When adjusting the interrupt level treshold on P4/C6 during a critical section exit
it would take a few cycles before this is taken into account by the CPU.

This meant that under some circumstances, e.g. 02, we could do
yield()->vPortExitCritical()->vPortEnterCritical()
without getting rescheduled.
This causes issues for freertos as it assumes the task will not continue into the
vPortEnterCritical before the scheduler has schedulded it again.

This meant that e.g. xTaskNotifyWait would yield, but then immeditaly continue as if
it was already notified.
pull/13550/head
Marius Vikhammer 2024-03-22 12:11:28 +08:00
rodzic 821d3e2cee
commit be839733ed
1 zmienionych plików z 10 dodań i 0 usunięć

Wyświetl plik

@ -232,6 +232,16 @@ FORCE_INLINE_ATTR void __attribute__((always_inline)) rv_utils_restore_intlevel_
* a single write to the mintthresh register without further manipulations needed.
* This is done to quicken up exit for critical sections */
REG_WRITE(CLIC_INT_THRESH_REG, restoreval);
/**
* After writing the threshold register, the new threshold is not directly taken into account by the CPU.
* By executing ~8 nop instructions, or by performing a memory load right now, the previous memory write
* operations is forced, making the new threshold active.
*
* Without this we risk executing the next several instrucitons before getting interrupted
* This is especially bad if we immediatly enter a new critical section
*/
REG_READ(CLIC_INT_THRESH_REG);
}
/* Direct register write version of rv_utils_set_intlevel(). Used to speed up critical sections. */