1 /*
2 * Copyright (c) Texas Instruments Incorporated 2021-2022
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
33 /**
34 * \file SafeRTOS_config.c
35 *
36 * \brief The file implements the safertos OS init configuration.
37 *
38 */
40 /* ========================================================================== */
41 /* Include Files */
42 /* ========================================================================== */
44 #include <ti/osal/TimerP.h>
45 #include <ti/osal/src/nonos/Nonos_config.h>
47 #include "SafeRTOS_priv.h"
49 /* ========================================================================== */
50 /* Macros & Typedefs */
51 /* ========================================================================== */
53 /* Scheduler Initialisation Definitions */
55 /* SafeRTOS inspects the vector table to ensure
56 * the necessary handlers have been installed. */
57 #define configSTACK_CHECK_MARGIN ( 0U )
59 /* The user configuration for the timer module. */
60 #define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1U )
61 #define configTIMER_QUEUE_LENGTH ( 50U )
62 #define configTIMER_CMD_QUEUE_BUFFER_SIZE ( ( configTIMER_QUEUE_LENGTH * sizeof( timerQueueMessageType ) ) + safertosapiQUEUE_OVERHEAD_BYTES )
64 #if defined (BUILD_MCU)
65 #define configTIMER_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE_WITH_FPU )
66 /* The user configuration for the idle task. */
67 #define configIDLE_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE_WITH_FPU )
68 #endif
70 #if defined (BUILD_C66X)
71 /* The user configuration for the idle task. */
72 #define configIDLE_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE )
73 #endif
75 #if defined (BUILD_C7X)
76 #define configTIMER_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE )
77 /* The user configuration for the idle task. */
78 #define configIDLE_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE )
79 #endif
81 /* ========================================================================== */
82 /* Global Structure Definition */
83 /* ========================================================================== */
85 /* None */
87 /* ========================================================================== */
88 /* Function Declarations */
89 /* ========================================================================== */
91 /* Timer interrupt handler function. */
92 static void prvTimerTickIsr( uintptr_t arg );
94 /* ========================================================================== */
95 /* Global Variables */
96 /* ========================================================================== */
97 /* For SafeRTOS on R5F with FFI Support, task stack should be aligned to the stack size */
98 #if defined (BUILD_MCU)
99 static portInt8Type acIdleTaskStack[ configIDLE_TASK_STACK_SIZE ] __attribute__( ( aligned( configIDLE_TASK_STACK_SIZE ) ) ) = { 0 };
101 /* Declare the stack for the timer task, it cannot be done in the timer
102 * module as the syntax for alignment is port specific. Also the callback
103 * functions are executed in the timer task and their complexity/stack
104 * requirements are application specific. */
105 static portInt8Type acTimerTaskStack[ configTIMER_TASK_STACK_SIZE ] __attribute__( ( aligned( configTIMER_TASK_STACK_SIZE ) ) ) = { 0 };
106 #else
107 static portInt8Type acTimerTaskStack[ configTIMER_TASK_STACK_SIZE ] __attribute__( ( aligned ( safertosapiSTACK_ALIGNMENT ) ) ) = { 0 };
108 static portInt8Type acIdleTaskStack[ configIDLE_TASK_STACK_SIZE ] __attribute__( ( aligned ( safertosapiSTACK_ALIGNMENT ) ) ) = { 0 };
109 #endif /* defined (BUILD_MCU) */
111 /* The buffer for the timer command queue. */
112 static portInt8Type acTimerCommandQueueBuffer[ configTIMER_CMD_QUEUE_BUFFER_SIZE ] __attribute__( ( aligned ( safertosapiWORD_ALIGNMENT ) ) ) = { 0 };
114 /* The structure passed to xTaskInitializeScheduler() to configure the kernel
115 * with the application defined constants and call back functions. */
116 const xPORT_INIT_PARAMETERS gSafertosPortInit =
117 {
118 configSYSTICK_CLOCK_HZ, /* ulCPUClockHz */
119 configTICK_RATE_HZ, /* ulTickRateHz */
120 #if defined (BUILD_C7X)
121 OSAL_SAFERTOS_OS_YEILD_INT_NUM_C7X, /* uxYieldInterruptNumber */
122 #endif
124 /* Hook Functions */
125 NULL, /* pvSvcHookFunction */
127 /* System Stack parameters */
128 configSTACK_CHECK_MARGIN, /* uxAdditionalStackCheckMarginBytes */
130 /* Idle Task parameters */
131 acIdleTaskStack, /* pcIdleTaskStackBuffer */
132 configIDLE_TASK_STACK_SIZE, /* uxIdleTaskStackSizeBytes */
133 #if defined (BUILD_MCU)
134 pdFALSE, /* xIdleTaskUsingFPU */
135 { /* xIdleTaskMPUParameters */
136 mpuUNPRIVILEGED_TASK, /* The idle hook will be executed in unprivileged mode. */
137 {
138 { NULL, 0U, 0U, 0U },
139 { NULL, 0U, 0U, 0U },
140 }
141 },
142 #endif
143 #if defined (BUILD_C66X)
144 safertosapiUNPRIVILEGED_TASK, /* The idle hook will not be executed in privileged mode. */
145 #endif
146 NULL, /* pvIdleTaskTLSObject */
148 /* Timer feature initialisation parameters */
149 configTIMER_TASK_PRIORITY, /* uxTimerTaskPriority */
150 configTIMER_TASK_STACK_SIZE, /* uxTimerTaskStackSize */
151 acTimerTaskStack, /* pcTimerTaskStackBuffer */
152 configTIMER_QUEUE_LENGTH, /* uxTimerCommandQueueLength */
153 configTIMER_CMD_QUEUE_BUFFER_SIZE, /* uxTimerCommandQueueBufferSize */
154 acTimerCommandQueueBuffer, /* pcTimerCommandQueueBuffer */
156 #if defined (BUILD_MCU)
157 pdTRUE, /* xEnableCache */
158 #endif
159 };
161 uint32_t gSaftRtosInitDone = (uint32_t) FALSE;
163 /* ========================================================================== */
164 /* Function Defintions */
165 /* ========================================================================== */
167 void OS_init( void )
168 {
169 portBaseType xInitSchedResult;
171 xInitSchedResult = prvSetupHardware();
173 if (xInitSchedResult == pdPASS)
174 {
175 /* Initialise the kernel by passing in a pointer to the xPORT_INIT_PARAMETERS structure
176 * and return the resulting error code. */
177 xInitSchedResult = xTaskInitializeScheduler( &gSafertosPortInit );
178 }
180 /* Assert that xInitSchedResult is successful */
181 DebugP_assert((xInitSchedResult == pdPASS));
183 gSaftRtosInitDone = TRUE;
185 return;
186 }
188 /*---------------------------------------------------------------------------*/
190 __attribute__((weak)) \
191 void vApplicationErrorHook( portTaskHandleType xHandleOfTaskWithError,
192 portBaseType xErrorCode )
193 {
194 /* The parameters are not used, these lines prevent compiler warnings. */
195 ( void ) xHandleOfTaskWithError;
196 ( void ) xErrorCode;
198 /* Will only get here if an internal kernel error occurs. */
199 DebugP_assert(0);
200 }
202 /*---------------------------------------------------------------------------*/
204 /* Tick timer setup using TI PDK timers and interrupts. */
205 __attribute__((weak)) \
206 void vApplicationSetupTickInterruptHook( portUInt32Type ulTimerClockHz,
207 portUInt32Type ulTickRateHz )
208 {
209 TimerP_Handle pxTickTimerHandle = NULL;
210 TimerP_Params xTimerParams;
212 Safertos_OSTimerParams xOSTimerParams;
214 ( void ) ulTimerClockHz;
216 TimerP_Params_init( &xTimerParams );
217 xTimerParams.runMode = TimerP_RunMode_CONTINUOUS;
218 xTimerParams.startMode = TimerP_StartMode_USER;
219 xTimerParams.periodType = TimerP_PeriodType_MICROSECS;
220 xTimerParams.period = ( 1000000UL / ulTickRateHz );
221 prvGetOSTimerParams( &xOSTimerParams );
222 #if defined (BUILD_C66X) || defined (BUILD_C7X)
223 xTimerParams.intNum = xOSTimerParams.intNum;
224 xTimerParams.eventId = xOSTimerParams.eventId;
225 #endif
227 pxTickTimerHandle = TimerP_create( xOSTimerParams.timerId,
228 &prvTimerTickIsr,
229 &xTimerParams );
231 /* don't expect the handle to be null or the timer to start OK */
232 if( ( NULL == pxTickTimerHandle ) ||
233 ( TimerP_OK != TimerP_start( pxTickTimerHandle ) ) )
234 {
235 DebugP_assert(0);
236 }
237 }
239 /*-------------------------------------------------------------------------*/
241 void prvGetOSTimerParams( Safertos_OSTimerParams *params)
242 {
243 #if defined (BUILD_C66X)
244 if (CSL_chipReadDNUM() == 0U)
245 {
246 params->timerId = OSAL_SAFERTOS_OS_TIMER_ID_C66X_1;
247 params->eventId = OSAL_SAFERTOS_OS_TIMER_EVENT_ID_C66X_1;
248 params->intNum = OSAL_SAFERTOS_OS_TIMER_INT_NUM_C66X_1;
249 }
250 else
251 {
252 params->timerId = OSAL_SAFERTOS_OS_TIMER_ID_C66X_2;
253 params->eventId = OSAL_SAFERTOS_OS_TIMER_EVENT_ID_C66X_2;
254 params->intNum = OSAL_SAFERTOS_OS_TIMER_INT_NUM_C66X_2;
256 }
257 #endif
258 #if defined (BUILD_MCU)
259 CSL_ArmR5CPUInfo info;
261 CSL_armR5GetCpuID(&info);
262 if (info.grpId == (uint32_t)CSL_ARM_R5_CLUSTER_GROUP_ID_0)
263 {
264 params->timerId = (info.cpuID == CSL_ARM_R5_CPU_ID_0)?
265 OSAL_SAFERTOS_OS_TIMER_ID_MCU1_0:
266 OSAL_SAFERTOS_OS_TIMER_ID_MCU1_1;
267 }
268 else if (info.grpId == (uint32_t)CSL_ARM_R5_CLUSTER_GROUP_ID_1)
269 {
270 params->timerId = (info.cpuID == CSL_ARM_R5_CPU_ID_0)?
271 OSAL_SAFERTOS_OS_TIMER_ID_MCU2_0:
272 OSAL_SAFERTOS_OS_TIMER_ID_MCU2_1;
273 }
274 else if (info.grpId == (uint32_t)CSL_ARM_R5_CLUSTER_GROUP_ID_2)
275 {
276 params->timerId = (info.cpuID == CSL_ARM_R5_CPU_ID_0)?
277 OSAL_SAFERTOS_OS_TIMER_ID_MCU3_0:
278 OSAL_SAFERTOS_OS_TIMER_ID_MCU3_1;
279 }
280 #elif defined (BUILD_C7X)
281 params->timerId = OSAL_SAFERTOS_OS_TIMER_ID_C7X_1;
282 params->intNum = OSAL_SAFERTOS_OS_TIMER_INT_NUM_C7X_1;
283 params->eventId = TimerP_USE_DEFAULT;
284 #endif
285 }
287 /* ========================================================================== */
288 /* Static Function Definitions */
289 /* ========================================================================== */
291 static void prvTimerTickIsr( uintptr_t arg )
292 {
293 ( void ) arg;
294 vTaskProcessSystemTickFromISR();
295 }
297 /*-------------------------------------------------------------------------*/