Differences

This shows you the differences between two versions of the page.

Link to this comparison view

patr:laboratoare:10 [2021/10/22 17:46]
127.0.0.1 external edit
patr:laboratoare:10 [2022/01/13 14:00] (current)
alexandru.ionita99
Line 1: Line 1:
-===== Laboratorul 10. =====+===== 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**.  
 + 
 +<code c> 
 +// 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; 
 +</​code>​ 
 + 
 +În [[https://​www.freertos.org/​fr-content-src/​uploads/​2018/​07/​FreeRTOS_Reference_Manual_V10.0.0.pdf|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: ** 
 +<code c> 
 +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(). */ 
 + } 
 +
 +</​code>​ 
 + 
 +=== 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** 
 +<code c> 
 +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*/ 
 +
 +</​code>​ 
 + 
 +Î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 )** 
 + 
 +<note tip>​Funcțiile **Give** și **Take** întorc două valori posibile: **pdPASS** dacă operația a fost realizată cu succes sau **pdFAIL** dacă nu.</​note>​ 
  
  
patr/laboratoare/10.1634914005.txt.gz · Last modified: 2022/01/12 15:21 (external edit)
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