2 Comentários

RTOS: Uso de grupo de eventos para sincronização de tarefas

FreeRTOS oferece, além dos 2 métodos anteriores para comunicação e sincronização de tarefas, os grupos de eventos (abreviando para G.E.). Um G.E. pode armazenar diversos eventos (flags) e, com isso, podemos deixar uma tarefa em espera (estado bloqueado) até que um ou vários eventos específicos ocorram.

O que é e como funciona um grupo de eventos?

Antes de entender um grupo de eventos, vamos relembrar o que são eventos (flags ou bandeiras). Flags são variáveis (normalmente binárias) que indicam quando algo ocorreu ou não, como por exemplo:

  1. Um sensor ativa uma flag ao término de sua leitura;
  2. Uma interrupção atribuída a um botão ativa uma flag indicando que ele foi pressionado.

Sendo assim, nosso embarcado pode ter muitas flags indicando diferentes coisas para que possamos tomar atitudes de acordo com a ocorrência delas.

Os G.E são variáveis de 16 ou 32 bits (definido pelo usuário) onde cada bit é uma flag específica indicando que algo ocorreu ou não. Nos nossos exemplos, usaremos os grupos de eventos de 32 bits, sendo 24 bits de uso livre e 8 reservados. Já que cada objeto do grupo de eventos permite manipular até 24 eventos diferentes, dependendo do tamanho do seu projeto, pode-se economizar uma preciosa quantidade de memória RAM, comparado com o uso de semáforos binários ou queues para cada evento.

Veja um exemplo das flags em um grupo de eventos na figura 1 abaixo:

Exemplo de flags em um grupo de eventos.
Figura 1 – Exemplo de flags em um grupo de eventos.

Diferentemente dos semáforos e queues, um grupo de eventos tem algumas características importantes:

  1. Podemos acordar as tarefas com combinação de uma ou várias flags diferentes;
  2. Reduz o consumo de memória RAM se comparado quando usado vários semáforos binários ou queues para sincronização;
  3. Todas as tarefas que estão esperando (estado bloqueado) pelas flags, são desbloqueadas, funcionando como uma “mensagem broadcast” e não apenas a de maior prioridade, como acontece com os semáforos e queues. Vamos observar essa importante característica nas figuras 2 e 3.

Na figura 2, duas tarefas (T1 e T2) esperam pelo mesmo semáforo binário (ou queue) para executar certa ação. Entretanto, quando a tarefa (Main) libera o semáforo para uso, apenas a tarefa de maior prioridade (T2) obtém o semáforo, causando Starvation na tarefa (T1), já que ela nunca será executada.

Tarefas esperando pelo mesmo semáforo.
Figura 2 – Tarefas esperando pelo mesmo semáforo.

Na figura 3 abaixo, há a mesma lógica porém com grupo de eventos, que desbloqueia todas tarefas (broadcast) e não apenas a de maior prioridade. Este detalhe é muito importante quando você pretende ter mais de uma tarefa esperando pelo mesmo item.

Tarefas esperando pelo mesmo evento.
Figura 3 – Tarefas esperando pelo mesmo evento.

Como já foi dito, um grupo de eventos é um conjunto de bits onde cada um tem seu significado específico, logo, precisamos entender o básico sobre manipulação de bits na linguagem C e você pode aprender mais vendo este ótimo artigo do Fábio Souza aqui. Vamos testar um G.E. na prática, onde uma tarefa espera por um flag para executar sua rotina.

Código do projeto:

Testando esse simples código, podemos ver que é praticamente idêntico ao funcionamento dos semáforos e queues, porém, como foi dito anteriormente, podemos manter a tarefa bloqueada por um ou mais eventos e isso é feito através de uma pequena lógica, veja a seguir.

Vamos resumir e apenas mostrar a parte onde definimos os eventos e a função que os aguarda.

Com o 4º parâmetro da função em true, a função irá esperar, durante 1 segundo, até que todos os três eventos fiquem valendo 1. Se qualquer um dos três não ocorrer dentro do tempo limite, a função retornará apenas após o tempo limite.

Além disso, temos mais uma possibilidade que é configurar a função para esperar por  qualquer um dos três e não mais todos os três juntos, veja abaixo:

Com o 4º parâmetro da função em false, a função irá esperar, durante 1 segundo, por qualquer um dos três eventos. Se qualquer um dos três eventos ocorrer, a função retornará, imediatamente.

A função sempre retorna o valor atual do grupo de eventos, logo, você precisa aplicar máscaras binárias para descobrir se o evento específico ocorreu. O artigo citado acima do Fábio Souza, pode te ajudar a entender máscaras binárias!

Os grupos de eventos são muito importantes em diversos ecossistemas, já que permite a propagação global de eventos (broadcast) por todas tarefas. Muito similar aos semáforos e queues, é de importância para qualquer projetista que pretende seguir com RTOS.

Saiba mais

Desenvolvendo com o Zephyr RTOS: Controlando o Kernel

Primeiras impressões com o react.o

Fila circular para sistemas embarcados

Referências

https://www.freertos.org/event-groups-API.html
https://freertos.org/Documentation/RTOS_book.html
http://esp-idf.readthedocs.io/en/latest/api-reference/system/freertos.html

Outros artigos da série

<< RTOS: Uso de Queue para sincronização e comunicação de tarefasRTOS: Software Timer no FreeRTOS >>
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Software » RTOS: Uso de grupo de eventos para sincronização de tarefas
Comentários:
Notificações
Notificar
guest
2 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Yuri Lima
Yuri Lima
19/09/2018 11:01

Show de bola, Jose Morais. Esses conteúdos estão cada vez melhores. Parabéns!!!

José Morais
José Morais
Reply to  Yuri Lima
19/09/2018 16:12

hehe, obrigado Yuri!

Talvez você goste:

Séries



Outros da Série

Menu

WEBINAR
 
Porque o RTOS não faz o que eu quero?

Data: 28/10 às 19:30h - Apoio: Mouser Electronics
 
INSCREVA-SE AGORA »



 
close-link