Setting up the code

First, the semaphore needs to be created, and its handle (or pointer) has to be stored so that it can be used between tasks. The following excerpt has been taken from mainSemExample.c:

//create storage for a pointer to a semaphore
SemaphoreHandle_t semPtr = NULL;

int main(void)
{
//.... init code removed.... //

//create a semaphore using the FreeRTOS Heap
semPtr = xSemaphoreCreateBinary();
//ensure pointer is valid (semaphore created successfully)
assert_param(semPtr != NULL);
The semaphore pointer, that is, semPtr, needs to be placed in a location that is accessible to other functions that need access to the semaphore. For example, don't declare semPtr as a local variable inside a function – it won't be available to other functions and it will go out of scope as soon as the function returns.

To see what's going on with the source code and see how the system is reacting, we'll associate a few different LEDs with task A and task B.

Task A will toggle the green LED and give a semaphore every five times it's run through the blinking loop, as shown in the following excerpt from mainSemExample.c:

void GreenTaskA( void* argument )
{
uint_fast8_t count = 0;
while(1)
{
//every 5 times through the loop, give the semaphore
if(++count >= 5)
{
count = 0;
SEGGER_SYSVIEW_PrintfHost("Task A (green LED) gives semPtr");
xSemaphoreGive(semPtr);
}
GreenLed.On();
vTaskDelay(100/portTICK_PERIOD_MS);
GreenLed.Off();
vTaskDelay(100/portTICK_PERIOD_MS);
}
}

Task B, on the other hand, will rapidly blink the blue LED three times after successfully taking the semaphore, as shown in the following excerpt from mainSemExample.c:

/**
* wait to receive semPtr and triple blink the Blue LED
*/
void BlueTaskB( void* argument )
{
while(1)
{
if(xSemaphoreTake(semPtr, portMAX_DELAY) == pdPASS)
{
//triple blink the Blue LED
for(uint_fast8_t i = 0; i < 3; i++)
{
BlueLed.On();
vTaskDelay(50/portTICK_PERIOD_MS);
BlueLed.Off();
vTaskDelay(50/portTICK_PERIOD_MS);
}
}
else
{
// This is the code that will be executed if we time out
// waiting for the semaphore to be given
}
}
}

Great! Now that our code is ready, let's see what this behavior looks like.

FreeRTOS allows for indefinite delays in certain circumstances through the use of portMAX_DELAY. As long as #define INCLUDE_vTaskSuspend 1 is present in FreeRTOSConfig.h, the calling task will be suspended indefinitely and the return value of xSemaphoreTake() can be safely ignored. When vTaskSuspend() is not defined as 1, portMAX_DELAY will result in a very long delay (0xFFFFFFF RTOS ticks (~ 49.7 days) on our system), but not an infinite one.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.37.68