#include <Arduino.h>
// Pinos e constantes
#define LED_ALARM_PIN 2
#define DEBUG_GPIO 4 // Para medir tempo de execução da Tarefa 1
// Períodos das tarefas
#define TASK_1_PERIOD 100
#define TASK_2_PERIOD 500
#define TASK_3_PERIOD 1000
// Tempos de execução simulados
#define TASK_1_EXEC_TIME 20
#define TASK_2_EXEC_TIME 50
#define TASK_3_EXEC_TIME 300
typedef struct {
const char *name;
TaskHandle_t handle;
uint32_t period_ms;
uint32_t exec_time_ms;
TickType_t last_wake_time;
UBaseType_t priority;
} RM_TaskControlBlock;
RM_TaskControlBlock tasks[3];
// ---------- Função Fibonacci ----------
unsigned long fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
// ---------- Tarefa 1: Monitoramento com LED e GPIO ----------
void task1_monitoramento(void *param) {
RM_TaskControlBlock *tcb = (RM_TaskControlBlock *) param;
tcb->last_wake_time = xTaskGetTickCount();
while (1) {
digitalWrite(DEBUG_GPIO, HIGH); // Sobe GPIO para medir início
int valorSimulado = random(0, 100);
if (valorSimulado > 70) {
digitalWrite(LED_ALARM_PIN, HIGH);
Serial.printf("[%lu ms] [T1] ALERTA! Valor crítico: %d\n", millis(), valorSimulado);
} else {
digitalWrite(LED_ALARM_PIN, LOW);
Serial.printf("[%lu ms] [T1] OK: %d\n", millis(), valorSimulado);
}
digitalWrite(DEBUG_GPIO, LOW); // Desce GPIO para medir fim
vTaskDelayUntil(&tcb->last_wake_time, pdMS_TO_TICKS(tcb->period_ms));
}
}
// ---------- Tarefa 2: Sensor Simulado + UART ----------
void task2_sensor_uart(void *param) {
RM_TaskControlBlock *tcb = (RM_TaskControlBlock *) param;
tcb->last_wake_time = xTaskGetTickCount();
while (1) {
// Simula distância entre 30cm e 150cm
float simulated_distance = random(300, 1500) / 10.0;
Serial.printf("[%lu ms] [T2] Distância simulada: %.1f cm\n", millis(), simulated_distance);
vTaskDelayUntil(&tcb->last_wake_time, pdMS_TO_TICKS(tcb->period_ms));
}
}
// ---------- Tarefa 3: Fibonacci + Carga Artificial ----------
void task3_fibonacci(void *param) {
RM_TaskControlBlock *tcb = (RM_TaskControlBlock *) param;
tcb->last_wake_time = xTaskGetTickCount();
while (1) {
int n = random(30, 32); // Fibonacci mais leve para evitar travamento total
unsigned long result = fibonacci(n);
Serial.printf("[%lu ms] [T3] Fibonacci(%d) = %lu\n", millis(), n, result);
// Simula carga artificial com laço vazio
for (volatile int j = 0; j < 500000; j++);
vTaskDelayUntil(&tcb->last_wake_time, pdMS_TO_TICKS(tcb->period_ms));
}
}
// ---------- Setup ----------
void setup() {
Serial.begin(115200);
delay(1000);
pinMode(LED_ALARM_PIN, OUTPUT);
pinMode(DEBUG_GPIO, OUTPUT);
digitalWrite(DEBUG_GPIO, LOW);
// Define tarefas com prioridades RM
tasks[0] = {"Monitoramento", NULL, TASK_1_PERIOD, TASK_1_EXEC_TIME, 0, 3}; // alta prioridade
tasks[1] = {"Sensor_UART", NULL, TASK_2_PERIOD, TASK_2_EXEC_TIME, 0, 2}; // média prioridade
tasks[2] = {"Historico", NULL, TASK_3_PERIOD, TASK_3_EXEC_TIME, 0, 1}; // baixa prioridade
xTaskCreate(task1_monitoramento, tasks[0].name, 2048, &tasks[0], tasks[0].priority, &tasks[0].handle);
xTaskCreate(task2_sensor_uart, tasks[1].name, 2048, &tasks[1], tasks[1].priority, &tasks[1].handle);
xTaskCreate(task3_fibonacci, tasks[2].name, 4096, &tasks[2], tasks[2].priority, &tasks[2].handle);
}
void loop() {
// FreeRTOS em controle total
}