Mutexes no FreeRTOS: Exclusão Mútua e Herança de Prioridade
Os mutexes (mutual exclusions) são mecanismos fundamentais para garantir acesso exclusivo a recursos compartilhados entre múltiplas tasks. No FreeRTOS, mutexes são usados quando mais de uma thread pode acessar o mesmo recurso, como periféricos, buffers globais, estruturas de dados ou interfaces de comunicação, e esse acesso precisa ser serializado para evitar corrupção de dados.
Embora à primeira vista mutexes e semáforos pareçam semelhantes, no FreeRTOS eles possuem papéis conceituais distintos. O mutex foi projetado especificamente para proteção de recursos, enquanto o semáforo é um mecanismo de sincronização. Essa diferença se torna crítica ao analisarmos o suporte à herança de prioridade, presente apenas nos mutexes.
Herança de Prioridade
A herança de prioridade é um mecanismo automático que evita o problema clássico de inversão de prioridade. Esse problema ocorre quando:
- Uma task de baixa prioridade adquire um mutex.
- Uma task de alta prioridade tenta adquirir o mesmo mutex e bloqueia.
- Uma task de prioridade média passa a executar, impedindo a task de baixa prioridade de liberar o mutex.
No FreeRTOS, ao detectar essa situação, o kernel eleva temporariamente a prioridade da task que detém o mutex para a prioridade da task bloqueada mais alta, garantindo previsibilidade temporal.
Criação de um Mutex
#include "FreeRTOS.h"
#include "semphr.h"
SemaphoreHandle_t xUartMutex;
void vInit(void)
{
xUartMutex = xSemaphoreCreateMutex();
}
Uso de Mutex em uma Task
void vUartTask(void *pvParameters)
{
for (;;)
{
if (xSemaphoreTake(xUartMutex, portMAX_DELAY) == pdTRUE)
{
uart_send_string("Mensagem segura\n");
xSemaphoreGive(xUartMutex);
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
Quando usar Mutexes
Use mutexes quando:
- Um recurso físico ou lógico é compartilhado.
- O acesso deve ser exclusivo.
- Existe risco de inversão de prioridade.
- A mesma task sempre libera o recurso que adquiriu.
Evite mutexes quando:
- A sincronização é baseada em eventos, não em recursos.
- Uma ISR precisa sinalizar uma task (mutex não pode ser usado em ISR).
- O recurso não exige exclusividade estrita.
Vantagens Técnicas
- Proteção segura de recursos compartilhados.
- Herança de prioridade automática.
- Modelo claro de posse do recurso.
- Essencial em sistemas de tempo real determinísticos.
Armadilhas comuns
- Usar mutex como mecanismo de sinalização.
- Esquecer de liberar o mutex (deadlock).
- Criar dependências circulares entre mutexes.
- Bloquear por longos períodos segurando um mutex.
Um princípio prático importante: quanto menor o tempo segurando um mutex, melhor o comportamento temporal do sistema.
Na próxima seção, entraremos nos Semaphores, explicando semáforos binários e de contagem, suas diferenças em relação aos mutexes e quando cada um deve ser aplicado.