/** * @file app_tasks.c * @brief FreeRTOS tasks: two LED blink tasks + one printf task, * inter-task communication via a message queue. */ #include "app_tasks.h" #include "bsp_led.h" #include "bsp_usart.h" #include #include "FreeRTOS.h" #include "task.h" #include "queue.h" #define LED1_PERIOD_MS 500 #define LED2_PERIOD_MS 1000 #define LOG_QUEUE_LENGTH 10 #define LED_TASK_STACK 1024 /* in words */ #define PRINT_TASK_STACK 1024 /* printf needs more stack */ #define LED_TASK_PRIO 2 #define PRINT_TASK_PRIO 3 static QueueHandle_t s_logQueue = NULL; /* Active log printing switch, default off (set via the CLI "log" command) */ static volatile uint8_t s_logEnabled = 0; /** * @brief Enable/disable active log printing from the LED tasks. */ void AppTasks_SetLogEnabled(uint8_t enable) { s_logEnabled = (enable != 0) ? 1 : 0; } /** * @brief Return the current log printing switch state. */ uint8_t AppTasks_GetLogEnabled(void) { return s_logEnabled; } /** * @brief Toggle LED1(PB0) every 500 ms, post a log message each time * (only when log printing is enabled). */ static void LedTask(void* argument) { LogMsg_t msg = {1, 0}; (void)argument; for (;;) { bsp_led_toggle(LED1_PORT, LED1_PIN); if (AppTasks_GetLogEnabled()) { msg.led_id = 1; msg.count++; xQueueSend(s_logQueue, &msg, 0); } vTaskDelay(pdMS_TO_TICKS(LED1_PERIOD_MS)); } } /** * @brief Toggle LED2(PA6) every 1000 ms, post a log message each time * (only when log printing is enabled). */ static void LedTask2(void* argument) { LogMsg_t msg = {2, 0}; (void)argument; for (;;) { bsp_led_toggle(LED2_PORT, LED2_PIN); if (AppTasks_GetLogEnabled()) { msg.led_id = 2; msg.count++; xQueueSend(s_logQueue, &msg, 0); } vTaskDelay(pdMS_TO_TICKS(LED2_PERIOD_MS)); } } /** * @brief Block on the log queue and printf every received message. */ static void PrintTask(void* argument) { LogMsg_t msg; (void)argument; for (;;) { if (xQueueReceive(s_logQueue, &msg, portMAX_DELAY) == pdPASS) { bsp_usart_tx_lock(); printf("LED%u toggled, count = %lu\n", (unsigned int)msg.led_id, (unsigned long)msg.count); bsp_usart_tx_unlock(); } } } /** * @brief Create the log queue and all application tasks. */ void AppTasks_CreateAll(void) { s_logQueue = xQueueCreate(LOG_QUEUE_LENGTH, sizeof(LogMsg_t)); xTaskCreate(LedTask, "LED1", LED_TASK_STACK, NULL, LED_TASK_PRIO, NULL); xTaskCreate(LedTask2, "LED2", LED_TASK_STACK, NULL, LED_TASK_PRIO, NULL); xTaskCreate(PrintTask, "PRINT", PRINT_TASK_STACK, NULL, PRINT_TASK_PRIO, NULL); }