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