Semaphore doesn't work

I am a newbie to freeRTOS and i was trying to learn about semaphores, the plan was to create 3 tasks each is blinking the same led for some time with different frequencies the result was the led is just on forever.
so I canceled 2 tasks and kept only one task to catch the problem and the led is just on forever again.
I used the debugger and what happens is that it never continue the loop of for loop it toggles the bit and then delay and then toggle again and then go out to check the semaphore and repeat, this is very strange behavior
but that’s in the debugger, in reality, it never toggles it’s on forever
can you help me?

#include <avr/io.h>
/* FreeRTOS files. */
#include "FreeRTOS.h"
#include "task.h"
#include "croutine.h"
#include "FreeRTOSConfig.h"
#include "semphr.h"
#include <avr/interrupt.h>


/* Define all the tasks */
static void ledBlinkingtask1(void* pvParameters);


xSemaphoreHandle  MySemaphore = 0;

int main(void) {
	DDRB=0xff;

	/* Call FreeRTOS APIs to create tasks, all tasks has the same priority "1" with the
	same stack size*/
	xTaskCreate(ledBlinkingtask1,"LED1",
	configMINIMAL_STACK_SIZE, NULL, 1, NULL );
	
	
	// Start the RTOS kernel
	vTaskStartScheduler();

	return 0;
}

static void ledBlinkingtask1(void* pvParameters){
	
	const uint16_t blinkDelay = 500;
	while (1)
	{
		if (xSemaphoreTake(MySemaphore,2000))
		{
			for (int i =0;i<9;i++)
			{
				PORTB ^= (1<<0); //toggle PB0 //PB0
				vTaskDelay(blinkDelay); //wait some time
			}
			xSemaphoreGive(MySemaphore);

		}
	}
}

I’m not fully following your description - if you only have one task why would it be the semaphore that is the problem?

Does this mean that if you have a single task and step through the code in the debugger it works as you expect, but if you run the code without the debugger it doesn’t work? If so, could it just be that the LED is toggling very quickly so you can’t see that it is toggling?

Secondary to that, when you have three tasks running at the same priority it is likely only one task will ever get the semaphore. That is because the task gives the semaphore back then immediately takes it again - the only way another task would get the semaphore would be if a tick interrupt occurred between giving the semaphore and then taking it again. You could fix that by calling taskYIELD() after xSempahoreGive() - although this point is not related to the issue you describe when there is only one task.

I am a newbie to freeRTOS and i was trying to learn about semaphores, the plan was to create 3 tasks each is blinking the same led for some time with different frequencies the result was the led is just on forever.
so I canceled 2 tasks and kept only one task to catch the problem and the led is just on forever again.
I used the debugger and what happens is that it never continue the loop of for loop it toggles the bit and then delay and then toggle again and then go out to check the semaphore and repeat, this is very strange behavior
but that’s in the debugger, in reality, it never toggles it’s on forever
can you help me?

Just to be sure, that the right picture is in the mind.

A semaphore literally is like what you see in the picture. If you have seen any old classic train signalling systems.

The “tasks” are the “trains” themselves. Once the train passes, the sempahore falls down. That is classic semaphore behaviour. You saw the same behaviour in the debugger.

The semaphore was raised for the task to execute. The task did execute, the semaphore was lowered.