Hi there,
I work with a freeRTOS system that runs on a STM H7, generated with Cubemx.
I would like to release a semaphore (in User code Tload_Timer_IrqProcess) from the “TIM1 update interrupt”, i.e. the freeRTOS heart:
/**
* @brief This function handles TIM1 update interrupt.
*/
void TIM1_UP_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_IRQn 0 */
/* USER CODE END TIM1_UP_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_UP_IRQn 1 */
// trigger tload events
Tload_Timer_IrqProcess();
/* USER CODE END TIM1_UP_IRQn 1 */
}
This does not work because the timer-interrupt has a priority of 0, but the call of freertos-systemcalls is probably only allowed up to the value “LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY”.
If I call the semaphore function from the timer interrupt, I get stuck in queue.c at this point:
tASSERT_IF_INTERRUPT_PRIORITY_INVALID();
Hmmm… I commented out that spot and my program then works fine.
It worries me as I’m probably breaking an important system requirement which will then hit badly elsewhere.
Is there any way to free a semaphore from a priority 0 interrupt?
Thank you very much for tipps,
friendly regards
recently
well you MUST not call a FreeRTOS API fn from an ISR above max sys call, it will not work. The only option you have is to raise MAX SYSCALL to include pri 0.
Actually, it only appears to work, but you can be sure to experience random and unpredictable crashes. The critical section shield is vital to ensure coherency of the system data structures.
And what I also don’t like is when I change LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY in cubemx, then a lot of interrupts are suddenly shifted to 1, I couldn’t be responsible for the effects. I just want to free up a semaphore and not launch a major attack on the system…
Just don’t do it (freeing a semaphore) this way as it’s not possible. Free it somewhere else in task context if you really, really want to do it (why ?).
For me it seems odd to even think of doing potentially lengthy resource management in an ISR (callback) besides the fact that an ISR is a very restricted context where many things are not possible (in a safe way).
Who is right now, RAc or Hartmut? RAc says set Max syscall to 0 (only option), Hartmut says it doesn’t work at all (although I can already see it working with my illegal hack).
As people have said, it just isn’t possible to directly do this, and something seems wrong with your design to need it.
That said, if you really need to do this, one trick that can be done is to have your high priority task trigger some other ‘unused’ interrupt, with a reasonable priority and do the operation in that ISR. That interrupt doesn’t need to be in any way ‘related’ to the function you are doing, just preferably some interrupt you aren’t using and can set the pending bit for.
Actually, I failed to notice that you actually wish to delete the semaphore in the ISR, that never occurred to me. I thought you intended to release (give) it. If the former, Hartmut is right: Do not even think about it. If the latter, my elaboratons are correct (though I am fairly certain that Hartmut would not oppose them).