mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 03:07:21 +02:00
Merge branch 'feature/re-enable_suspend_test_esp32c3_v4.3' into 'release/v4.3'
freertos: Workaround delay between interrupt request and trigger on RISC-V (backport v4.3) See merge request espressif/esp-idf!12679
This commit is contained in:
@ -178,6 +178,24 @@ void prvTaskExitError(void)
|
|||||||
void vPortClearInterruptMask(int mask)
|
void vPortClearInterruptMask(int mask)
|
||||||
{
|
{
|
||||||
REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, mask);
|
REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, mask);
|
||||||
|
/**
|
||||||
|
* The delay between the moment we unmask the interrupt threshold register
|
||||||
|
* and the moment the potential requested interrupt is triggered is not
|
||||||
|
* null: up to three machine cycles/instructions can be executed.
|
||||||
|
*
|
||||||
|
* When compilation size optimization is enabled, this function and its
|
||||||
|
* callers returning void will have NO epilogue, thus the instruction
|
||||||
|
* following these calls will be executed.
|
||||||
|
*
|
||||||
|
* If the requested interrupt is a context switch to a higher priority
|
||||||
|
* task then the one currently running, we MUST NOT execute any instruction
|
||||||
|
* before the interrupt effectively happens.
|
||||||
|
* In order to prevent this, force this routine to have a 3-instruction
|
||||||
|
* delay before exiting.
|
||||||
|
*/
|
||||||
|
asm volatile ( "nop" );
|
||||||
|
asm volatile ( "nop" );
|
||||||
|
asm volatile ( "nop" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set interrupt mask and return current interrupt enable register */
|
/* Set interrupt mask and return current interrupt enable register */
|
||||||
@ -188,6 +206,17 @@ int vPortSetInterruptMask(void)
|
|||||||
ret = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG);
|
ret = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG);
|
||||||
REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, RVHAL_EXCM_LEVEL);
|
REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, RVHAL_EXCM_LEVEL);
|
||||||
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
|
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
|
||||||
|
/**
|
||||||
|
* In theory, this function should not return immediately as there is a
|
||||||
|
* delay between the moment we mask the interrupt threshold register and
|
||||||
|
* the moment a potential lower-priority interrupt is triggered (as said
|
||||||
|
* above), it should have a delay of 2 machine cycles/instructions.
|
||||||
|
*
|
||||||
|
* However, in practice, this function has an epilogue of one instruction,
|
||||||
|
* thus the instruction masking the interrupt threshold register is
|
||||||
|
* followed by two instructions: `ret` and `csrrs` (RV_SET_CSR).
|
||||||
|
* That's why we don't need any additional nop instructions here.
|
||||||
|
*/
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,9 +89,6 @@ TEST_CASE("Suspend/resume task on other core", "[freertos]")
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
|
|
||||||
// TODO ESP32C3 IDF-2588
|
|
||||||
|
|
||||||
/* Task suspends itself, then sets a flag and deletes itself */
|
/* Task suspends itself, then sets a flag and deletes itself */
|
||||||
static void task_suspend_self(void *vp_resumed)
|
static void task_suspend_self(void *vp_resumed)
|
||||||
{
|
{
|
||||||
@ -118,7 +115,6 @@ TEST_CASE("Suspend the current running task", "[freertos]")
|
|||||||
// Shouldn't need any delay here, as task should resume on this CPU immediately
|
// Shouldn't need any delay here, as task should resume on this CPU immediately
|
||||||
TEST_ASSERT_TRUE(resumed);
|
TEST_ASSERT_TRUE(resumed);
|
||||||
}
|
}
|
||||||
#endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
|
|
||||||
|
|
||||||
|
|
||||||
volatile bool timer_isr_fired;
|
volatile bool timer_isr_fired;
|
||||||
|
Reference in New Issue
Block a user