4. 3.3 Mutex — protection des ressources partagées
Un mutex est un sémaphore binaire avec ownership. La tâche qui prend le mutex doit le rendre. Indispensable pour protéger un périphérique partagé (bus I2C, SPI, UART, buffer global).
Différence critique : un sémaphore binaire peut être donné par n'importe qui. Un mutex ne peut être rendu que par la tâche qui l'a pris. FreeRTOS ajoute l'héritage de priorité pour les mutex (voir Module 4, priority inversion).
SemaphoreHandle_t xMutexI2C = xSemaphoreCreateMutex();
void task_display(void *pv) {
while (1) {
if (xSemaphoreTake(xMutexI2C, pdMS_TO_TICKS(100)) == pdTRUE) {
ssd1306_update_screen(); // accès exclusif au bus I2C
xSemaphoreGive(xMutexI2C);
}
vTaskDelay(pdMS_TO_TICKS(200));
}
}
void task_sensor(void *pv) {
while (1) {
if (xSemaphoreTake(xMutexI2C, pdMS_TO_TICKS(100)) == pdTRUE) {
float lux = bh1750_read(); // même bus I2C
xSemaphoreGive(xMutexI2C);
xQueueSend(xQueueLight, &lux, 0);
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
Règles d'or :
- Ne jamais appeler xSemaphoreTake d'un mutex depuis une ISR → utiliser sémaphore binaire + xSemaphoreGiveFromISR
- Toujours rendre le mutex (xSemaphoreGive) même en cas d'erreur
- Section critique minimale : prendre → opération → rendre, aussi vite que possible