Vehicle Control Unit 0.01
This is the c library for controlling the car.
Loading...
Searching...
No Matches
Classes | Macros | Functions | Variables
Scheduler.c File Reference
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "queue.h"
#include "../../Inc/Scheduler/Scheduler.h"
Include dependency graph for Scheduler.c:

Go to the source code of this file.

Classes

struct  ScheduledUpdateable
 
struct  WorkItem
 

Macros

#define WORK_QUEUE_SIZE   32
 
#define WORKER_STACK_SIZE   1024
 
#define WORKER_PRIORITY   (tskIDLE_PRIORITY + 2)
 

Functions

static void workerTask (void *pvParameters)
 
static void updateableTimerCallback (TimerHandle_t xTimer)
 
void SchedulerInit (Scheduler *scheduler, Updateable *updatableArray[])
 
void SchedulerRun (Scheduler *scheduler)
 
void SchedulerStop (Scheduler *scheduler)
 
void SchedulerSuspendUpdateable (const char *name)
 
void SchedulerResumeUpdateable (const char *name)
 
void SchedulerGetStats (void)
 
void SchedulerCleanup (void)
 

Variables

static ScheduledUpdateable scheduledTasks [MAX_SENSORS]
 
static int taskCount = 0
 
static TaskHandle_t workerTaskHandle = NULL
 
static QueueHandle_t workQueue = NULL
 

Macro Definition Documentation

◆ WORK_QUEUE_SIZE

#define WORK_QUEUE_SIZE   32

Definition at line 25 of file Scheduler.c.

◆ WORKER_PRIORITY

#define WORKER_PRIORITY   (tskIDLE_PRIORITY + 2)

Definition at line 27 of file Scheduler.c.

◆ WORKER_STACK_SIZE

#define WORKER_STACK_SIZE   1024

Definition at line 26 of file Scheduler.c.

Function Documentation

◆ SchedulerCleanup()

void SchedulerCleanup ( void  )

Definition at line 225 of file Scheduler.c.

225 {
226 // Delete worker task
227 if (workerTaskHandle != NULL) {
228 vTaskDelete(workerTaskHandle);
229 workerTaskHandle = NULL;
230 }
231
232 // Delete work queue
233 if (workQueue != NULL) {
234 vQueueDelete(workQueue);
235 workQueue = NULL;
236 }
237
238 // Delete all timers
239 for (int i = 0; i < taskCount; i++) {
240 if (scheduledTasks[i].timer != NULL) {
241 xTimerDelete(scheduledTasks[i].timer, portMAX_DELAY);
242 scheduledTasks[i].timer = NULL;
243 }
244 }
245
246 taskCount = 0;
247 printf("Scheduler cleaned up\n");
248}
static ScheduledUpdateable scheduledTasks[MAX_SENSORS]
Definition: Scheduler.c:18
static QueueHandle_t workQueue
Definition: Scheduler.c:23
static TaskHandle_t workerTaskHandle
Definition: Scheduler.c:22
static int taskCount
Definition: Scheduler.c:19
TimerHandle_t timer
Definition: Scheduler.c:9

◆ SchedulerGetStats()

void SchedulerGetStats ( void  )

Definition at line 202 of file Scheduler.c.

202 {
203 UBaseType_t queueLength = uxQueueMessagesWaiting(workQueue);
204 UBaseType_t queueSpaces = uxQueueSpacesAvailable(workQueue);
205
206 printf("Scheduler Statistics:\n");
207 printf("- Active timers: %d\n", taskCount);
208 printf("- Work queue: %lu items pending, %lu spaces available\n",
209 queueLength, queueSpaces);
210
211 if (workerTaskHandle != NULL) {
212 TaskStatus_t taskStatus;
213 vTaskGetInfo(workerTaskHandle, &taskStatus, pdTRUE, eInvalid);
214 printf("- Worker task stack high water mark: %u words\n",
215 taskStatus.usStackHighWaterMark);
216 }
217
218 if (queueLength > (WORK_QUEUE_SIZE * 3 / 4)) {
219 printf("WARNING: Work queue is %lu%% full - worker may be overloaded\n",
220 (queueLength * 100) / WORK_QUEUE_SIZE);
221 }
222}
#define WORK_QUEUE_SIZE
Definition: Scheduler.c:25

