/* * 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(); }