2 * FreeRTOS Kernel V11.2.0
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5 * SPDX-License-Identifier: MIT
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
8 * this software and associated documentation files (the "Software"), to deal in
9 * the Software without restriction, including without limitation the rights to
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11 * the Software, and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 * https://www.FreeRTOS.org
25 * https://github.com/FreeRTOS
29 /*-----------------------------------------------------------
30 * Implementation of functions defined in portable.h for the SH2A port.
31 *----------------------------------------------------------*/
33 /* Scheduler includes. */
37 /* Library includes. */
40 /*-----------------------------------------------------------*/
42 /* The SR assigned to a newly created task. The only important thing in this
43 * value is for all interrupts to be enabled. */
44 #define portINITIAL_SR ( 0UL )
46 /* Dimensions the array into which the floating point context is saved.
47 * Allocate enough space for FPR0 to FPR15, FPUL and FPSCR, each of which is 4
48 * bytes big. If this number is changed then the 72 in portasm.src also needs
50 #define portFLOP_REGISTERS_TO_STORE ( 18 )
51 #define portFLOP_STORAGE_SIZE ( portFLOP_REGISTERS_TO_STORE * 4 )
53 #if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
54 #error configSUPPORT_DYNAMIC_ALLOCATION must be 1 to use this port.
57 /*-----------------------------------------------------------*/
60 * The TRAPA handler used to force a context switch.
62 void vPortYield( void );
65 * Function to start the first task executing - defined in portasm.src.
67 extern void vPortStartFirstTask( void );
70 * Obtains the current GBR value - defined in portasm.src.
72 extern uint32_t ulPortGetGBR( void );
74 /*-----------------------------------------------------------*/
77 * See header file for description.
79 StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
80 TaskFunction_t pxCode,
83 /* Mark the end of the stack - used for debugging only and can be removed. */
84 *pxTopOfStack = 0x11111111UL;
86 *pxTopOfStack = 0x22222222UL;
88 *pxTopOfStack = 0x33333333UL;
92 *pxTopOfStack = portINITIAL_SR;
96 *pxTopOfStack = ( uint32_t ) pxCode;
144 *pxTopOfStack = ( uint32_t ) pvParameters;
172 *pxTopOfStack = ulPortGetGBR();
174 /* GBR = global base register.
175 * VBR = vector base register.
176 * TBR = jump table base register.
177 * R15 is the stack pointer. */
181 /*-----------------------------------------------------------*/
183 BaseType_t xPortStartScheduler( void )
185 extern void vApplicationSetupTimerInterrupt( void );
187 /* Call an application function to set up the timer that will generate the
188 * tick interrupt. This way the application can decide which peripheral to
189 * use. A demo application is provided to show a suitable example. */
190 vApplicationSetupTimerInterrupt();
192 /* Start the first task. This will only restore the standard registers and
193 * not the flop registers. This does not really matter though because the only
194 * flop register that is initialised to a particular value is fpscr, and it is
195 * only initialised to the current value, which will still be the current value
196 * when the first task starts executing. */
197 trapa( portSTART_SCHEDULER_TRAP_NO );
199 /* Should not get here. */
202 /*-----------------------------------------------------------*/
204 void vPortEndScheduler( void )
206 /* Not implemented as there is nothing to return to. */
208 /*-----------------------------------------------------------*/
210 void vPortYield( void )
212 int32_t lInterruptMask;
214 /* Ensure the yield trap runs at the same priority as the other interrupts
215 * that can cause a context switch. */
216 lInterruptMask = get_imask();
218 /* taskYIELD() can only be called from a task, not an interrupt, so the
219 * current interrupt mask can only be 0 or portKERNEL_INTERRUPT_PRIORITY and
220 * the mask can be set without risk of accidentally lowering the mask value. */
221 set_imask( portKERNEL_INTERRUPT_PRIORITY );
223 trapa( portYIELD_TRAP_NO );
225 /* Restore the interrupt mask to whatever it was previously (when the
226 * function was entered). */
227 set_imask( ( int ) lInterruptMask );
229 /*-----------------------------------------------------------*/
231 BaseType_t xPortUsesFloatingPoint( TaskHandle_t xTask )
233 uint32_t * pulFlopBuffer;
235 extern void * volatile pxCurrentTCB;
237 /* This function tells the kernel that the task referenced by xTask is
238 * going to use the floating point registers and therefore requires the
239 * floating point registers saved as part of its context. */
241 /* Passing NULL as xTask is used to indicate that the calling task is the
242 * subject task - so pxCurrentTCB is the task handle. */
245 xTask = ( TaskHandle_t ) pxCurrentTCB;
248 /* Allocate a buffer large enough to hold all the flop registers. */
249 pulFlopBuffer = ( uint32_t * ) pvPortMalloc( portFLOP_STORAGE_SIZE );
251 if( pulFlopBuffer != NULL )
253 /* Start with the registers in a benign state. */
254 memset( ( void * ) pulFlopBuffer, 0x00, portFLOP_STORAGE_SIZE );
256 /* The first thing to get saved in the buffer is the FPSCR value -
257 * initialise this to the current FPSCR value. */
258 *pulFlopBuffer = get_fpscr();
260 /* Use the task tag to point to the flop buffer. Pass pointer to just
261 * above the buffer because the flop save routine uses a pre-decrement. */
262 vTaskSetApplicationTaskTag( xTask, ( void * ) ( pulFlopBuffer + portFLOP_REGISTERS_TO_STORE ) );
272 /*-----------------------------------------------------------*/