2018-02-07 12:47 AM
Hi,
I'm developing on a custom board with STM32F429. I need to use stop mode for power consumption. We have some external interrupt (e.g. interrupt from accelerometer) we use to wakeup from stop mode.
Wake up is working fine, but the problem is that exiting from stop mode, HSI oscillator is automatically used. I need to reconfigure the PLL prior to executing the interrupt handler that woke up the MCU. I enter stop mode in my idle task as soon as it's possible.
My first solution was to enter stop mode with global interrupt disabled, in order to reconfigure PLL in idle task and then restoring global interrupt and execute the interrupt handler that woke up the MCU. But it's not working: MCU remains in stop mode no matter what.
I used this apporach in the past using a Kinetis MCU (cortex M4) from NXP and it was working fine.
Am I missing something?2018-02-07 02:47 AM
Hello
alessandro.morniroli
,please provide here more info about:
Best regards,
Tilen
2018-02-07 06:57 AM
Hi Tilen,
I know the MCU is still in stop because I turn on a led as soon as it exits from stop mode (but the led remain off).
I managed to exit from stop mode with global interrupt disabled, starting from a blank project
__disable_irq ();
HAL_PWR_EnterSTOPMode (PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
ledPowerOn ();
__enable_irq ();�?�?�?�?�?�?�?�?
ledPowerOn is executed before the interrupt handler that woke up the MCU (this is correct, and this is what I want).
I think the problem is that in my project, I'm using FreeRTOS, and instead of __disable_irq ()
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
__ASM volatile ('cpsid i' : : : 'memory');
}�?�?�?�?
I'm using the FreeRTOS macro vPortEnterCritical ()
#define configPRIO_BITS 4
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY \
( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See https://community.st.com/external-link.jspa?url=http%3A%2F%2Fwww.FreeRTOS.org%2FRTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY \
( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
{
uint32_t ulNewBASEPRI;
__asm volatile
(
' mov %0, %1
' \
' msr basepri, %0
' \
' isb
' \
' dsb
' \
:'=r' (ulNewBASEPRI) : 'i' ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
);
}
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context. Only API
functions that end in 'FromISR' can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */
if( uxCriticalNesting == 1 )
{
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
}
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
I think it's something in basepri setting that is preventing interrupt to trigger and to exit from stop mode.
2018-02-07 07:35 AM
Hello
alessandro.morniroli
,FreeRTOS might not always disable interrupts when entering critical section.
Please check URL below with some informations.
To force interrupt disable, use __disable_irq function
https://www.freertos.org/RTOS-Cortex-M3-M4.html
Do you use tickless sleep mode inside idle thread?
Best regards,
Tilen
2018-05-09 05:22 AM
Hi Tilen,
no I haven't used tickless sleep mode.Best regards,Alessandro Morniroli