#include <Arduino.h> // Wokwi uses Arduino framework by default for STM32
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h" // For software timers (optional for this project, but good to include)
// --- GPIO Definitions for Nucleo-C031C6 ---
// Onboard User LED (usually PA5)
#define LED1_PIN PA5
// External LED (connected to PB1 in Wokwi diagram)
#define LED2_PIN PB1
// --- Task Definitions ---
#define LED1_BLINK_PERIOD_MS 250 // 250ms on, 250ms off (500ms cycle)
#define LED2_BLINK_PERIOD_MS 750 // 750ms on, 750ms off (1500ms cycle)
// Task Handle (optional, but useful if you need to refer to the task later)
TaskHandle_t xLed1BlinkTaskHandle = NULL;
TaskHandle_t xLed2BlinkTaskHandle = NULL;
// --- Task Function Prototypes ---
void vLed1BlinkTask(void *pvParameters);
void vLed2BlinkTask(void *pvParameters);
// --- Main Setup Function (Arduino-like setup() from Wokwi) ---
void setup() {
Serial.begin(115200); // Initialize serial for debugging if needed
Serial.println("STM32 Nucleo-C031C6 FreeRTOS LED Blink");
// Configure LED pins as OUTPUT
pinMode(LED1_PIN, OUTPUT);
pinMode(LED2_PIN, OUTPUT);
// Create tasks
// xTaskCreate( TaskFunction_t pvTaskCode,
// const char *const pcName,
// const uint16_t usStackDepth,
// void *const pvParameters,
// UBaseType_t uxPriority,
// TaskHandle_t *const pxCreatedTask );
xTaskCreate(
vLed1BlinkTask, // Task function
"LED1_Blink", // Name of task
128, // Stack size (words)
NULL, // Parameters to pass to task
tskIDLE_PRIORITY + 2,// Task priority (higher than LED2)
&xLed1BlinkTaskHandle // Task handle
);
xTaskCreate(
vLed2BlinkTask, // Task function
"LED2_Blink", // Name of task
128, // Stack size (words)
NULL, // Parameters to pass to task
tskIDLE_PRIORITY + 1,// Task priority (lower than LED1)
&xLed2BlinkTaskHandle // Task handle
);
// The FreeRTOS scheduler is started automatically by Wokwi's underlying framework
// You don't usually call vTaskStartScheduler() explicitly in Wokwi's setup()
// as it's handled by the Arduino core for STM32.
}
// --- Task Implementations ---
// Task to blink LED1 (onboard LED)
void vLed1BlinkTask(void *pvParameters) {
TickType_t xLastWakeTime;
const TickType_t xFrequency = pdMS_TO_TICKS(LED1_BLINK_PERIOD_MS);
// Initialise the xLastWakeTime variable with the current tick count.
xLastWakeTime = xTaskGetTickCount();
for (;;) {
// Toggle the LED
digitalWrite(LED1_PIN, !digitalRead(LED1_PIN)); // Toggle
// Wait for the next cycle
vTaskDelayUntil(&xLastWakeTime, xFrequency);
}
}
// Task to blink LED2 (external LED)
void vLed2BlinkTask(void *pvParameters) {
TickType_t xLastWakeTime;
const TickType_t xFrequency = pdMS_TO_TICKS(LED2_BLINK_PERIOD_MS);
// Initialise the xLastWakeTime variable with the current tick count.
xLastWakeTime = xTaskGetTickCount();
for (;;) {
// Toggle the LED
digitalWrite(LED2_PIN, !digitalRead(LED2_PIN)); // Toggle
// Wait for the next cycle
vTaskDelayUntil(&xLastWakeTime, xFrequency);
}
}
// --- Loop Function (empty as FreeRTOS takes over) ---
void loop() {
// FreeRTOS scheduler takes control. This loop should ideally never be reached.
// If you are using Wokwi with Arduino framework, sometimes things can still
// be put here for simple non-RTOS logic, but for FreeRTOS, tasks handle it.
vTaskDelay(1); // Give up control to FreeRTOS scheduler just in case
}