◆ SchedulerInit()

void SchedulerInit ( Scheduler scheduler,
Updateable updatableArray[] 
)

Definition at line 80 of file Scheduler.c.

80 {
81 scheduler->running = 0;
82 taskCount = 0;
83
84 // Create work queue for communicating between timer callbacks and worker task
85 workQueue = xQueueCreate(WORK_QUEUE_SIZE, sizeof(WorkItem));
86 if (workQueue == NULL) {
87 printf("ERROR: Failed to create work queue\n");
88 return;
89 }
90
91 // Create worker task to handle updateables
92 if (xTaskCreate(workerTask, "SchedulerWorker", WORKER_STACK_SIZE, NULL,
93 WORKER_PRIORITY, &workerTaskHandle) != pdPASS) {
94 printf("ERROR: Failed to create worker task\n");
95 return;
96 }
97
98 printf("Created scheduler worker task\n");
99
100 // Create timers for each updateable
101 for (int i = 0; updatableArray[i] != NULL && i < MAX_SENSORS; i++) {
102 Updateable* updateable = updatableArray[i];
103
104 if (updateable->hz <= 0 || updateable->hz > MAX_HZ) {
105 printf("Warning: Skipping %s - invalid frequency %d Hz\n",
106 updateable->name, updateable->hz);
107 continue;
108 }
109
110 // Calculate period in FreeRTOS ticks
111 TickType_t period = pdMS_TO_TICKS(1000 / updateable->hz);
112 if (period == 0) period = 1; // Minimum 1 tick for 1kHz tasks
113
114 // Create timer name
115 char timerName[32];
116 snprintf(timerName, sizeof(timerName), "T_%s", updateable->name);
117
118 // Create FreeRTOS software timer
119 TimerHandle_t timer = xTimerCreate(
120 timerName, // Timer name
121 period, // Period in ticks
122 pdTRUE, // Auto-reload (periodic)
123 updateable, // Timer ID
124 updateableTimerCallback // Callback function
125 );
126
127 if (timer != NULL) {
128 scheduledTasks[taskCount].updateable = updateable;
130 taskCount++;
131
132 printf("Created timer: %s at %dHz (period: %lu ticks)\n",
133 updateable->name, updateable->hz, period);
134 } else {
135 printf("ERROR: Failed to create timer for %s\n", updateable->name);
136 }
137 }
138
139 printf("Scheduler initialized with %d timers and worker task\n", taskCount);
140}
#define MAX_SENSORS
Definition: PriorityQueue.h:8
#define WORKER_STACK_SIZE
Definition: Scheduler.c:26
static void workerTask(void *pvParameters)
Definition: Scheduler.c:30
#define WORKER_PRIORITY
Definition: Scheduler.c:27
static void updateableTimerCallback(TimerHandle_t xTimer)
Definition: Scheduler.c:59
#define MAX_HZ
Definition: Scheduler.h:8
Updateable * updateable
Definition: Scheduler.c:8
int running
Definition: Scheduler.h:11
char name[MAX_NAME_LENGTH]
Definition: Updateable.h:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SchedulerResumeUpdateable()

void SchedulerResumeUpdateable ( const char *  name)

Definition at line 189 of file Scheduler.c.

189 {
190 for (int i = 0; i < taskCount; i++) {
191 if (scheduledTasks[i].updateable &&
192 strcmp(scheduledTasks[i].updateable->name, name) == 0) {
193 if (xTimerStart(scheduledTasks[i].timer, 0) == pdPASS) {
194 printf("Resumed timer for %s\n", name);
195 return;
196 }
197 }
198 }
199 printf("Warning: Could not find or resume timer for %s\n", name);
200}

◆ SchedulerRun()

void SchedulerRun ( Scheduler scheduler)

Definition at line 142 of file Scheduler.c.

142 {
143 scheduler->running = 1;
144
145 // Start all timers
146 int started = 0;
147 for (int i = 0; i < taskCount; i++) {
148 if (xTimerStart(scheduledTasks[i].timer, 0) == pdPASS) {
149 started++;
150 } else {
151 printf("ERROR: Failed to start timer for %s\n",
152 scheduledTasks[i].updateable->name);
153 }
154 }
155
156 printf("Started %d/%d timers\n", started, taskCount);
157
158 // Start FreeRTOS scheduler
159 vTaskStartScheduler();
160}
Here is the caller graph for this function:

