Can I use xSemaphoreGiveFromISR for two different semaphores in the same IR routine

Hi,

I have two threads:
Thread 1 gets data from an I2C device and takes about 512 us per acquisition
Thread 2 calculates values from the data and activates a processor output this takes about 180 us.
Thread 2 has a higher priority than thread 1.

The timing of the processes must be accurate to 2 ms i.e. two RTC Ticks.

I run a timer and which interrupts every ms with a high priority.

The ISR of the timer gives to two separate semaphores one for thread 1 and one for thread 2.

viz:

__attribute__((section(".Tim2itcm"))) void TIM2_IRQHandler(void)
//void TIM2_IRQHandler(void)
{
  HAL_TIM_IRQHandler(&htim2);
//  __HAL_TIM_CLEAR_IT(&htim2, TIM_IT_UPDATE); /* rjg */


  osSemaphoreRelease(sampleTimerSemHandle);
  osSemaphoreRelease(clockControllerSemHandle);
}

You can see I'm using the CMSIS OS wrapper but this just calls the FreeRTOS functions anyway.

When I run the system from debug the sytem works fine and I get  a jitter on the data of about +/- 1ms.  However when I boot the system using by power cycling I end up with a hard fault which occurs during the second semaphore call.  I thought I might have a stack problem so I increased the FreeRTOS minimum to 2048 with no fix.

The question I have is: 

"Is it OK to have two calls to xSemaphoreGiveFromISR for the two seperate sem's or is this a no-no?"

Best regards
Rob


Yes it is fine but you are better off calling the native api otherwise you are missing the “HigherPriorityTaskWoken” parameter which could mean a context switch doesn’t happen immediately - see the docs for xSemaphoreGiveFromISR().

Hi Barry

Thanks for that!

I will take your advice and use the native FreeRTOS Calls. I used the CMSIS thing because STM32CubeMx creates those, but I think it’s just layer of code that adds no value and obscures the underlying good stuff.

The funny thing is the code works fine if I start it using the debugger, but as soon as I power cycle it all turns to you-know-what.

I use FreeRTOS for all my STM32 apps as it is simple to use and it just works.

Best regards

Rob

Toongabbie Light & Power

What line causes the fault? You can follow the instructions here to find the faulting instruction - Debugging and diagnosing hard faults on ARM Cortex-M CPUs

Thanks.

Hi Richard

Sorry I got your name the wrong way around.

Hi,

I replaced the tasks and semaphores with static versions. The hard fault then occurred whilst debugging so it took me five minutes to realise I hadn’t allocated sufficient stack for the second task. The semaphore buffer was getting overwritten by stack transaction so the app was passing a bad semaphore handle to the xSemaphoreTake giving a memory alignment hard fault.

I don’t know why it worked under debug, but not under power reset when I was using the dynamic tasks and sem’s.

I am using STLink V3.0 debugger with the CubeMX Eclipse IDE.

Has anyone got any theories/ideas on this?

Another question:

Why don’t CPU manufacturers provide a stack limit register in addition to the stack pointer such that if the stack hits the limit register a dedicated hard fault - stack error is generated. I know this question is beyond the scope of FreeRTOS, but such a device would save a lot of embarrassment.

Different code can cause different error/stack overflow symptoms.
You’re better off defining configASSERT, enable FreeRTOS stack checking etc. for development.
Regarding the latter question e.g. ARM Cortex-M33 and later have stack pointer limit registers supported and used by FreeRTOS.

I think one of the microchip parts FreeRTOS supports also has a stack limit register, maybe the daPIC (?). Separately, FreeRTOS ports that support memory protection bound the stack with a memory protection region that generates a memfault if you overflow (or under flow!) the stack.

This has been discussed before, for example here:

Using the ARM MPU to detect stack overflow - Kernel - FreeRTOS Community Forums