Delay between portEND_SWITCHING_ISR & Task Resume

I try to implement a usDelay function to wait for some hundred of microseconds with semaphore usage.
For it :

void TIM3_IRQHandler()
    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    xSemaphoreHandle sem = NULL;
    if (TIM_GetITStatus (TIM3, TIM_IT_CC1))
        TIM_ClearITPendingBit (TIM3, TIM_IT_CC1);
        TIM_ITConfig (TIM3, TIM_IT_CC1, DISABLE);
        xSemaphoreGiveFromISR (sem, &xHigherPriorityTaskWoken);
        portEND_SWITCHING_ISR (xHigherPriorityTaskWoken);

From my task i will call this function :

void delay_us (unsigned short delay)
    TIM_ClearITPendingBit (TIM3, TIM_IT_CC1);
    TIM_SetCompare1 (TIM3, TIM3->CNT + delay);
    TIM_ITConfig (TIM3, TIM_IT_CC1, ENABLE);
    xSemaphoreTake (sem, portMAX_DELAY);

Here the code in the task :

t1 = TIM3->CNT;
delay_us1 (100);
t2 = TIM3->CNT;
duration = t2-t1;

For this example i get a 200us duration ?!?!?!

My timer settings are correct (SYSCLK set to 720000000 & Timer prescaler set to 71).
I find a huge 100us variable delay between the ISR END Function & my task resume. I don’t understand why, any answers ?
Please tell me if you need other informations

What else is your system doing? Does it have any critical sections that will delay the timer interrupt? Which chip are you using? not that it would make much difference to the jitter - you would be better off using a direct to task notification rather than a semaphore.

I work on a STM32F103ZDT6. I have around 15 Tasks working together without any critical sections.
I did some tests using only one test task and for a delay of 100us i achieve a real delay of 120us.
I currently work with FreeRTOS 7.0 & Tasks Notifications are not available under this version. But i think i will need to upgrade my firmware …

Why is the ISR using a different variable for the semaphore handle, and setting it to NULL?

There should be some ‘global’ semaphore handle that has been defined and initialized, (or as Richard Barry suggests, use direct-to-task notification).

Version 7 is very old. The newer the version the more assert points there are to help you identify issues the first time you run the code.

Is the 120us period consistent? What period do you get if you setup the timer interrupt from main() then sit in a loop (in main(), so without making any FreeRTOS API calls)?