Laboratorul 10 - Semafoare FreeRTOS

Introducere

FreeRTOS conține un API specializat în crearea și apelarea semafoarelor, denumit Semaphore API. După cum ați observat în cadrul laboratorului de C POSIX cu același subiect, semafoarele și mutexurile pot fi utilizate pentru sincronizarea task-urilor, accesul la resurse partajate, dar și alte tipuri de semnalizări (similar cu rolul semafoarelor fizice :) ).

FreeRTOS utilizează următoarele tipuri de semafoare, pe care le vom detalia în continuare:

  • Semafoare binare
  • Semafoare generalizate
  • Mutexuri

În cadrul acestui laborator, vom discuta despre semafoarele binare și cele generalizate, urmând ca în următorul să fie prezentate mutexurile.

Toate tipurile de semafore, similar altor elemente din FreeRTOS, sunt referite cu ajutorul handle-urilor. În plus, pentru a le utiliza, este necesară declararea bilbiotecii semphr.h, alături de clasica Arduino_FreeRTOS.h.

// Include biblioteca FreeRTOS
#include <Arduino_FreeRTOS.h>
 
// Include biblioteca pentru semafoare
#include <semphr.h>
 
// Declară o variabilă globală de tipul SemaphoreHandle_t
SemaphoreHandle_t semafor;

În Documentația oficială FreeRTOS, API-ul corespunzător este prezentat începând cu pagina 208, împreună cu exemple de utilizare pentru fiecare funcție.

Declarare

Semafoare binare

O situație în care semafoarele binare se pretează este sincronizarea a două task-uri. De exemplu, un task mai rapid poate fi blocat la un semafor până când un task mai lent ajunge într-un punct în care îl deblochează.

Diferențele dintre mutexuri și semafoarele binare vor fi prezentate în cadrul laboratorului viitor. Momentan, ne vom orienta atenția către crearea semafoarelor binare.

Pentru a crea un semafor binar, este utilizată funcția xSemaphoreCreateBinary() . Aceasta alocă spațiu în heap pentru semaforul binar și îl creează, cu starea inițială este “blocat”. Dacă valoarea întoarsă este NULL, nu există suficientă memorie disponibilă.

Exemplu:

SemaphoreHandle_t xSemaphore;
void vATask( void * pvParameters )
{
 /* Încearcă crearea unui semafor. */
 xSemaphore = xSemaphoreCreateBinary();
 if( xSemaphore == NULL )
 {
 /* Nu există spațiu suficient în memorie pentru a crea semaforul */
 }
 else
 {
 /* Semaforul poate fi acum utilizat. Apelarea xSemaphoreTake() va eșua până la apelarea xSemaphoreGive(). */
 }
}

Semafoare generalizate

Semafoarele generalizate pot avea orice valoare ≥ 0. Când valoarea sa este 0, semaforul este blocat. Pentru a crea un semafor generalizat, este utilizată funcția xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount ). Primul argument reprezintă valoarea maximă a semaforului, iar al doilea argument definește valoare inițială a acestuia.

Exemplu

void vATask( void * pvParameters )
{
SemaphoreHandle_t xSemaphore;  // Declarare handle
 
xSemaphore = xSemaphoreCreateCounting( 10, 0 ); // Creare semafor generalizat cu valoare inițială 0 și valoarea maximă 10
if( xSemaphore != NULL )
{
/* Semaforul a fost creat cu succces*/
}

În exemplul de mai sus, handle-ul a fost declarat în interiorul unui task și nu sub formă de variabilă globală.

Utilizare

Următoarele funcții sunt de interes:

  • Pentru a afla valoarea unui semafor, este utilizată funcția UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore )
  • Pentru a crește valoarea unui semafor, este utilizată funcția BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore )
  • Pentru a scădea valoarea unui semafor, este utilizată funcția BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait). Al doilea parametru specifică timpul maxim pe care un task îl poate petrece așteptând deblocarea semaforului. După depășirea acestui timp, taksul își continuă execuția
  • Pentru a șterge un semafor, este utilizată funcția void vSemaphoreDelete( SemaphoreHandle_t xSemaphore )

Funcțiile Give și Take întorc două valori posibile: pdPASS dacă operația a fost realizată cu succes sau pdFAIL dacă nu.

patr/laboratoare/10.txt · Last modified: 2022/01/13 14:00 by alexandru.ionita99
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0