◆ SchedulerStop()

void SchedulerStop ( Scheduler scheduler)

Definition at line 162 of file Scheduler.c.

162 {
163 scheduler->running = 0;
164
165 // Stop all timers
166 for (int i = 0; i < taskCount; i++) {
167 if (scheduledTasks[i].timer != NULL) {
168 xTimerStop(scheduledTasks[i].timer, portMAX_DELAY);
169 }
170 }
171
172 printf("All timers stopped\n");
173}

◆ SchedulerSuspendUpdateable()

void SchedulerSuspendUpdateable ( const char *  name)

Definition at line 176 of file Scheduler.c.

176 {
177 for (int i = 0; i < taskCount; i++) {
178 if (scheduledTasks[i].updateable &&
179 strcmp(scheduledTasks[i].updateable->name, name) == 0) {
180 if (xTimerStop(scheduledTasks[i].timer, 0) == pdPASS) {
181 printf("Suspended timer for %s\n", name);
182 return;
183 }
184 }
185 }
186 printf("Warning: Could not find or suspend timer for %s\n", name);
187}

◆ updateableTimerCallback()

static void updateableTimerCallback ( TimerHandle_t  xTimer)
static

Definition at line 59 of file Scheduler.c.

59 {
60 Updateable* updateable = (Updateable*)pvTimerGetTimerID(xTimer);
61
62 if (updateable != NULL && workQueue != NULL) {
63 WorkItem workItem = {
64 .updateable = updateable,
65 .timestamp = xTaskGetTickCount()
66 };
67
68 // Send to worker task (non-blocking from timer context)
69 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
70 if (xQueueSendFromISR(workQueue, &workItem, &xHigherPriorityTaskWoken) != pdTRUE) {
71 // Queue full - this indicates the worker task is overloaded
72 printf("ERROR: Work queue full for %s - dropping task\n", updateable->name);
73 }
74
75 // Yield if higher priority task was woken
76 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
77 }
78}
Updateable * updateable
Definition: Scheduler.c:14
Here is the caller graph for this function:

◆ workerTask()

static void workerTask ( void *  pvParameters)
static

Definition at line 30 of file Scheduler.c.

30 {
31 WorkItem workItem;
32
33 while (1) {
34 // Wait for work items from timer callbacks
35 if (xQueueReceive(workQueue, &workItem, portMAX_DELAY) == pdTRUE) {
36 if (workItem.updateable != NULL) {
37 // Record start time for performance monitoring
38 TickType_t startTime = xTaskGetTickCount();
39
40 // Execute the updateable
41 Task task;
42 TaskInit(&task, workItem.updateable, workItem.updateable->hz);
43 TaskExecute(&task);
44
45 // Check execution time
46 TickType_t executionTime = xTaskGetTickCount() - startTime;
47 TickType_t maxTime = pdMS_TO_TICKS(1000 / workItem.updateable->hz) / 2; // 50% of period
48
49 if (executionTime > maxTime) {
50 printf("WARNING: %s took %lu ticks (max recommended: %lu)\n",
51 workItem.updateable->name, executionTime, maxTime);
52 }
53 }
54 }
55 }
56}
void TaskInit(Task *task, Updateable *updateable, int hz)
Initializes a task with the given sensor and update frequency.
Definition: Task.c:3
void TaskExecute(Task *task)
Executes the task by calling the sensor's update function.
Definition: Task.c:9
Definition: Task.h:8
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ scheduledTasks

ScheduledUpdateable scheduledTasks[MAX_SENSORS]
static

Definition at line 18 of file Scheduler.c.

◆ taskCount

int taskCount = 0
static

Definition at line 19 of file Scheduler.c.

◆ workerTaskHandle

TaskHandle_t workerTaskHandle = NULL
static

Definition at line 22 of file Scheduler.c.

◆ workQueue

QueueHandle_t workQueue = NULL
static

Definition at line 23 of file Scheduler.c.