Complete o código baseado no sistema operacional FREERTOS abaixo de forma que os níveis lógicos nos pinos RD1, RD2, RD3 e RD4 sejam alternados a cada 200 \mathrm{~ms}, 600 \mathrm{~ms}, 300 \mathrm{~ms} e 300 ms respectivamente, como na questão 1. No caso do pino RD5, o mesmo só deverá apresentar nível lógico 1 se o botão no pino RBO estiver pressionado (nível lógico 0), sendo que a verificação do botão deverá ocorrer a cada 150 ms . (0,50 pontos)
Obs: em cada tarefa só pode ser relacionado um pino de I/O.
void main( void ){
TRISD=0b00000000;
TRISB=0b00000001;
xTaskCreate(vTASK0,(const char * const)"T0",configMINIMAL_STACK_SIZE,NULL,(tskIDLE_PRIORITY+1), NULL);
xTaskCreate(vTASK ,(const char * const)"T1",configMINIMAL_STACK_SIZE,NULL,(tskIDLE_PRIORITY+ ), NULL);
xTaskCreate(vTASK ,(const char * const)"T2",configMINIMAL_STACK_SIZE,NULL,(tskIDLE_PRIORITY+ ), NULL);
xTaskCreate(vTASK ,(const char * const)"T3",configMINIMAL_STACK_SIZE,NULL,(tskIDLE_PRIORITY+ ), NULL);
xTaskCreate(vTASK ,(const char * const)"T4",configMINIMAL_STACK_SIZE,NULL,(tskIDLE_PRIORITY+ ), NULL);
vTaskStartScheduler();
}
void vTASKO(){
    while(1) {
    PORTDbits.RD1=! PORTDbits.RD1;
    vTaskDelay(200/portTICK_RATE_MS);
    }
}

Passo 1

O enunciado pede que criemos cinco tarefas no FreeRTOS, cada uma cuidando de um único pino de saída em PORTD ou de leitura em PORTB, com as seguintes características:
  • vTASK0 alterna RD1 a cada 200 ms (já dada).
  • vTASK1 alterna RD2 a cada 600 ms.
  • vTASK2 alterna RD3 a cada 300 ms.
  • vTASK3 alterna RD4 a cada 300 ms.
  • vTASK4 verifica RB0 a cada 150 ms e, se estiver pressionado (nível lógico 0), coloca RD5 = 1; caso contrário, RD5 = 0.
Vamos completar as chamadas a xTaskCreate e implementar vTASK1…vTASK4.

Passo 2

Preencher as chamadas a xTaskCreate, usando a mesma prioridade para todas as tarefas:
    xTaskCreate(vTASK0, "T0", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY+1), NULL);
    xTaskCreate(vTASK1, "T1", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY+1), NULL);
    xTaskCreate(vTASK2, "T2", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY+1), NULL);
    xTaskCreate(vTASK3, "T3", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY+1), NULL);
    xTaskCreate(vTASK4, "T4", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY+1), NULL);
    vTaskStartScheduler();

Passo 3

Implementar as tarefas que alternam pinos RD2, RD3 e RD4 nos períodos especificados:
void vTASK1(void *pvParameters)
{
    (void) pvParameters;
    for(;;) {
        PORTDbits.RD2 = !PORTDbits.RD2;
        vTaskDelay(600 / portTICK_RATE_MS);
    }
}

void vTASK2(void *pvParameters)
{
    (void) pvParameters;
    for(;;) {
        PORTDbits.RD3 = !PORTDbits.RD3;
        vTaskDelay(300 / portTICK_RATE_MS);
    }
}

void vTASK3(void *pvParameters)
{
    (void) pvParameters;
    for(;;) {
        PORTDbits.RD4 = !PORTDbits.RD4;
        vTaskDelay(300 / portTICK_RATE_MS);
    }
}

Passo 4

Implementar a tarefa que monitora o botão em RB0 a cada 150 ms e aciona RD5:
void vTASK4(void *pvParameters)
{
    (void) pvParameters;
    for(;;) {
        if(PORTBbits.RB0 == 0) {      // botão pressionado
            PORTDbits.RD5 = 1;
        } else {
            PORTDbits.RD5 = 0;
        }
        vTaskDelay(150 / portTICK_RATE_MS);
    }
}

Resposta

#include "FreeRTOS.h"
#include "task.h"

void vTASK0(void *pvParameters)
{
    (void) pvParameters;
    for(;;) {
        PORTDbits.RD1 = !PORTDbits.RD1;
        vTaskDelay(200 / portTICK_RATE_MS);
    }
}

void vTASK1(void *pvParameters)
{
    (void) pvParameters;
    for(;;) {
        PORTDbits.RD2 = !PORTDbits.RD2;
        vTaskDelay(600 / portTICK_RATE_MS);
    }
}

void vTASK2(void *pvParameters)
{
    (void) pvParameters;
    for(;;) {
        PORTDbits.RD3 = !PORTDbits.RD3;
        vTaskDelay(300 / portTICK_RATE_MS);
    }
}

void vTASK3(void *pvParameters)
{
    (void) pvParameters;
    for(;;) {
        PORTDbits.RD4 = !PORTDbits.RD4;
        vTaskDelay(300 / portTICK_RATE_MS);
    }
}

void vTASK4(void *pvParameters)
{
    (void) pvParameters;
    for(;;) {
        if(PORTBbits.RB0 == 0) {      // botão pressionado
            PORTDbits.RD5 = 1;
        } else {
            PORTDbits.RD5 = 0;
        }
        vTaskDelay(150 / portTICK_RATE_MS);
    }
}

void main(void)
{
    TRISD = 0b00000000;  // RD1..RD5 como saída
    TRISB = 0b00000001;  // RB0 como entrada

    xTaskCreate(vTASK0, "T0", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY+1), NULL);
    xTaskCreate(vTASK1, "T1", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY+1), NULL);
    xTaskCreate(vTASK2, "T2", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY+1), NULL);
    xTaskCreate(vTASK3, "T3", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY+1), NULL);
    xTaskCreate(vTASK4, "T4", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY+1), NULL);

    vTaskStartScheduler();

    for(;;);  // Não deve chegar aqui
}

Exercícios relacionados