This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

osEventFlagsSet() after osKernelSuspend() in RTOS2 tick-less operation

Hi all,

I'm implementing a low power application based on CMSIS RTOS2 with ATSAML22 MCU. I have an RTOS2 tick-less operation like this:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// OS Idle Thread
__NO_RETURN void osRtxIdleThread (void *argument)
{
(void)argument;
for (;;)
{
// Returns OS ticks to sleep
osTickSleep = osKernelSuspend();
if (osTickSleep > 0)
{
// Is there some time to sleep?
// Start the wake up timer
WakeUp_TIMER_Start();
// Enter the low power state
LowPower_MCU_Enter();
#ifdef __DEBUG__
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

When an interrupt is fired while in stop mode I can wakeup and continue working in my app. But the problem is when the interrupt is fired between osKernelSuspend() and go to sleep. The interrupt have is like this:

Fullscreen
1
2
3
4
void IRQHandler (void)
{
osEventFlagsSet(evt_id, EVT_FLAG_1);
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Theorically, when the IRQHandler() is fired the thread which is waiting for the event is resumed from blocked state. But if the IRQHandler() is fired between osKernelSuspend() and go to sleep the thread is not resumed and the MCU enters in sleep. I know that the solution should be to use WFE instead of WFI but it seems that ATSAML22 MCU does not support the WFE instruction and I fixed the idle thread like:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// OS Idle Thread
__NO_RETURN void osRtxIdleThread (void *argument)
{
(void)argument;
for (;;)
{
// Get enabled IRQs in NVIC
uint32_t dwEnableIRQn = NVIC->ISER[0];
// Disable all IRQs in NVIC
NVIC->ICER[0] = 0xFFFFFFFF;
__DSB();
__ISB();
// Returns OS ticks to sleep
osTickSleep = osKernelSuspend();
if (osTickSleep > 0)
{
// Is there some time to sleep?
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Is it a good solution? Or, how can I know if there is any thread right now in ready state to avoid enter in stop mode?

Best regards

Fabrizio

0