xEventGroupSetBitsFromISR() return pdFAIL from the ISR sometimes

I am using xEventGroupSetBitsFromISR() from an ISR which trigger when ever the timer expires. The timer is a 1 shot interrupt timer. It is not periodic. I have noticed that sometimes xEventGroupSetBitsFromISR() return failure and the bit I am trying to set does not get set. I can’t use task notifcation because I am using streambuffer which seem to use this. I’ve ran into multiple problems using streambuffer and task notifcation in the past. My only other solution is to use a semaphore. I am running FreeRTOSv10.0.0 On another note most these timer are setup on order of a few 100microseconds. A tick for the RTOS is 5ms. The timer task is set to the highest prioirty in the system. ~~~ static inline void TimerHandler(const IRQnType irqnumber, const pitchnlt channel, const uint32t triggerbit) { if( NULL != events ) { BaseTypet is_awoken = pdFALSE;
    Timer_Disable(irq_number,channel);

    if( pdFAIL != xEventGroupSetBitsFromISR(events, trigger_bit, &is_awoken) )
    {
        portYIELD_FROM_ISR(is_awoken);
    }
    else
    {
        ASSERT_DEBUG_MODE(0);
    }
}
else
{
    ASSERT_DEBUG_MODE(0);
}
} ~~~

xEventGroupSetBitsFromISR() return pdFAIL from the ISR sometimes

It looks like after further investigation that xEventGroupSetBitsFromISR() is actually successing on every calls but the task pending on the bit (xEventGroupWaitBits()) never gets the bit. Testing this with only 1 task created.

xEventGroupSetBitsFromISR() return pdFAIL from the ISR sometimes

Ok, just to follow up on this I was completely mislead by what is occuring. The problem had nothing to do with ISR. It has to do with xEventGroupWaitBits() in the task is not blocking for 1 tick which is 5ms. It’s blocking for only 436us. The task calls xEventGroupWaitBits() with 1 tick timeout. But a single tick is 5ms while I had setup the ISR to run for 650us. Which means my ISR will run before that tick has elapsed. But that does not seem to occour. I used a scope and timed everything. xEventGroupWaitBits() when called with 1 tick is only delaying about 436us. I completed timed this. The expected calls are 1. Setup timer interrupt with 650us 2. Wait in the task for the event bit (xEventGroupWaitBits()) to be set by the ISR. With a max block time of 1 tick which equal to 5ms. 3. ISR runs and sets the event bit What I am finding is that xEventGroupWaitBits() returns before the ISR runs and when I time it using a GPIO pin and a scope the block time is only around 436us. What I found is if I set xEventGroupWaitBits() to block for 2 ticks which is 10ms everything works great! Any thoughts on why this may be occuring.

xEventGroupSetBitsFromISR() return pdFAIL from the ISR sometimes

There is no sub-tick resolution – if there is a tick every 5ms and you ask for a block time of 1 tick, then the actual block time can be anything from 0.000001ms to 4.999999ms, depending on where within the time slice the request to block for 1 tick was made.

xEventGroupSetBitsFromISR() return pdFAIL from the ISR sometimes

Hi Richard, I did a bad job at explaining what was occuring lets try this again. See the code reference below. The RTOS is setup for 200Hz which is 5ms per tick. I am setting up a hardware timer (lets call is PIT0) to interrupt once with a counter value equivalent to 650us. This is a different timer than the systick timer. Before I block on xEventGroupWaitBits() for 1 tick (i.e 5ms) I toggle a GPIO line which i connected to a scope. I do this so I can measure the real time external to the MCU. What I am finding is that occassionally xEventGroupWaitBits() does not wait anywhere close to 5ms. The PIT0 timer is setup correctly because I can measure that timing using another IO pin also connected to the scope. I have cases where xEventGroupWaitBits() returns before the PIT0 interrupt runs. When I check the timing on GPIO0 which measure the time xEventGroupWaitBits() is in the blocked state it was around 436us. This is very far off from 5ms. What I have found that works is if I set the timeout on xEventGroupWaitBits() to 2 ticks, everything works fine. That xEventGroupWaitBits() blocks for about 650us as expected. Additonally 1. I have been testing with only 1 task created. 2. trigger_bit variable is only 1 bit that is the 4th bit only. ~~~ xEventGroupClearBits(events, triggerbit); /*Clear the trigger bit which will be given from the ISR*/ SetupInterrupt_Timer0();
Toggle_GPIO0();

const EventBits_t bit_taken = xEventGroupWaitBits(events, trigger_bit, pdTRUE, pdTRUE, 1);

Toggle_GPIO0();
~~~

xEventGroupSetBitsFromISR() return pdFAIL from the ISR sometimes

What Richard is trying to explain to you is that a tick is NOT deterministic, if a task yield in the middle of a tick caused by an interrupted or another mechanism, the scheduler will run and launch the next available tasks of the highest priority it does not wait 5 ms to launch the next task…. doing so would be very inefficient use of the CPUs resources….most all Operating systems work like this. If you need more accurate timing use a hardware timer or change the tick to something faster like 1 ms…. but setting the tick faster, cause the OS to spend more time in the scheduler so, it become a system design trade off….

xEventGroupSetBitsFromISR() return pdFAIL from the ISR sometimes

To elaborate further: The tick interrupt occurs at a fixed frequency. If you ask to block for 1 tick you are effectively saying unblock the task at the next tick interrupt. If there is a tick interrupt every five milliseconds, and you block a task four milliseconds after the last tick interrupt, then the next tick interrupt will occur one milllisecond after that task entered the blocked state – and the task will therefore only block for one millisecond. This is what I mean by there is only (in your case) five millisecond resolution – you cannot block with any more accuracy than five milliseconds.