Hook Functions no FreeRTOS: Idle Hook vs Tick Hook
As Hook Functions no FreeRTOS são pontos de extensão controlados do kernel, projetados para permitir que o desenvolvedor insira código customizado sem modificar o núcleo do sistema operacional. Entre todas as hooks disponíveis, duas são particularmente relevantes para arquitetura, desempenho e consumo de energia: a Idle Hook e a Tick Hook. Embora ambas sejam callbacks fornecidos pelo usuário, elas possuem propósitos, contextos de execução e restrições completamente diferentes.
A Idle Hook (vApplicationIdleHook) é chamada no contexto da Idle Task, ou seja, no contexto de tarefa normal, porém com a menor prioridade do sistema. Ela só é executada quando nenhuma outra tarefa está pronta, o que a torna ideal para atividades que só devem ocorrer durante períodos de ociosidade. Já a Tick Hook (vApplicationTickHook) é chamada dentro da interrupção do SysTick (ou do timer de tick configurado), ou seja, em contexto de interrupção.
Para habilitar a Tick Hook, é necessário definir no FreeRTOSConfig.h:
#define configUSE_TICK_HOOK 1
E implementar a função:
void vApplicationTickHook(void)
{
/* Código do usuário */
}
A diferença de contexto muda completamente as regras de uso. Na Tick Hook, como o código é executado em ISR (Interrupt Service Routine), aplicam-se todas as restrições típicas de interrupções:
- Não é permitido chamar funções do FreeRTOS que não sejam ISR-safe.
- Só podem ser usadas funções com sufixo
FromISR, comoxQueueSendFromISR(). - O código deve ser o mais curto possível, evitando qualquer processamento pesado.
- Não é permitido bloquear ou esperar por eventos.
Um exemplo correto de uso da Tick Hook é o envio de um sinal periódico para uma tarefa, usando uma notificação:
void vApplicationTickHook(void)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTaskNotifyFromISR(
monitorTaskHandle,
0x01,
eSetBits,
&xHigherPriorityTaskWoken
);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
Esse padrão é comum quando se deseja criar um time base preciso, sincronizado com o tick do sistema, sem criar timers de software adicionais.
Em contraste, a Idle Hook não deve ser usada para sinalização periódica, justamente porque sua execução não é determinística no tempo. Se o sistema estiver ocupado, a Idle Hook simplesmente não será chamada. Portanto, qualquer lógica que dependa de periodicidade fixa deve ser implementada via Tick Hook, software timers ou tarefas dedicadas.
Do ponto de vista de Low Power, a diferença também é significativa. A Idle Hook é o local natural para executar instruções como WFI ou iniciar transições para modos de baixo consumo, pois ela reflete um estado real de inatividade do sistema. Já a Tick Hook, por estar associada a uma interrupção periódica, tende a impedir o processador de dormir por longos períodos, sendo um dos fatores que motivaram a criação do Tickless Idle.
Em termos arquiteturais, podemos resumir a distinção da seguinte forma:
- Idle Hook → Ociosidade real, contexto de tarefa, ideal para economia de energia.
- Tick Hook → Base temporal fixa, contexto de interrupção, ideal para sincronização e temporização fina.
Com essa distinção clara, estamos prontos para avançar para o tema central da economia de energia no FreeRTOS: o Low Power integrado ao kernel, começando pelo conceito de Tickless Idle, que redefine completamente a forma como o sistema lida com períodos de inatividade prolongada.