Novo serviço do BRTOS: “soft timers”
Mais uma novidade do BRTOS… agora o BRTOS conta com um novo serviço: os timers em software (ou “soft timers”, ou apenas “timers”). Um “soft timer” permite executar uma função em um determinado tempo no futuro. Ainda, ele pode ser configurado para funcionar periodicamente, com período variável ou apenas uma única vez (“one shot”).
Muitas vezes em um projeto precisamos executar alguma função periodicamente (por exemplo, incrementar um contador de tempo ou gerar eventos temporizados).
Uma forma simples de se fazer isto no BRTOS é criar uma tarefa responsável por executar a função e colocá-la para esperar o próximo instante de tempo usando a função “DelayTask”. Entretanto, esta solução tem alguns inconvenientes. Por exemplo, se o número de funções periódicas aumentar será necessário criar uma nova tarefa para cada função (aumentando o consumo de memória), ou colocá-las todas na mesma tarefa (tornando-a mais complexa e mais difícil de manter e modificar).
Outra solução que o BRTOS disponibiliza é a utilização da função “TimerHook” chamada pelo sistema na interrupção “TickTimer”. Porém, esta solução também tem alguns inconvenientes, pois a função “TimerHook” é chamada a partir da interrupção e, portanto, torna o tempo de execução da interrupção maior, impactando na rapidez de resposta do sistema.
Uma solução mais eficiente do que as apresentadas é a utilização de uma tarefa específica para gerenciar a execução destas funções. Assim, no serviço de “soft timers” do BRTOS, existe uma tarefa chamada “Timer Task”, que organiza os “timers” de acordo com os respectivos tempos de disparo e só executa quando algum “timer” expira. Esta solução é bastante eficiente, pois não aumenta o tempo de processamento dentro da interrupção, nem ocupa mais processamento quando nenhum “timer” expira. Ainda, ela retira do programador o trabalho e a complexidade de gerenciar as funções, tornando o desenvolvimento mais rápido e seguro.
Como utilizar o serviço de “soft timers” do BRTOS.
O serviço de “soft timers” do BRTOS está implementado em dois arquivos (“timers.c e timers.h”). Para utilizar o serviço, o desenvolvedor deve incluir o arquivo “timers.h” na região de “#includes” em seu projeto, bem como, inserir a seguinte diretiva ao arquivo BRTOSConfig.h: “ #define BRTOS_TMR_EN 1”. Opcionalmente, o desenvolvedor pode definir a diretiva “BRTOS_MAX_TIMER” com um determinado valor que corresponde ao número máximo de “timers” que serão ocupados. Se a diretiva “BRTOS_MAX_TIMER” não for definida, o BRTOS utilizará o valor padrão BRTOS_MAX_TIMER_DEFAULT definido no arquivo “timers.h”.
A API do serviço é composta por cinco funções públicas:
- OSTimerInit
- OSTimerSet
- OSTimerGet
- OSTimerStart
- OSTimerStop
Antes de realizar qualquer chamada as demais funções, o desenvolvedor deverá realizar a chamada da função “OSTimerInit”, a qual é responsável por instalar a tarefa “Timer Task” e realizar as inicializações necessárias. Esta função possui dois parâmetros, que correspondem ao tamanho em bytes da pilha da tarefa e a prioridade da tarefa. O desenvolvedor deve passar o tamanho da pilha de acordo com o máximo uso de pilha que pode ser realizado pelas funções a serem executadas no disparo dos “timers”. Ainda, a prioridade da tarefa “Timer Task” deve ser passada pelo desenvolvedor e nenhuma outra tarefa pode ter a mesma prioridade.
Após inicializar corretamente o serviço, o desenvolvedor pode criar um “timer” através da função “OSTimerSet”. Esta função recebe três parâmetros obrigatórios: um ponteiro para uma variável do tipo BRTOS_TIMER declarada globalmente ou localmente, um ponteiro para a função que será executada quando o “timer” expirar, e o tempo de expiração do “timer” (em ticks). Se este último parâmetro for igual a zero, o “timer” será criado, porém não será disparado. Para dispará-lo será necessário que o desenvolvedor realize uma chamada à função “OSTimerStart” com a identificação do “timer” e do tempo de expiração.
A função que será executada na expiração do “timer” é comumente denominada função de “callback”. Esta função possui um formato pré-definido que deve ser seguido pelo desenvolvedor. A função deve ter um protótipo como “TIMER_CNT nome_da_funcao (void)”, implicando que ela não recebe nenhum parâmetro e deve retornar um parâmetro do tipo “TIMER_CNT”. O retorno da função é obrigatório e é utilizado para informar ao sistema o próximo tempo de expiração do “timer”. Assim é possível se ter “timers” com períodos constantes ou variáveis. Ainda, se o desenvolvedor retornar “0”, indica ao sistema que o “timer” não será mais utilizado (“one-shot”) e, portanto, será apagado.
Embora as funções de “callback” sejam executadas dentro do contexto da tarefa “TimerTask”, é importante que o desenvolvedor não faça chamadas aos serviços do sistema que possam bloquear a tarefa, pois isso impedirá a execução dos demais “timers”.
Se o desenvolvedor desejar parar um “timer”, pode-se fazer uma chamada à função “OSTimerStop” contendo a identificação do “timer”. O segundo parâmetro da função indica ao sistema se o desenvolvedor deseja apagar o “timer” (liberar a memória para uso por outro “timer”). Se o segundo parâmetro da função for qualquer valor maior do que zero, o sistema apagará o “timer”.
Outra função útil ao desenvolvedor é a função “OSTimerGet” que retorna o tempo que falta (em ticks) para que um determinado “timer” expire. A identificação do “timer” é passada como parâmetro da função.
Um projeto de demonstração utilizando o serviço de “soft timers” do BRTOS está disponível no site do projeto: http://code.google.com/p/brtos/downloads/list.
Show de bola!
Ótima adição.. parabéns