Documente Academic
Documente Profesional
Documente Cultură
Observatii
traceTASK_INCREMENT_TICK()
traceTASK_SWITCHED_OUT()
traceTASK_SWITCHED_IN()
traceBLOCKING_ON_QUEUE_
RECEIVE(pxQueue)
Indica dac taskul in curs de excutie este pe cale sa treac in starea blocat la
citirea dintr-o coad goal sau solicitarea accesului la un semafor/mutex ocupat.
traceBLOCKING_ON_QUEUE_SEND
(pxQueue)
Indica dac taskul in curs de excutie este pe cale sa treac in starea blocat la
scrierea ntr-o coad plin.
traceGIVE_MUTEX_RECURSIVE(pxMutex)
traceQUEUE_CREATE()
traceQUEUE_CREATE_FAILED()
traceCREATE_MUTEX()
traceCREATE_MUTEX_FAILED()
traceGIVE_MUTEX_RECURSIVE(pxMutex)
traceGIVE_MUTEX_RECURSIVE_
FAILED(pxMutex)
traceTAKE_MUTEX_RECURSIVE(pxMutex)
traceCREATE_COUNTING_SEMAPHORE()
traceCREATE_COUNTING_SEMAPHORE_
FAILED()
traceQUEUE_SEND(pxQueue)
traceQUEUE_SEND_FAILED(pxQueue)
traceQUEUE_RECEIVE(pxQueue)
traceQUEUE_RECEIVE_FAILED()
traceQUEUE_PEEK()
traceQUEUE_SEND_FROM_ISR(pxQueue)
traceQUEUE_SEND_FROM_ISR_
FAILED(pxQueue)
traceQUEUE_RECEIVE_FROM_
ISR(pxQueue)
traceQUEUE_RECEIVE_FROM_ISR_
FAILED(pxQueue)
traceQUEUE_DELETE(pxQueue)
traceTASK_CREATE(pxTask)
traceTASK_CREATE_FAILED()
Apelata din xTaskCreate() dac taskul nu este creat cu success, din cauz ca nu
exista memorie heap suficient
traceTASK_DELETE(pxTask)
traceTASK_DELAY_UNTIL()
traceTASK_DELAY()
traceTASK_PRIORITY_SET(pxTask,
uxNewPriority)
traceTASK_SUSPEND(pxTask)
traceTASK_RESUME(pxTask)
traceTASK_RESUME_FROM_ISR(pxTask)
Exemple:
TraceTASK_SWITCHED_OUT() i traceTASK_SWITCHED_IN() sunt apelate de
vTaskSwitchContext.
In FreeRTOSconfig.h:
#define configUSE_TRACE_FACILITY
1. numarare comutri:
In main.c:
unsigned int nr_switch_T2;
void vMainMineIn(void){
if ( handT2 == pxCurrentTCB )
}
nr_switch_T2++;
2. numarare comutari de la T2 la T1
unsigned int nr_switch_T2, ies_T2;
void vMainMineOut(void){
if ( handT2 == pxCurrentTCB) ies_T2=1;
}
void vMainMineIn(void){
if ( handT1 == pxCurrentTCB && ies_T2==1 )
ies_T2=0;
}
nr_switch_T2++;
3. numarare comutari de la T2 la T2
unsigned int nr_switch_T2, ies_T2;
void vMainMineOut(void){
if ( handT2 == pxCurrentTCB) ies_T2=1;
}
void vMainMineIn(void){
if ( handT2 == pxCurrentTCB && ies_T2==1 )
ies_T2=0;
}
nr_switch_T2++;
Cerinta: configUSE_APPLICATION_TASK_TAG = 1
Exemplu de folosire:
#define traceTASK_SWITCHED_OUT() xTaskCallApplicationTaskHook( pxCurrentTCB, 0 )
static portBASE_TYPE prvExampleTaskHook( void * pvParameter) {
..
return 0;
}
Exemplu
In FreeRTOSConfig.h:
#define configUSE_APPLICATION_TASK_TAG 1
#define traceTASK_SWITCHED_IN() xTaskCallApplicationTaskHook( pxCurrentTCB, 0 )
In main:
unsigned int nr_cazuri, com_in_for_T2=1, flagT2=0;
static portBASE_TYPE HookT2_In( void * pvParameter) {
static unsigned int urmflagT2=-1;
if(urmflagT2!=flagT2) com_in_for_T2++;
return 0;
}
void Task1(void *params) {
portTickType xLastTime = xTaskGetTickCount()-1;
TaskSetApplicationTaskTag( NULL, 0 );
for (;;){
no_ticks=xTaskGetTickCount();
if (xLastTime!=no_ticks){varaux1=varaux1+1;xLastTime=no_ticks;}
vParTestToggleLED(15); vTaskDelayUntil(&xLastTime,15);
}}
taskSCHEDULER_NOT_STARTED,
taskSCHEDULER_RUNNING,
taskSCHEDULER_SUSPENDED
Timpii de executie asociati unui task in cadrul unui frame sau pe portiuni de cod pot
fi determinati
+ folosind functiile trace cu traceTASK_SWITCHED_IN()/
traceTASK_SWITCHED_OUT()
+ gestionand un numarator hardware pentru o rezolutie bun.
+ marcand inceputul /sfarsitul secventei dorite printr-un flag
Aceste servicii sunt deja oferite foarte simplu de FreeRTOS care poate evidenia
timpii de execuie ai proceselor ca valoare absoluta i % din timp total de execuie.
Necesar: configGENERATE_RUN_TIME_STATS = 1
Atunci vTaskStartScheduler() apeleaz portCONFIGURE_TIMER_
FOR_RUN_TIME_STATS(), pentru a seta o rezolutie mai mic dect cea a
tickului la calcularea timpilor de execuie.
Setarea este vizibil prin portGET_RUN_TIME_COUNTER_VALUE()
Exemplu
In FreeRTOSConfig.h
#define configTICK_RATE_HZ
( ( portTickType ) 100 )
#define configGENERATE_RUN_TIME_STATS
1
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ( 0UL )
#define portGET_RUN_TIME_COUNTER_VALUE() 5000UL
In Main.c se modifica
void Task2(void *params) {
portTickType xLastTime = xTaskGetTickCount();//la primul frame valoarea este 0
vTaskSetApplicationTaskTag( NULL, HookT2_In );
for (;;){
flagT2++;
no_ticks=xTaskGetTickCount();
if (xLastTime!=no_ticks){varaux2=varaux2+1;xLastTime=no_ticks;}
if (no_ticks <50) { vParTestSetLED( 14, 0 );}
if (no_ticks ==50) {
if (uxCurrentNumberOfTasks==2)
xTaskCreate(Task1, (signed portCHAR *)
"T1",configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1,
&handT1);
vParTestSetLED( 14, 1 );
}
if (no_ticks >50){
uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
vTaskGetRunTimeStats( &myBuffer[0] );
vParTestToggleLED(14);
vTaskDelayUntil(&xLastTime,35);
}
}
}
2. Verificare suplimentar:
(trebuie setat configCHECK_FOR_STACK_OVERFLOW = 2)
La crearea taskului, stiva este intializat cu un marcator specific.
La comutarea din starea in curs de executie se verific dac ultimii 16 octeti
introdusi in stiv nu sunt modificati de proces. In caz de eroare, este apelat hook-ul
de depire stiv.
Nu garanteaz detectarea tuturor depirilor, dar este destul de bun.
Exercitii
1. Schitati in C (pentru FreeRTOS) urmatorul program:
o Sunt activate task T1 (prioritate P1), task T2 (prioritate P2), task T3 (prioritate
P3) si task T2 (prioritate 2) apoi este activat planificatorul.
o T1 suspenda T2 daca acesta nu este deja suspendat si intra in blocare pentru 2
sec.
o T2 intra in blocare pentru 2 sec
o T3 scoate T2 din suspended daca acesta este deja suspendat si intra in blocare
pentru 2 sec.
a) P1= 2, P2=1, P3=3:
b) P1= 4, P2=1, P3=2:
c) P1= 3, P2=2, P3=1:
Indicati o varianta prin care sa ilustrati experimental daca T3 este preemtat si cate
preemtari au loc pe un interval de timp specificat.
Frame-ul are lungime de 500 msec.