- RTOS: Um ambiente multi-tarefas para Sistemas Embarcados
- RTOS: Scheduler e Tarefas
- RTOS: Semáforos para sincronização de tarefas
- RTOS: Uso de Queue para sincronização e comunicação de tarefas
- RTOS: Uso de grupo de eventos para sincronização de tarefas
- RTOS: Software Timer no FreeRTOS
Os semáforos que vimos no artigo anterior permitem a sincronização de tarefas e uma simples comunicação entre elas com apenas valores binários. Mas se seu projeto precisa de algo mais complexo para sincronização ou comunicação entre tarefas e ISRs, pode ser a vez da Queue.
O que é uma Queue e como funciona?
Queue é um buffer, uma fila de dados no formato FIFO, que permite sincronização de tarefas, como vimos em semáforos, porém é mais utilizada para comunicação entre tarefas e ISRs onde precisamos enviar valores (variáveis) para outros lugares. Usar queues visa a diminuição de variáveis globais em seu código. Mesmo ele sendo um objeto global, conta com métodos de atomicidade e timeout que podem agregar uma dinâmica muito interessante em seu projeto e produto.
A queue funciona na forma de um buffer FIFO, mas há funções que permitem escrever no começo do buffer em vez de apenas no fim. É tão simples que com a figura 3 já podemos entender o funcionamento da queue e testar na prática!
As queues do FreeRTOS são objetos com capacidade e comprimento fixo. Como o exemplo da figura 3, a queue foi criada com 5 “espaços” (slots) e 2 bytes por slot. Isso implica na forma e frequência em que a queue será utilizada. Ela deve atender o tamanho máximo de suas variáveis e também ter comprimento considerável para evitar que fique lotada (a menos que seja proposital, como nas “MailBox”). Apesar da queue também funcionar para sincronização de tarefas como vimos em semáforos, o foco dessa prática será unicamente na transferência de dados entre duas tarefas. Então vamos começar!
Código do projeto:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
#include <driver/gpio.h> #include <freertos/FreeRTOS.h> #include <freertos/task.h> #include <freertos/semphr.h> #include <esp_system.h> #include <esp_log.h> QueueHandle_t buffer;//Objeto da queue void t1(void*z) { uint32_t snd = 0; while(1) { if (snd < 15)//se menor que 15 { xQueueSend(buffer, &snd, pdMS_TO_TICKS(0));//Envia a variavel para queue snd++;//incrementa a variavel } else//se nao, espera 5seg para testar o timeout da outra tarefa { vTaskDelay(pdMS_TO_TICKS(5000)); snd = 0; } vTaskDelay(pdMS_TO_TICKS(500)); } } void t2(void*z) { uint32_t rcv = 0; while(1) { if (xQueueReceive(buffer, &rcv, pdMS_TO_TICKS(1000)) == true)//Se recebeu o valor dentro de 1seg (timeout), mostrara na tela { ESP_LOGI("Queue", "Item recebido: %u", rcv);//Mostra o valor recebido na tela } else { ESP_LOGE("Queue", "Item nao recebido, timeout expirou!");//Se o timeout expirou, mostra erro } } } void app_main() { buffer = xQueueCreate(10, sizeof(uint32_t));//Cria a queue *buffer* com 10 slots de 4 Bytes xTaskCreatePinnedToCore(t1, "t1", 4096, NULL, 1, NULL, 0);//Cria a tarefa que escreve valores na queue xTaskCreatePinnedToCore(t2, "t2", 4096, NULL, 1, NULL, 0);//Cria a tarefa que le valores da queue } |
Testando o código, podemos observar que enquanto a tarefa responsável por enviar variáveis (t1) envia valores abaixo de 15, a outra tarefa (t2) mostra o valor recebido na tela. Porém, quando t1 chega no número 15, entra em delay por 5 segundos, ocasionando no timeout da leitura na t2, mostrando na tela que o timeout de 1 segundo expirou.
Queues podem tanto funcionar como um tipo especial de semáforos, onde podemos analisar valores recebidos e sincronizar tarefas a partir disso, como também, e principalmente, efetuar a comunicação entre tarefas e ISRs.
Saiba mais
Desenvolvendo com o Zephyr RTOS: Controlando o Kernel
Primeiras impressões com o react.o
Fila circular para sistemas embarcados
Referências
Bom dia, José Morais, como faço para entrar em contato com você?
Pode me chamar no Telegram/Whatsapp (14) 998202683
Opa. Morais, blzz cara!!! ?
Cara continuar nessa abordagem de fila, acredito que tenha bastante assunto para abordar ainda. Eu venho acompanhando seus posts e acho muito significativo. Parabéns pela iniciativa. CONTINUA!!!!!!!
Opa! O plano inicial era parar por aqui, mas acho que vou continuar com “eventos”, “software timer” e assim por diante…
Show de bola cara. VLWW
Não para não, está muito interessante! Está muito bom!!