Open hadongzhu opened 1 year ago
@hadongzhu, Thanks, you are right that it cannot exit low power mode when an interrupt masked by BASEPRI occurs When TX_PORT_USE_BASEPRI is enabled. Here is a workaround.
#ifdef TX_ENABLE_WFI
#ifdef TX_PORT_USE_BASEPRI
CPSID i
MOV r1, #0
MSR BASEPRI, r1
#endif
DSB // Ensure no outstanding memory transactions
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI
MSR BASEPRI, r1
CPSIE i
#endif
#endif
@wangwen-4220, thank you for your reply, your workaround works fine, but I think this is not the best solution. WFI instroction means "Wait For Interrupt", and in function tx_low_power_enter
, the comment for TX_RESTORE
is /* Re-enable interrupts before low power mode is entered. */
, but it do not enable interrupts actually. So, it's may be It may be better to enable interrupts before entering low power mode, instead of after entering low power mode, like this:
__tx_ts_wait:
#ifdef TX_PORT_USE_BASEPRI
LDR r1, =TX_PORT_BASEPRI // Mask interrupt priorities =< TX_PORT_BASEPRI
MSR BASEPRI, r1
#else
CPSID i // Disable interrupts
#endif
LDR r1, [r2] // Pickup the next thread to execute pointer
STR r1, [r0] // Store it in the current pointer
CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready!
#ifdef TX_PORT_USE_BASEPRI
MOV r4, #0 // Disable BASEPRI masking (enable interrupts)
MSR BASEPRI, r4
#else
CPSIE i // Enable interrupts
#endif
#ifdef TX_LOW_POWER
PUSH {r0-r3}
BL tx_low_power_enter // Possibly enter low power mode
POP {r0-r3}
#endif
#ifdef TX_ENABLE_WFI
DSB // Ensure no outstanding memory transactions
WFI // Wait for interrupt
ISB // Ensure pipeline is flushed
#endif
#ifdef TX_LOW_POWER
PUSH {r0-r3}
BL tx_low_power_exit // Exit low power mode
POP {r0-r3}
#endif
B __tx_ts_wait // Loop to continue waiting
Hi,
I'm using ThreadX (6.2.1) on STM32H750 (Cortex-M7) with AC6 toolchain. When TX_PORT_USE_BASEPRI is enabled, it can not exit low power mode when an interrupt masked by BASEPRI occurs.
I find that interrupts are not enabled before entering low power mode, in
.\ports\cortex_m7\ac6\src\tx_thread_schedule.S
:Interrupts are enabled after WFI. and in
.\utility\low_power\tx_low_power.c
:Since the interrupt is disabled before calling
tx_low_power_enter
,TX_RESTORE
intx_low_power_enter
cannot re-enable interrupts. So interrupts are not enabled before entering low power mode. It results in interrupts masked by BASEPRI not being able to make it exit from low power mode. And when using PRIMASK to disable interrupts, there is no such problem, it can still exit low power mode when any interrupt occurs.