#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "stm32c0xx_hal.h"
#include <stdio.h>
// Définition des pins pour les LEDs
#define LED1_PIN GPIO_PIN_5
#define LED2_PIN GPIO_PIN_6
#define LED_PORT GPIOA
// Déclaration du mutex
SemaphoreHandle_t uartMutex;
// Fonction pour simuler l'envoi de messages UART
void UART_Send(const char *message) {
printf("%s", message); // Utilisation de printf pour envoyer via UART (Wokwi fait la redirection automatiquement)
}
// Tâche 1 - Envoie un message et contrôle les LEDs
void UART_Task1(void *pvParameters) {
for (;;) {
// ------------------- À compléter -------------------
// Acquérir le mutex pour protéger l'accès à la ressource partagée (UART)
if (xSemaphoreTake(uartMutex, portMAX_DELAY)) {
// Envoyer un message via UART
UART_Send("Task 1: Hello from UART!\r\n");
// Allumer LED1
HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_SET);
vTaskDelay(pdMS_TO_TICKS(500)); // LED1 allumée pendant 500ms
// Éteindre LED1
HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_RESET);
// ------------------- À compléter -------------------
// Libérer le mutex après utilisation
xSemaphoreGive(uartMutex);
}
vTaskDelay(pdMS_TO_TICKS(1000)); // Pause de 1 seconde
}
}
// Tâche 2 - Envoie un message et contrôle les LEDs
void UART_Task2(void *pvParameters) {
for (;;) {
// ------------------- À compléter -------------------
// Acquérir le mutex pour protéger l'accès à la ressource partagée (UART)
if (xSemaphoreTake(uartMutex, portMAX_DELAY)) {
// Envoyer un message via UART
UART_Send("Task 2: Message from UART\r\n");
// Allumer LED2
HAL_GPIO_WritePin(LED_PORT, LED2_PIN, GPIO_PIN_SET);
vTaskDelay(pdMS_TO_TICKS(500)); // LED2 allumée pendant 500ms
// Éteindre LED2
HAL_GPIO_WritePin(LED_PORT, LED2_PIN, GPIO_PIN_RESET);
// ------------------- À compléter -------------------
// Libérer le mutex après utilisation
xSemaphoreGive(uartMutex);
}
vTaskDelay(pdMS_TO_TICKS(1500)); // Pause de 1,5 seconde
}
}
void MX_GPIO_Init(void) {
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
// Initialiser LED1 (Pin 5)
GPIO_InitStruct.Pin = LED1_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
// Initialiser LED2 (Pin 6)
GPIO_InitStruct.Pin = LED2_PIN;
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
}
int main(void) {
HAL_Init();
MX_GPIO_Init(); // Initialisation des GPIOs pour les LEDs
// ------------------- À compléter -------------------
// Créer un mutex pour protéger l'accès à l'UART
uartMutex = xSemaphoreCreateMutex();
if (uartMutex != NULL) {
// ------------------- À compléter -------------------
// Créer les tâches UART_Task1 et UART_Task2 avec des priorités différentes
xTaskCreate(UART_Task1, "UART Task 1", 256, NULL, 1, NULL); // Priorité 1 pour Task 1
xTaskCreate(UART_Task2, "UART Task 2", 256, NULL, 2, NULL); // Priorité 2 pour Task 2
// Démarrer le scheduler FreeRTOS
vTaskStartScheduler();
}
// Si le système arrive ici, cela signifie que la mémoire est insuffisante
while (1) {
}
}