123 lines
2.8 KiB
C
123 lines
2.8 KiB
C
/**
|
|
* @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 <stdio.h>
|
|
|
|
#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 128 /* in words */
|
|
#define PRINT_TASK_STACK 256 /* 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);
|
|
}
|