Skip to content

Instantly share code, notes, and snippets.

@Gavinok
Last active March 29, 2023 23:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gavinok/426f3e6c8dda8e1947f9673fc4f90463 to your computer and use it in GitHub Desktop.
Save Gavinok/426f3e6c8dda8e1947f9673fc4f90463 to your computer and use it in GitHub Desktop.
/*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
***************************************************************************
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
***************************************************************************
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wwrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
/*
FreeRTOS is a market leading RTOS from Real Time Engineers Ltd. that supports
31 architectures and receives 77500 downloads a year. It is professionally
developed, strictly quality controlled, robust, supported, and free to use in
commercial products without any requirement to expose your proprietary source
code.
This simple FreeRTOS demo does not make use of any IO ports, so will execute on
any Cortex-M3 of Cortex-M4 hardware. Look for TODO markers in the code for
locations that may require tailoring to, for example, include a manufacturer
specific header file.
This is a starter project, so only a subset of the RTOS features are
demonstrated. Ample source comments are provided, along with web links to
relevant pages on the http://www.FreeRTOS.org site.
Here is a description of the project's functionality:
The main() Function:
main() creates the tasks and software timers described in this section, before
starting the scheduler.
The Queue Send Task:
The queue send task is implemented by the prvQueueSendTask() function.
The task uses the FreeRTOS vTaskDelayUntil() and xQueueSend() API functions to
periodically send the number 100 on a queue. The period is set to 200ms. See
the comments in the function for more details.
http://www.freertos.org/vtaskdelayuntil.html
http://www.freertos.org/a00117.html
The Queue Receive Task:
The queue receive task is implemented by the prvQueueReceiveTask() function.
The task uses the FreeRTOS xQueueReceive() API function to receive values from
a queue. The values received are those sent by the queue send task. The queue
receive task increments the ulCountOfItemsReceivedOnQueue variable each time it
receives the value 100. Therefore, as values are sent to the queue every 200ms,
the value of ulCountOfItemsReceivedOnQueue will increase by 5 every second.
http://www.freertos.org/a00118.html
An example software timer:
A software timer is created with an auto reloading period of 1000ms. The
timer's callback function increments the ulCountOfTimerCallbackExecutions
variable each time it is called. Therefore the value of
ulCountOfTimerCallbackExecutions will count seconds.
http://www.freertos.org/RTOS-software-timer.html
The FreeRTOS RTOS tick hook (or callback) function:
The tick hook function executes in the context of the FreeRTOS tick interrupt.
The function 'gives' a semaphore every 500th time it executes. The semaphore
is used to synchronise with the event semaphore task, which is described next.
The event semaphore task:
The event semaphore task uses the FreeRTOS xSemaphoreTake() API function to
wait for the semaphore that is given by the RTOS tick hook function. The task
increments the ulCountOfReceivedSemaphores variable each time the semaphore is
received. As the semaphore is given every 500ms (assuming a tick frequency of
1KHz), the value of ulCountOfReceivedSemaphores will increase by 2 each second.
The idle hook (or callback) function:
The idle hook function queries the amount of free FreeRTOS heap space available.
See vApplicationIdleHook().
The malloc failed and stack overflow hook (or callback) functions:
These two hook functions are provided as examples, but do not contain any
functionality.
*/
/* Standard includes. */
#include <stdint.h>
#include <stdio.h>
#include "stm32f4_discovery.h"
/* Kernel includes. */
#include "stm32f4xx.h"
#include "../FreeRTOS_Source/include/FreeRTOS.h"
#include "../FreeRTOS_Source/include/queue.h"
#include "../FreeRTOS_Source/include/semphr.h"
#include "../FreeRTOS_Source/include/task.h"
#include "../FreeRTOS_Source/include/timers.h"
#include "taskheader.h"
/*-----------------------------------------------------------*/
xQueueHandle xQueue_toDDS = 0;
xQueueHandle xQueue_fromDDS = 0;
xQueueHandle xQueue_toGenerator = 0;
xTimerHandle xTimer_Task1 = 0;
xTimerHandle xTimer_Task2 = 0;
xTimerHandle xTimer_Task3 = 0;
/*-----------------------------------------------------------*/
typedef enum Found { FOUND, NOT_FOUND } Found;
typedef struct MaybeFound {
Found found;
DD_Task_List **list;
} MaybeFound;
DD_Task_List *newNode(TaskHandle_t t_handle, enum task_type type,
uint32_t task_id, uint32_t release_time,
uint32_t absolute_deadline, uint32_t completion_time) {
DD_Task t =
(DD_Task){t_handle, type, task_id, release_time,
absolute_deadline, completion_time};
DD_Task_List *val = (DD_Task_List *)pvPortMalloc(sizeof(DD_Task_List));
val->task = t;
val->next_task = NULL;
return val;
}
bool idEq(const int id, const DD_Task task) { return task.task_id == id; }
MaybeFound findIf(bool(fun_ptr)(const int, const DD_Task), int fun_arg,
DD_Task_List **list) {
for (DD_Task_List **l = list; (*l) != NULL; l = &(*l)->next_task) {
if (fun_ptr(fun_arg, (*l)->task)) {
return (MaybeFound){FOUND, l};
}
}
return (MaybeFound){NOT_FOUND, NULL};
}
Found delete(DD_Task_List **l) {
if (l == NULL)
return NOT_FOUND;
DD_Task_List *tmp_task;
if ((*l)->next_task) {
tmp_task = *l;
*l = (*l)->next_task;
} else {
// If there is nothing left then set this list to NULL
tmp_task = *l;
*l = NULL;
}
vPortFree(tmp_task);
(tmp_task) = NULL;
return FOUND;
}
void insert(DD_Task_List *new, DD_Task_List **l) {
if (*l == NULL) {
*l = new;
return;
}
// if ((*l)->next_task)
// new->next_task = (*l)->next_task;
// (*l)->next_task = new;
DD_Task_List *tmp = *l;
new->next_task = tmp;
*l = new;
return;
}
bool deadlineBefore(const int deadline, DD_Task task) {
return deadline < task.absolute_deadline;
}
void insertByDeadline(DD_Task_List *new, DD_Task_List **list) {
if (*list == NULL) {
*list = new;
return;
}
// add task at front of list if the new deadline is earlier
MaybeFound f = findIf(deadlineBefore, new->task.absolute_deadline, list);
if (f.found == FOUND) {
insert(new, f.list);
return;
}
DD_Task_List *l;
// Iterate to the end of the list and insert there
for (l = *list; l->next_task != NULL; l = l->next_task) {}
l->next_task = new;
return;
}
void printLL(DD_Task_List *list) {
if (list == NULL)
printf("NULL");
for (DD_Task_List *l = list; l != NULL; l = l->next_task) {
printf("{ id %d , rt %d, ct %d, dl %d}\n ",
(int)l->task.task_id,
(int)l->task.release_time,
(int)l->task.completion_time,
(int)l->task.absolute_deadline);
}
printf("\n");
}
#define amber_led LED3
#define green_led LED4
#define red_led LED5
#define blue_led LED6
int main(void)
{
/* Initialize LEDs */
STM_EVAL_LEDInit(amber_led);
STM_EVAL_LEDInit(green_led);
STM_EVAL_LEDInit(red_led);
STM_EVAL_LEDInit(blue_led);
/* Create the queue used by the queue send and queue receive tasks.
http://www.freertos.org/a00116.html */
xQueue_fromDDS= xQueueCreate( QUEUE_LENGTH, /* The number of items the queue can hold. */
sizeof( FromDDS_Message ) ); /* The size of each item the queue holds. */
xQueue_toDDS = xQueueCreate( QUEUE_LENGTH, /* The number of items the queue can hold. */
sizeof( ToDDS_Message ) ); /* The size of each item the queue holds. */
/* Add to the registry, for the benefit of kernel aware debugging. */
vQueueAddToRegistry( xQueue_toDDS, "to the dds");
vQueueAddToRegistry( xQueue_fromDDS, "from the dds");
xTaskCreate( DDS_Task, "DDS", configMINIMAL_STACK_SIZE, NULL, 3, NULL);
xTaskCreate( DDT_Generator_Task, "DDT Generator", configMINIMAL_STACK_SIZE, NULL, 3, NULL);
xTaskCreate( Monitor_Task, "Monitor", configMINIMAL_STACK_SIZE, NULL, 3, NULL);
/* Start the tasks and timer running. */
vTaskStartScheduler();
return 0;
}
/*-----------------------------------------------------------*/
void updatePriorities(DD_Task_List* active_tasks) {
if (active_tasks == NULL) return;
vTaskPrioritySet(active_tasks->task.t_handle, 2);
for(DD_Task_List* l = active_tasks->next_task ; l != NULL ; l = l->next_task){
vTaskPrioritySet(l->task.t_handle, 1);
}
}
bool overdueTask(const int current_time, const DD_Task task) {
return task.absolute_deadline < current_time;
}
void DDS_Task( void *pvParameters )
{
DD_Task_List* active_tasks = NULL;
DD_Task_List* completed_tasks = NULL;
DD_Task_List* overdue_tasks = NULL;
ToDDS_Message msg;
TickType_t start_time = xTaskGetTickCount();
TaskHandle_t task;
FromDDS_Message sent_message;
while(1)
{
if(xQueueReceive( xQueue_toDDS, &msg, 1000)==pdFALSE)
{
continue;
}
switch (msg.msg) {
case DELETE:
if (active_tasks == NULL) {
break;
}
// mark as completed
MaybeFound f = findIf(idEq, msg.info.task_id , &active_tasks);
if (f.found == FOUND) {
DD_Task_List * l = (*f.list);
if (l->task.absolute_deadline < xTaskGetTickCount() - start_time){
insertByDeadline(newNode(l->task.t_handle, l->task.type,
l->task.task_id,
l->task.release_time,
l->task.absolute_deadline,
xTaskGetTickCount() - start_time -1 ),
&overdue_tasks);
} else {
insertByDeadline(newNode(l->task.t_handle,
l->task.type,
l->task.task_id,
l->task.release_time,
l->task.absolute_deadline,
xTaskGetTickCount() - start_time -1 ),
&completed_tasks);
}
delete(f.list);
}
// Send confirmation that this task has been handled
sent_message.msg = DELETED_TASK;
DD_Task_List tmptasks ;
tmptasks.task.task_id = msg.info.task_id;
tmptasks.task.t_handle = NULL;
sent_message.tasks = &tmptasks;
xQueueSend(xQueue_fromDDS, &sent_message, 1000);
break;
case CREATE:
switch (msg.info.task_id) {
case 1:
xTaskCreate( User_Defined1_Task, "UserDef1", configMINIMAL_STACK_SIZE, NULL, 0, &task);
break;
case 2:
xTaskCreate( User_Defined2_Task, "UserDef2", configMINIMAL_STACK_SIZE, NULL, 0, &task);
break;
case 3:
xTaskCreate( User_Defined3_Task, "UserDef3", configMINIMAL_STACK_SIZE, NULL, 0, &task);
break;
}
DD_Task_List * nn = newNode(task, msg.info.type,msg.info.task_id,
xTaskGetTickCount() - start_time -1,
msg.info.absolute_deadline -1 ,
-1);
insertByDeadline(nn,
&active_tasks);
break;
case GET_ACTIVE:
sent_message.msg = ACTIVE_LIST;
sent_message.tasks = active_tasks;
xQueueSend(xQueue_fromDDS, &sent_message, 1000);
break;
case GET_COMPLETE:
sent_message.msg = COMPLETED_LIST;
sent_message.tasks = completed_tasks;
xQueueSend(xQueue_fromDDS, &sent_message, 1000);
break;
case GET_OVERDUE:
sent_message.msg = OVERDUE_LIST;
sent_message.tasks = overdue_tasks;
xQueueSend(xQueue_fromDDS, &sent_message, 1000);
break;
default:
break;
}
if (msg.msg == CREATE || msg.msg == DELETE){
// push overdue tasks to overdue task queue
MaybeFound maybeODT = findIf(overdueTask, xTaskGetTickCount() - start_time, &active_tasks);
if (maybeODT.found == FOUND) {
DD_Task_List * l = (*maybeODT.list);
insertByDeadline(newNode(l->task.t_handle, l->task.type,
l->task.task_id,
l->task.release_time,
l->task.absolute_deadline,
xTaskGetTickCount() - start_time -1),
&overdue_tasks);
vTaskDelete(l->task.t_handle);
delete(maybeODT.list);
}
updatePriorities(active_tasks);
}
}
}
void User_Defined1_Task( void *pvParameters )
{
while(1)
{
STM_EVAL_LEDOn(blue_led);
TickType_t start_ticks, current_ticks, exec_ticks;
start_ticks = xTaskGetTickCount();
current_ticks = xTaskGetTickCount();
exec_ticks = TASK1_EXEC/ portTICK_PERIOD_MS;
while(exec_ticks--)
{
start_ticks = xTaskGetTickCount();
while(1)
{
current_ticks = xTaskGetTickCount();
if(start_ticks != current_ticks) break;
}
}
STM_EVAL_LEDOff(blue_led);
delete_dd_task(1);
}
}
void User_Defined2_Task( void *pvParameters )
{
while(1)
{
STM_EVAL_LEDOn(green_led);
TickType_t start_ticks, current_ticks, exec_ticks;
start_ticks = xTaskGetTickCount();
current_ticks = xTaskGetTickCount();
exec_ticks = pdMS_TO_TICKS(TASK2_EXEC);
while(exec_ticks--)
{
start_ticks = xTaskGetTickCount();
while(1)
{
current_ticks = xTaskGetTickCount();
if(start_ticks != current_ticks) break;
}
}
STM_EVAL_LEDOff(green_led);
delete_dd_task(2);
}
}
void User_Defined3_Task( void *pvParameters )
{
STM_EVAL_LEDOn(red_led);
TickType_t start_ticks, current_ticks, exec_ticks;
start_ticks = xTaskGetTickCount();
current_ticks = xTaskGetTickCount();
exec_ticks = pdMS_TO_TICKS(TASK3_EXEC);
while(exec_ticks--)
{
start_ticks = xTaskGetTickCount();
while(1)
{
current_ticks = xTaskGetTickCount();
if(start_ticks != current_ticks) break;
}
}
STM_EVAL_LEDOff(red_led);
delete_dd_task(3);
}
void vTimerCallback(TimerHandle_t xTimer)
{
if( xTimer == xTimer_Task1)
{
create_dd_task(NULL, PERIODIC, 1, xTaskGetTickCount() + pdMS_TO_TICKS(TASK1_PERIOD));
xTimerChangePeriod(xTimer,pdMS_TO_TICKS(TASK1_PERIOD),1000);
}
else if (xTimer == xTimer_Task2)
{
create_dd_task(NULL, PERIODIC, 2, xTaskGetTickCount() + pdMS_TO_TICKS(TASK2_PERIOD));
xTimerChangePeriod(xTimer,pdMS_TO_TICKS(TASK2_PERIOD),1000);
}
else if (xTimer == xTimer_Task3)
{
create_dd_task(NULL, PERIODIC, 3, xTaskGetTickCount() + pdMS_TO_TICKS(TASK3_PERIOD));
xTimerChangePeriod(xTimer,pdMS_TO_TICKS(TASK3_PERIOD),1000);
}
}
void DDT_Generator_Task( void *pvParameters )
{
xTimer_Task1 = xTimerCreate("task 1 timer" , 1, pdTRUE, NULL, vTimerCallback);
xTimer_Task2 = xTimerCreate("task 2 timer", 1, pdTRUE, NULL, vTimerCallback);
xTimer_Task3 = xTimerCreate("task 3 timer", 1, pdTRUE, NULL, vTimerCallback);
xTimerStart(xTimer_Task1, 0);
xTimerStart(xTimer_Task2, 0);
xTimerStart(xTimer_Task3, 0);
while(1)
{
vTaskDelay(100000);
}
}
void Monitor_Task( void *pvParameters )
{
while(1){
vTaskDelay((HYPERPERIOD ) + 2);
// if (revoeve (event queue) != true) continue
DD_Task_List* atl = get_active_dd_task_list();
DD_Task_List* otl = get_overdue_dd_task_list();
DD_Task_List* ctl = get_complete_dd_task_list();
printf("=============\nactive tasks\n");
printLL(atl);
printf("overdue tasks\n");
printLL(otl);
printf("completed tasks\n");
printLL(ctl);
}
for(;;){}
}
//This function receives all of the information necessary to create a new dd_task struct (excluding
//the release time and completion time). The struct is packaged as a message and sent to a queue
//for the DDS to receive.
void create_dd_task(
TaskHandle_t t_handle,
task_type type,
uint32_t task_id,
uint32_t absolute_deadline)
{
DD_Info task_info = {
t_handle, //TaskHandle_t t_handle
type, //task_type type;
task_id,
absolute_deadline, //uint32_t absolute_deadline;
};
ToDDS_Message msg = {
CREATE,
task_info
};
xQueueSend(xQueue_toDDS, &msg, 0);
}
//This function receives the ID of the DD-Task which has completed its execution. The ID is packaged
//as a message and sent to a queue for the DDS to receive.
void delete_dd_task(uint32_t task_id)
{
DD_Info task_info = {NULL,0,task_id,0};
ToDDS_Message msg = {
DELETE,
task_info
};
FromDDS_Message rsp;
xQueueSend(xQueue_toDDS, &msg, 0);
xQueueReceive(xQueue_fromDDS, &rsp, 1000 );
for (;;) {
if (rsp.msg == DELETED_TASK && rsp.tasks->task.task_id == task_id) {
vTaskDelete(rsp.tasks->task.t_handle);
return;
}else {
xQueueSend(xQueue_fromDDS, &rsp, 1000 );
xQueueReceive(xQueue_fromDDS, &rsp, 1000);
}
}
}
//This function sends a message to a queue requesting the Active Task List from the DDS. Once a
//response is received from the DDS, the function returns the list.
DD_Task_List* get_active_dd_task_list(void)
{
DD_Info task_info = {NULL,0,1,0};
ToDDS_Message msg = {
GET_ACTIVE,
task_info
};
xQueueSend(xQueue_toDDS, &msg, 1000);
FromDDS_Message rsp;
xQueueReceive(xQueue_fromDDS, &rsp, 1000);
for (;;) {
if ( rsp.msg == ACTIVE_LIST ) {
return rsp.tasks;
} else {
xQueueSend(xQueue_fromDDS, &rsp, 1000 );
xQueueReceive(xQueue_fromDDS, &rsp, 1000);
}
}
}
//This function sends a message to a queue requesting the Completed Task List from the DDS. Once
//a response is received from the DDS, the function returns the list.
DD_Task_List* get_complete_dd_task_list(void)
{
DD_Info task_info = {NULL,0,1,0};
ToDDS_Message msg = {
GET_COMPLETE,
task_info
};
xQueueSend(xQueue_toDDS, &msg, 1000);
FromDDS_Message rsp;
xQueueReceive(xQueue_fromDDS, &rsp, 1000);
for (;;) {
if ( rsp.msg == COMPLETED_LIST ) {
return rsp.tasks;
} else {
xQueueSend(xQueue_fromDDS, &rsp, 1000 );
xQueueReceive(xQueue_fromDDS, &rsp, 1000);
}
}
}
//This function sends a message to a queue requesting the Overdue Task List from the DDS. Once a
//response is received from the DDS, the function returns the list.
DD_Task_List* get_overdue_dd_task_list(void)
{
DD_Info task_info = {NULL,0,1,0};
ToDDS_Message msg = {
GET_OVERDUE,
task_info
};
xQueueSend(xQueue_toDDS, &msg, 1000);
FromDDS_Message rsp;
xQueueReceive(xQueue_fromDDS, &rsp, 1000);
for (;;) {
if ( rsp.msg == OVERDUE_LIST ) {
return rsp.tasks;
} else {
xQueueSend(xQueue_fromDDS, &rsp, 1000 );
xQueueReceive(xQueue_fromDDS, &rsp, 1000);
}
}
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* The malloc failed hook is enabled by setting
configUSE_MALLOC_FAILED_HOOK to 1 in FreeRTOSConfig.h.
Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. pxCurrentTCB can be
inspected in the debugger if the task name passed into this function is
corrupt. */
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
volatile size_t xFreeStackSpace;
/* The idle task hook is enabled by setting configUSE_IDLE_HOOK to 1 in
FreeRTOSConfig.h.
This function is called on each cycle of the idle task. In this case it
does nothing useful, other than report the amount of FreeRTOS heap that
remains unallocated. */
xFreeStackSpace = xPortGetFreeHeapSize();
if( xFreeStackSpace > 100 )
{
/* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */
}
}
/* Standard includes. */
#include <stdint.h>
#include <stdio.h>
#include "stm32f4_discovery.h"
/* Kernel includes. */
#include "stm32f4xx.h"
#include "../FreeRTOS_Source/include/FreeRTOS.h"
#include "../FreeRTOS_Source/include/queue.h"
#include "../FreeRTOS_Source/include/semphr.h"
#include "../FreeRTOS_Source/include/task.h"
#include "../FreeRTOS_Source/include/timers.h"
#include <stdbool.h>
#define QUEUE_LENGTH 100
#define TASK1_LENGTH 100
#define TestBench1
//Test Bench 1
#ifdef TestBench1
#define TASK1_PERIOD 500
#define TASK2_PERIOD 500
#define TASK3_PERIOD 750
#define TASK1_EXEC 95
#define TASK2_EXEC 150
#define TASK3_EXEC 250
#define HYPERPERIOD 1500
#endif
//TestBench 2
#ifdef TestBench2
#define TASK1_PERIOD 250
#define TASK2_PERIOD 500
#define TASK3_PERIOD 750
#define TASK1_EXEC 95
#define TASK2_EXEC 150
#define TASK3_EXEC 250
#define HYPERPERIOD 1500
#endif
////TestBench 3
#ifdef TestBench3
#define TASK1_PERIOD 500
#define TASK2_PERIOD 500
#define TASK3_PERIOD 500
#define TASK1_EXEC 100
#define TASK2_EXEC 200
#define TASK3_EXEC 200
#define HYPERPERIOD 1000
#endif
#ifndef TASK_HEADER
#define TASK_HEADER
typedef enum task_type {PERIODIC,APERIODIC} task_type;
typedef enum DDS_Command {
CREATE,
DELETE,
GET_ACTIVE,
GET_COMPLETE,
GET_OVERDUE
} DDS_Command;
typedef enum DDS_Response{
ACTIVE_LIST,
COMPLETED_LIST,
OVERDUE_LIST,
DELETED_TASK,
} DDS_Response;
typedef struct DD_Task {
TaskHandle_t t_handle;
enum task_type type;
uint32_t task_id;
uint32_t release_time;
uint32_t absolute_deadline;
uint32_t completion_time;
} DD_Task;
// Singly-linked list of DD tasks
typedef struct DD_Task_List {
DD_Task task;
struct DD_Task_List *next_task;
} DD_Task_List;
typedef struct DD_Info {
TaskHandle_t t_handle;
task_type type;
uint32_t task_id;
uint32_t absolute_deadline;
} DD_Info;
typedef struct ToDDS_Message {
DDS_Command msg;
DD_Info info;
}ToDDS_Message;
typedef struct FromDDS_Message {
DDS_Response msg;
DD_Task_List *tasks;
}FromDDS_Message;
typedef struct Tasks_To_Generate {
TaskHandle_t t_handle;
uint32_t period;
}Tasks_To_Generate;
// task handle
// period
void create_dd_task( TaskHandle_t t_handle,
enum task_type type,
uint32_t task_id,
uint32_t absolute_deadline);
void delete_dd_task(uint32_t task_id);
DD_Task_List* get_active_dd_task_list(void);
DD_Task_List* get_complete_dd_task_list(void);
DD_Task_List* get_overdue_dd_task_list(void);
void DDS_Task( void *pvParameters );
void User_Defined1_Task( void *pvParameters );
void User_Defined2_Task( void *pvParameters );
void User_Defined3_Task( void *pvParameters );
void DDT_Generator_Task( void *pvParameters );
void Monitor_Task( void *pvParameters );
void vTimerCallback(TimerHandle_t xTimer);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment