Synchronizing tasks

I have two tasks. One is watching and processing a UART. The other one should toggle RESET/SET PC13 of an STM32F103C8T6 (blue pill). The latter should flash the LED for very short moment. (still osDelay(10) seems tool long). I solved it by letting Task1 set a global variable sem1 to TRUE. Task 2 tests sem1 and flashes the LED when sem1 goes TRUE and resets it.

Is there a standard way to do this in FreeRTOS rather than “hand crafting” this mechanism like I did?

Your description of the problem is not very clear. It seems that you want to trigger LED tasks from the UART handling task when something happens. If that is right, you should be able to use task notification for that - RTOS task notification API functions

Hope I can make it clearer:

Task1 is waiting to receive a character in the input queue- As soon as the character is available, it puts it in the output queue and flags that a character has been received. It does this by setting the flag sem1.

Task2’s sheere obligation is, to watch whether sem1 is set, toggle the LED once and reset sem1.

That would work. There are couple of thinks that you can consider -

  1. If the task 2 is just toggling an LED, you can likely do that in task1 itself.
  2. If you still decide to use a task, then instead of waking task2 periodically and check the global flag, you can use a semaphore or direct to task notification, so that task2 only wakes up when needed (i.e. when a character is received).

Thanks. That’s what I was aiming at. I didn’t want to bury Task1 with toggling the LED since its prior task is reacting on input.
Do you have an example of setting up a semaphore in FreeRTOS?

When I worked in security (card readers etc), we were frequently implementing similar things. The following strategy has proven the mostbstable (abbreviated pseudo code):

  • In your UART receiver task, rewind a timer, say, unconditionally set a global variable to, say, 10.
  • In a timer (regardless where), check whether that timer variable is 0. If not, set your LED and decrement the timer. If that yields 0, clear the LED. That way, you will always have (in this case) 10 timer ticks after the last character until the LED goes off. Only thing to worry about is potential underflows due to race conditions, but those are easy to handle.

Another option, since toggling an LED is fairly simple, is task 1 could turn on the LED, and then start a software timer for the duration you want the LED on, and then in the software timer callback you could turn off the LED.

Now, one issue that may come up, is that, particularly for short delays, you are going to notice a variation in the LED on time, because it is going to matter where in the current tick you are when you turn on the LED. A answer to that is to use a seperate task or Timer Callback, and first wait for 1 tick and THEN turn the LED on, and then wait for the duration and turn it off.