RTOS

Escrito por Gabriel Aleksandravicius

Apresentação#

O propósito dessa página é:

  • Apresentar multitasking com Arduino vanilla
  • Apresentar conceito de RTOS
    • Definir sistema operacional
    • Definir multitasking
    • Fornecer casos de uso
  • Comparar esses dois conceitos, trazendo vantagens e desvantagens deles
    • Concluir se é válido implementar RTOS nos nossos projetos
  • Avaliar RTOS que podemos implementar e como fazê-lo
    • RTOS + state machine

Multitasking no Arduino vanilla#

Quando começamos nosso aprendizado com Arduino, geralmente realizamos tarefas simples e vamos tornando-a mais complexa com o tempo. Começamos com o 'hello world' do mundo dos embarcados, que é piscar um LED em uma frequência determinada. Depois, adicionamos mais LEDs. Em seguida podemos testar outras coisas, como atuar um servo ou fazer leituras com um sensor. Por fim, o próximo desafio é, naturalmente, testar fazer tudo isso ao mesmo tempo. E como fazemos isso?

Pra responder a essa pergunta, vejamos um exemplo mais simples: como piscar dois leds em frequências diferentes.

Piscando com delay()#

O código básico dentro de loop() para piscar um LED se parece com isso:

void loop() {
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led, LOW);
delay(1000);
}

Piscando sem delay()#

Essa estrutura é factível para códigos simples, porém um grande problema reside no uso da função delay(): ela interrompe a execução de praticamente qualquer outro bloco de código. Portanto, não podemos piscar dois LEDs com frequências diferentes.

A solução fornecida na própria documentação do Arduino é a seguinte:

// Blink without delay
int red = 5;
int blue = 7;
unsigned long previousTimeRed;
unsigned long previousTimeBlue;
unsigned long intervalRed = 1000;
unsigned long intervalBlue = 500;
int ledStateRed = LOW;
int ledStateBlue = LOW;
void setup() {
pinMode(red, OUTPUT);
pinMode(blue, OUTPUT);
}
void loop() {
unsigned long currentTime = millis();
// interval/2 = intervalo do blink (acende e apaga)
if (currentTime - previousTimeRed >= (intervalRed/2)) {
previousTimeRed = currentTime;
if (ledStateRed == LOW) {
ledStateRed = HIGH;
} else {
ledStateRed = LOW;
}
digitalWrite(red, ledStateRed);
}
if (currentTime - previousTimeBlue >= (intervalBlue/2)) {
previousTimeBlue = currentTime;
if (ledStateBlue == LOW) {
ledStateBlue = HIGH;
} else {
ledStateBlue = LOW;
}
digitalWrite(blue, ledStateBlue);
}
}

Deixamos de usar a função delay() e, no lugar, implementamos a contagem de tempo com millis(). Temos uma variável global, intervalRed, responsável por determinar o intervalo do LED vermelho. Também temos uma variável responsável por armazenar o último momento em que o LED mudou de estado (previousTimeRed) e uma variável para armazenar o estado (ledStateRed). O mesmo vale para o outro LED. Dentro de loop() a função millis() é chamada e seu valor de retorno (quantidade de tempo passado desde o início do programa) é armazenado em currentTime. O bloco de código a seguir faz a verificação do tempo, checando se o tempo passado desde a última mudança de estado já é maior ou igual ao intervalo pré-estabelecido pro LED. Se sim, o estado do LED é alterado.

dica

Embora tenha resolvido o problema do delay, o código ficou muito repetitivo dessa forma. Veja uma solução mais elegante aqui.

Multitasking com RTOS#

A solução empregada no tópico anterior é válida e muito pode ser feito seguindo o mesmo princípio - poderíamos trocar os LEDs por sensores que fazem a leitura em frequências diferentes, por exemplo. Então por que usar um RTOS? Pra responder a isso, primeiro vejamos o que é um RTOS.

O que é um RTOS?#

Por que usar um sistema operacional?#

Exemplo#

Referências#