490 lines
17 KiB
Plaintext
490 lines
17 KiB
Plaintext
/*
|
|
* Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
* this software and associated documentation files (the "Software"), to deal in
|
|
* the Software without restriction, including without limitation the rights to
|
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
*/
|
|
|
|
//
|
|
// Includes
|
|
//
|
|
#include "c2000_freertos.h"
|
|
|
|
% var module = system.modules['/kernel/freertos_tool/FREERTOS'];
|
|
% var taskNames = [];
|
|
% var semaphoreNames = [];
|
|
% var queueNames = [];
|
|
% var timerNames = [];
|
|
% var eventNames = [];
|
|
% if (module != null)
|
|
% {
|
|
% var instance = module.$instances[0];
|
|
% if(instance.APPLICATION_ALLOCATED_HEAP == true)
|
|
% {
|
|
uint8_t ucHeap[ `instance.TOTAL_HEAP_SIZE` ];
|
|
#pragma DATA_SECTION(ucHeap, ".freertosHeap")
|
|
#pragma DATA_ALIGN ( ucHeap , portBYTE_ALIGNMENT )
|
|
|
|
% }
|
|
% if(instance.SUPPORT_STATIC_ALLOCATION == true)
|
|
% {
|
|
StaticTask_t idleTaskTCBBuffer;
|
|
StackType_t idleTaskStack[IDLE_TASK_STACK_SIZE];
|
|
#pragma DATA_SECTION(idleTaskStack, ".freertosStaticStack")
|
|
#pragma DATA_ALIGN ( idleTaskStack , portBYTE_ALIGNMENT )
|
|
|
|
% if(instance.USE_TIMERS == true)
|
|
% {
|
|
//
|
|
// Timer service task specific variables
|
|
//
|
|
StaticTask_t timerTaskTCBBuffer;
|
|
StackType_t timerTaskStack[TIMER_TASK_STACK_SIZE];
|
|
#pragma DATA_SECTION(timerTaskStack, ".freertosStaticStack")
|
|
#pragma DATA_ALIGN ( timerTaskStack , portBYTE_ALIGNMENT )
|
|
|
|
% }
|
|
% }
|
|
% /* Start: Task related declarations */
|
|
% var tasks = instance.tasks;
|
|
% var numberOfTasks = tasks.length;
|
|
% for (var taskInstanceIndex = 0; taskInstanceIndex < numberOfTasks; taskInstanceIndex++)
|
|
% {
|
|
% var taskInstance = tasks[taskInstanceIndex];
|
|
% if(taskInstance.createDynamicTask == false)
|
|
% {
|
|
//
|
|
// Variables for `taskInstance.$name` TCB and stack
|
|
//
|
|
StaticTask_t `taskInstance.taskControlBlock`;
|
|
StackType_t `taskInstance.taskStackBuffer`[`taskInstance.$name`_STACK_SIZE];
|
|
#pragma DATA_SECTION(`taskInstance.taskStackBuffer`, ".freertosStaticStack")
|
|
#pragma DATA_ALIGN ( `taskInstance.taskStackBuffer` , portBYTE_ALIGNMENT )
|
|
|
|
% }
|
|
//
|
|
// Task Handle for `taskInstance.$name`
|
|
//
|
|
TaskHandle_t `taskInstance.taskHandle` = NULL;
|
|
|
|
% }
|
|
% /* End: Task related declarations */
|
|
% /* Start: Semaphores/Mutexes related declarations */
|
|
% var semaphores = instance.semaphores;
|
|
% var numberOfsemaphores = semaphores.length;
|
|
% for (var semaphoreInstanceIndex = 0; semaphoreInstanceIndex < numberOfsemaphores; semaphoreInstanceIndex++)
|
|
% {
|
|
% var semaphoreInstance = semaphores[semaphoreInstanceIndex];
|
|
//
|
|
// Declare a variable to hold the handle of the created semaphore.
|
|
//
|
|
SemaphoreHandle_t `semaphoreInstance.semHandle` = NULL;
|
|
|
|
% if(semaphoreInstance.createDynamicSem == false)
|
|
% {
|
|
//
|
|
// Declare a variable to hold data associated with the created static semaphore.
|
|
//
|
|
StaticSemaphore_t `semaphoreInstance.semBuffer`;
|
|
|
|
% }
|
|
% }
|
|
% /* End: Semaphores related declarations */
|
|
% /* Start: Queues related configurations */
|
|
% var queues = instance.queues
|
|
% var numberOfQueues = queues.length
|
|
% for(var queueInstanceIndex = 0; queueInstanceIndex < numberOfQueues; queueInstanceIndex++)
|
|
% {
|
|
% var queueInstance = queues[queueInstanceIndex]
|
|
//
|
|
// Declare a variable to hold the handle of the created queue
|
|
//
|
|
QueueHandle_t `queueInstance.queueHandle` = NULL;
|
|
|
|
% if(queueInstance.createDynamicQueue == false)
|
|
% {
|
|
//
|
|
// Declare variable to hold the queue's data structure.
|
|
//
|
|
StaticQueue_t `queueInstance.queueBuffer`;
|
|
|
|
//
|
|
// Declare the array to use as the queue's storage area. This must be at least
|
|
// QueueLength * ItemSize bytes.
|
|
//
|
|
uint8_t `queueInstance.queueStorageBuffer`[`queueInstance.queueLength` * `queueInstance.queueItemSize`];
|
|
|
|
% }
|
|
% }
|
|
% /* End: Queues related configurations */
|
|
% /* Start: Timers related declarations */
|
|
% var timers = instance.timers;
|
|
% var numberOfTimers = timers.length;
|
|
% for (var timerInstanceIndex = 0; timerInstanceIndex < numberOfTimers; timerInstanceIndex++)
|
|
% {
|
|
% var timerInstance = timers[timerInstanceIndex];
|
|
//
|
|
// Declare a variable to hold the handle of the created timer.
|
|
//
|
|
TimerHandle_t `timerInstance.timerHandle`;
|
|
|
|
% if(timerInstance.createDynamicTimer == false)
|
|
% {
|
|
//
|
|
// Declare a variable to hold the data associated with the created static timer.
|
|
//
|
|
StaticTimer_t `timerInstance.timerBuffer`;
|
|
|
|
% }
|
|
% }
|
|
% /* End: Timers related declarations */
|
|
% /* Start: Events related declarations */
|
|
% var events = instance.events;
|
|
% var numberOfEvents = events.length;
|
|
% for (var eventInstanceIndex = 0; eventInstanceIndex < numberOfEvents; eventInstanceIndex++)
|
|
% {
|
|
% var eventInstance = events[eventInstanceIndex];
|
|
//
|
|
// Declare a variable to hold the handle of the created event group.
|
|
//
|
|
EventGroupHandle_t `eventInstance.eventHandle`;
|
|
|
|
% if(eventInstance.createDynamicEvent == false)
|
|
% {
|
|
//
|
|
// Declare a variable to hold the data associated with the created static event group.
|
|
//
|
|
StaticEventGroup_t `eventInstance.eventGroupBuffer`;
|
|
|
|
% }
|
|
% }
|
|
% /* End: Events related declarations */
|
|
% }
|
|
% if (module != null)
|
|
% {
|
|
% var instance = module.$instances[0];
|
|
% /* Start: Tasks related configurations */
|
|
% var tasks = instance.tasks;
|
|
% var numberOfTasks = tasks.length;
|
|
% for (var taskInstanceIndex = 0; taskInstanceIndex < numberOfTasks; taskInstanceIndex++)
|
|
% {
|
|
% var taskInstance = tasks[taskInstanceIndex];
|
|
% taskNames.push(taskInstance.$name)
|
|
//
|
|
// `taskInstance.$name`_init() - Initializes task `taskInstance.$name`
|
|
//
|
|
void `taskInstance.$name`_init() {
|
|
% if(taskInstance.createDynamicTask == false)
|
|
% {
|
|
//
|
|
// Create the task with static memory allocation.
|
|
//
|
|
`taskInstance.taskHandle` =
|
|
xTaskCreateStatic(`taskInstance.taskPointer`, // Function that implements the task.
|
|
"`taskInstance.$name`", // Text name for the task.
|
|
`taskInstance.taskStackSize`, // Number of indexes in the xStack array.
|
|
(void *) `taskInstance.taskParams`, // Parameter passed into the task.
|
|
`taskInstance.taskPriority`, // Priority at which the task is created.
|
|
`taskInstance.taskStackBuffer`, // Array to use as the task's stack.
|
|
&`taskInstance.taskControlBlock` ); // Variable to hold the task's TCB
|
|
% }
|
|
% else
|
|
% {
|
|
//
|
|
// Create the task with dynamic memory allocation.
|
|
//
|
|
xTaskCreate(`taskInstance.taskPointer`, // Function that implements the task.
|
|
"`taskInstance.$name`", // Text name for the task.
|
|
`taskInstance.taskStackSize`, // Number of indexes in the xStack array.
|
|
(void *) `taskInstance.taskParams`, // Parameter passed into the task.
|
|
`taskInstance.taskPriority`, // Priority at which the task is created.
|
|
&`taskInstance.taskHandle` ); // Variable to hold the task's data structure.
|
|
|
|
% }
|
|
}
|
|
|
|
% }
|
|
% /* End: Tasks related configurations */
|
|
% /* Start: Semaphores/Mutexes related configurations */
|
|
% var semaphores = instance.semaphores;
|
|
% var numberOfSemaphores = semaphores.length;
|
|
% for (var semaphoreInstanceIndex = 0; semaphoreInstanceIndex < numberOfSemaphores; semaphoreInstanceIndex++)
|
|
% {
|
|
% var semaphoreInstance = semaphores[semaphoreInstanceIndex];
|
|
% semaphoreNames.push(semaphoreInstance.$name)
|
|
//
|
|
// `semaphoreInstance.$name`_init() - Initializes semaphore `semaphoreInstance.$name`
|
|
//
|
|
void `semaphoreInstance.$name`_init() {
|
|
% if(semaphoreInstance.createDynamicSem == false)
|
|
% {
|
|
% if(semaphoreInstance.semType == "BINARY_SEMAPHORE")
|
|
% {
|
|
//
|
|
// Create the binary semaphore with static memory allocation.
|
|
//
|
|
`semaphoreInstance.semHandle` =
|
|
xSemaphoreCreateBinaryStatic(&`semaphoreInstance.semBuffer`);
|
|
|
|
% }
|
|
% else if(semaphoreInstance.semType == "COUNTING_SEMAPHORE")
|
|
% {
|
|
//
|
|
// Create the counting semaphore with static memory allocation.
|
|
//
|
|
`semaphoreInstance.semHandle` = xSemaphoreCreateCountingStatic(`semaphoreInstance.semMaxCount`, `semaphoreInstance.semInitialCount`, &`semaphoreInstance.semBuffer`);
|
|
|
|
% }
|
|
% else if(semaphoreInstance.semType == "MUTEX_SEMAPHORE")
|
|
% {
|
|
//
|
|
// Create the counting semaphore with static memory allocation.
|
|
//
|
|
`semaphoreInstance.semHandle` =
|
|
xSemaphoreCreateMutexStatic(&`semaphoreInstance.semBuffer`);
|
|
|
|
% }
|
|
% else
|
|
% {
|
|
//
|
|
// Create the recursive mutex with static memory allocation.
|
|
//
|
|
`semaphoreInstance.semHandle` = xSemaphoreCreateRecursiveMutexStatic(&`semaphoreInstance.semBuffer`);
|
|
|
|
% }
|
|
% }
|
|
% else
|
|
% {
|
|
% if(semaphoreInstance.semType == "BINARY_SEMAPHORE")
|
|
% {
|
|
//
|
|
// Create the binary semaphore with dynamic memory allocation.
|
|
//
|
|
`semaphoreInstance.semHandle` = xSemaphoreCreateBinary();
|
|
|
|
% }
|
|
% else if(semaphoreInstance.semType == "COUNTING_SEMAPHORE")
|
|
% {
|
|
//
|
|
// Create the counting semaphore with dyanmic memory allocation.
|
|
//
|
|
`semaphoreInstance.semHandle` = xSemaphoreCreateCounting(`semaphoreInstance.semMaxCount`, `semaphoreInstance.semInitialCount`);
|
|
|
|
% }
|
|
% else if(semaphoreInstance.semType == "MUTEX_SEMAPHORE")
|
|
% {
|
|
//
|
|
// Create the mutex with dynamic memory allocation.
|
|
//
|
|
`semaphoreInstance.semHandle` = xSemaphoreCreateMutex();
|
|
|
|
% }
|
|
% else
|
|
% {
|
|
//
|
|
// Create the recursive mutex with static memory allocation.
|
|
//
|
|
`semaphoreInstance.semHandle` = xSemaphoreCreateRecursiveMutex();
|
|
|
|
% }
|
|
% }
|
|
}
|
|
|
|
% }
|
|
% /* End: Semaphores related configurations */
|
|
% /* Start: Queues related configurations */
|
|
% var queues = instance.queues;
|
|
% var numberOfQueues = queues.length;
|
|
% for (var queueInstanceIndex = 0; queueInstanceIndex < numberOfQueues; queueInstanceIndex++)
|
|
% {
|
|
% var queueInstance = queues[queueInstanceIndex];
|
|
% queueNames.push(queueInstance.$name)
|
|
//
|
|
// `queueInstance.$name`_init() - Initializes queue `queueInstance.$name`
|
|
//
|
|
void `queueInstance.$name`_init() {
|
|
% if(queueInstance.createDynamicQueue == false)
|
|
% {
|
|
//
|
|
// Create the queue with static memory allocation.
|
|
//
|
|
`queueInstance.queueHandle` =
|
|
xQueueCreateStatic(`queueInstance.queueLength`, `queueInstance.queueItemSize`,
|
|
`queueInstance.queueStorageBuffer`, &`queueInstance.queueBuffer` );
|
|
|
|
% }
|
|
% else
|
|
% {
|
|
//
|
|
// Create the queue with dynamic memory allocation.
|
|
//
|
|
`queueInstance.queueHandle` = xQueueCreate(`queueInstance.queueLength`, `queueInstance.queueItemSize`);
|
|
|
|
% }
|
|
}
|
|
|
|
% }
|
|
% /* End: Queues related configurations */
|
|
% /* Start: Timers related configurations */
|
|
% var timers = instance.timers;
|
|
% var numberOfTimers = timers.length;
|
|
% for (var timerInstanceIndex = 0; timerInstanceIndex < numberOfTimers; timerInstanceIndex++)
|
|
% {
|
|
% var timerInstance = timers[timerInstanceIndex];
|
|
% timerNames.push(timerInstance.$name)
|
|
//
|
|
// `timerInstance.$name`_init() - Initializes timer `timerInstance.$name`
|
|
//
|
|
void `timerInstance.$name`_init() {
|
|
% if(timerInstance.createDynamicTimer == false)
|
|
% {
|
|
//
|
|
// Create the timer with static memory allocation.
|
|
//
|
|
`timerInstance.timerHandle` =
|
|
xTimerCreateStatic("`timerInstance.$name`", `timerInstance.timerPeriod`, `(timerInstance.timerAutoReload == true) ? 1:0`,
|
|
`timerInstance.timerId`, `timerInstance.timerCallbackFunction`, &`timerInstance.timerBuffer`);
|
|
|
|
% }
|
|
% else
|
|
% {
|
|
//
|
|
// Create the timer with dynamic memory allocation.
|
|
//
|
|
`timerInstance.$name`Handle = xTimerCreate("`timerInstance.$name`", `timerInstance.timerPeriod`, `(timerInstance.timerAutoReload == true) ? 1:0`,`timerInstance.timerId`, `timerInstance.timerCallbackFunction`);
|
|
|
|
% }
|
|
}
|
|
|
|
% }
|
|
% /* End: Timers related configurations */
|
|
% /* Start: Events related configurations */
|
|
% var events = instance.events;
|
|
% var numberOfEvents = events.length;
|
|
% for (var eventInstanceIndex = 0; eventInstanceIndex < numberOfEvents; eventInstanceIndex++)
|
|
% {
|
|
% var eventInstance = events[eventInstanceIndex];
|
|
% eventNames.push(eventInstance.$name)
|
|
//
|
|
// `eventInstance.$name`_init() - Initializes event `eventInstance.$name`
|
|
//
|
|
void `eventInstance.$name`_init() {
|
|
% if(eventInstance.createDynamicEvent == false)
|
|
% {
|
|
//
|
|
// Create the event with static memory allocation.
|
|
//
|
|
`eventInstance.eventHandle` =
|
|
xEventGroupCreateStatic(&`eventInstance.eventGroupBuffer`);
|
|
% }
|
|
% else
|
|
% {
|
|
//
|
|
// Create the event with dynamic memory allocation.
|
|
//
|
|
`eventInstance.eventHandle` = xEventGroupCreate();
|
|
% }
|
|
}
|
|
|
|
% }
|
|
% /* End: Events related configurations */
|
|
% } /* end module */
|
|
% if(instance.SUPPORT_STATIC_ALLOCATION == true)
|
|
% {
|
|
//
|
|
// vApplicationGetIdleTaskMemory - Application must provide an implementation
|
|
// of vApplicationGetIdleTaskMemory() to provide the memory that is used by the
|
|
// Idle task if configUSE_STATIC_ALLOCATION is set to 1.
|
|
//
|
|
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
|
|
StackType_t **ppxIdleTaskStackBuffer,
|
|
uint32_t *pulIdleTaskStackSize )
|
|
{
|
|
/* If the buffers to be provided to the Idle task are declared inside this
|
|
function then they must be declared static - otherwise they will be allocated on
|
|
the stack and so not exists after this function exits. */
|
|
|
|
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
|
|
state will be stored. */
|
|
*ppxIdleTaskTCBBuffer = &idleTaskTCBBuffer;
|
|
|
|
/* Pass out the array that will be used as the Idle task's stack. */
|
|
*ppxIdleTaskStackBuffer = idleTaskStack;
|
|
|
|
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
|
|
Note that, as the array is necessarily of type StackType_t, size is
|
|
specified in words, not bytes. */
|
|
*pulIdleTaskStackSize = IDLE_TASK_STACK_SIZE;
|
|
}
|
|
|
|
% }
|
|
% if((instance.SUPPORT_STATIC_ALLOCATION == true) && (instance.USE_TIMERS == true))
|
|
% {
|
|
//
|
|
// Application must provide an implementation of vApplicationGetTimerTaskMemory()
|
|
// to provide the memory that is used by the Timer service task if both
|
|
// configUSE_STATIC_ALLOCATION and configUSE_TIMERS are set to 1.
|
|
//
|
|
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
|
|
StackType_t **ppxTimerTaskStackBuffer,
|
|
uint32_t *pulTimerTaskStackSize )
|
|
{
|
|
/* If the buffers to be provided to the Timer task are declared inside this
|
|
function then they must be declared static - otherwise they will be allocated on
|
|
the stack and so not exists after this function exits. */
|
|
|
|
/* Pass out a pointer to the StaticTask_t structure in which the Timer
|
|
task's state will be stored. */
|
|
*ppxTimerTaskTCBBuffer = &timerTaskTCBBuffer;
|
|
|
|
/* Pass out the array that will be used as the Timer task's stack. */
|
|
*ppxTimerTaskStackBuffer = timerTaskStack;
|
|
|
|
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
|
|
Note that, as the array is necessarily of type StackType_t,
|
|
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
|
*pulTimerTaskStackSize = TIMER_TASK_STACK_SIZE;
|
|
}
|
|
% }
|
|
|
|
//
|
|
// FreeRTOS_init - Initializes added FreeRTOS constructs and starts the scheduler
|
|
//
|
|
void FreeRTOS_init(){
|
|
% for (var taskName of taskNames) {
|
|
`taskName`_init();
|
|
% }
|
|
% for (var semaphoreName of semaphoreNames) {
|
|
`semaphoreName`_init();
|
|
% }
|
|
% for (var queueName of queueNames) {
|
|
`queueName`_init();
|
|
% }
|
|
% for (var timerName of timerNames) {
|
|
`timerName`_init();
|
|
% }
|
|
% for (var eventName of eventNames) {
|
|
`eventName`_init();
|
|
% }
|
|
|
|
//
|
|
// Start the scheduler
|
|
//
|
|
vTaskStartScheduler();
|
|
}
|