1 /*
2 * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy of
7 * this software and associated documentation files (the "Software"), to deal in
8 * the Software without restriction, including without limitation the rights to
9 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 * the Software, and to permit persons to whom the Software is furnished to do so,
11 * subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 */
24
25 /* Kernel includes. */
26 #include "FreeRTOS.h"
27 #include "task.h"
28
29 extern void vPortStartTask( void );
30
31 /* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
32 * will be set to 0 prior to the first task being started. */
33 portLONG ulCriticalNesting = 0x9999UL;
34
35 /* Used to record one tack want to switch task after enter critical area, we need know it
36 * and implement task switch after exit critical area */
37 portLONG pendsvflag = 0;
38
pxPortInitialiseStack(StackType_t * pxTopOfStack,TaskFunction_t pxCode,void * pvParameters)39 StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
40 TaskFunction_t pxCode,
41 void * pvParameters )
42 {
43 StackType_t * stk = NULL;
44
45 stk = pxTopOfStack;
46
47 *( --stk ) = ( uint32_t ) pxCode; /* Entry Point */
48 *( --stk ) = ( uint32_t ) 0xE0000140L; /* PSR */
49 *( --stk ) = ( uint32_t ) 0xFFFFFFFEL; /* R15 (LR) (init value will cause fault if ever used) */
50 *( --stk ) = ( uint32_t ) 0x13131313L; /* R13 */
51 *( --stk ) = ( uint32_t ) 0x12121212L; /* R12 */
52 *( --stk ) = ( uint32_t ) 0x11111111L; /* R11 */
53 *( --stk ) = ( uint32_t ) 0x10101010L; /* R10 */
54 *( --stk ) = ( uint32_t ) 0x09090909L; /* R9 */
55 *( --stk ) = ( uint32_t ) 0x08080808L; /* R8 */
56 *( --stk ) = ( uint32_t ) 0x07070707L; /* R7 */
57 *( --stk ) = ( uint32_t ) 0x06060606L; /* R6 */
58 *( --stk ) = ( uint32_t ) 0x05050505L; /* R5 */
59 *( --stk ) = ( uint32_t ) 0x04040404L; /* R4 */
60 *( --stk ) = ( uint32_t ) 0x03030303L; /* R3 */
61 *( --stk ) = ( uint32_t ) 0x02020202L; /* R2 */
62 *( --stk ) = ( uint32_t ) 0x01010101L; /* R1 */
63 *( --stk ) = ( uint32_t ) pvParameters; /* R0 : argument */
64
65 return stk;
66 }
67
xPortStartScheduler(void)68 BaseType_t xPortStartScheduler( void )
69 {
70 ulCriticalNesting = 0UL;
71
72 vPortStartTask();
73
74 return pdFALSE;
75 }
76
77
vPortEndScheduler(void)78 void vPortEndScheduler( void )
79 {
80 /* Not implemented as there is nothing to return to. */
81 }
82
vPortEnterCritical(void)83 void vPortEnterCritical( void )
84 {
85 portDISABLE_INTERRUPTS();
86 ulCriticalNesting++;
87 }
88
vPortExitCritical(void)89 void vPortExitCritical( void )
90 {
91 if( ulCriticalNesting == 0 )
92 {
93 while( 1 )
94 {
95 }
96 }
97
98 ulCriticalNesting--;
99
100 if( ulCriticalNesting == 0 )
101 {
102 portENABLE_INTERRUPTS();
103
104 if( pendsvflag )
105 {
106 pendsvflag = 0;
107 portYIELD();
108 }
109 }
110 }
111
112 #if configUSE_PREEMPTION == 0
xPortSysTickHandler(void)113 void xPortSysTickHandler( void )
114 {
115 portLONG ulDummy;
116
117 ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
118 xTaskIncrementTick();
119 portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
120 }
121
122 #else
xPortSysTickHandler(void)123 void xPortSysTickHandler( void )
124 {
125 portLONG ulDummy;
126
127 ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
128 traceISR_ENTER();
129 {
130 if( xTaskIncrementTick() != pdFALSE )
131 {
132 traceISR_EXIT_TO_SCHEDULER();
133 portYIELD_FROM_ISR( pdTRUE );
134 }
135 else
136 {
137 traceISR_EXIT();
138 }
139 }
140 portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
141 }
142 #endif /* if configUSE_PREEMPTION == 0 */
143
vPortYieldHandler(void)144 void vPortYieldHandler( void )
145 {
146 uint32_t ulSavedInterruptMask;
147
148 ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
149
150 vTaskSwitchContext();
151
152 portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
153 }
154
vApplicationStackOverflowHook(xTaskHandle * pxTask,signed portCHAR * pcTaskName)155 __attribute__( ( weak ) ) void vApplicationStackOverflowHook( xTaskHandle * pxTask,
156 signed portCHAR * pcTaskName )
157 {
158 for( ; ; )
159 {
160 }
161 }
162
vApplicationMallocFailedHook(void)163 __attribute__( ( weak ) ) void vApplicationMallocFailedHook( void )
164 {
165 for( ; ; )
166 {
167 }
168 }
169