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 swtich 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, TaskFunction_t pxCode, void *pvParameters )
40 {
41 StackType_t *stk = NULL;
42
43 stk = pxTopOfStack;
44
45 *(--stk) = (uint32_t)pxCode; /* Entry Point */
46 *(--stk) = (uint32_t)0xE0000140L; /* PSR */
47 *(--stk) = (uint32_t)0xFFFFFFFEL; /* R15 (LR) (init value will cause fault if ever used) */
48 *(--stk) = (uint32_t)0x13131313L; /* R13 */
49 *(--stk) = (uint32_t)0x12121212L; /* R12 */
50 *(--stk) = (uint32_t)0x11111111L; /* R11 */
51 *(--stk) = (uint32_t)0x10101010L; /* R10 */
52 *(--stk) = (uint32_t)0x09090909L; /* R9 */
53 *(--stk) = (uint32_t)0x08080808L; /* R8 */
54 *(--stk) = (uint32_t)0x07070707L; /* R7 */
55 *(--stk) = (uint32_t)0x06060606L; /* R6 */
56 *(--stk) = (uint32_t)0x05050505L; /* R5 */
57 *(--stk) = (uint32_t)0x04040404L; /* R4 */
58 *(--stk) = (uint32_t)0x03030303L; /* R3 */
59 *(--stk) = (uint32_t)0x02020202L; /* R2 */
60 *(--stk) = (uint32_t)0x01010101L; /* R1 */
61 *(--stk) = (uint32_t)pvParameters; /* R0 : argument */
62
63 return stk;
64 }
65
xPortStartScheduler(void)66 BaseType_t xPortStartScheduler( void )
67 {
68 ulCriticalNesting = 0UL;
69
70 vPortStartTask();
71
72 return pdFALSE;
73 }
74
75
vPortEndScheduler(void)76 void vPortEndScheduler( void )
77 {
78 /* Not implemented as there is nothing to return to. */
79 }
80
vPortEnterCritical(void)81 void vPortEnterCritical( void )
82 {
83 portDISABLE_INTERRUPTS();
84 ulCriticalNesting ++;
85 }
86
vPortExitCritical(void)87 void vPortExitCritical( void )
88 {
89 if (ulCriticalNesting == 0) {
90 while(1);
91 }
92
93 ulCriticalNesting --;
94 if (ulCriticalNesting == 0)
95 {
96 portENABLE_INTERRUPTS();
97
98 if (pendsvflag)
99 {
100 pendsvflag = 0;
101 portYIELD();
102 }
103 }
104 }
105
106 #if configUSE_PREEMPTION == 0
xPortSysTickHandler(void)107 void xPortSysTickHandler( void )
108 {
109 portLONG ulDummy;
110
111 ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
112 xTaskIncrementTick();
113 portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
114 }
115
116 #else
xPortSysTickHandler(void)117 void xPortSysTickHandler( void )
118 {
119 portLONG ulDummy;
120
121 ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
122 {
123 if (xTaskIncrementTick() != pdFALSE)
124 {
125 portYIELD_FROM_ISR(pdTRUE);
126 }
127 }
128 portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
129 }
130 #endif
131
vPortYieldHandler(void)132 void vPortYieldHandler( void )
133 {
134 uint32_t ulSavedInterruptMask;
135
136 ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
137
138 vTaskSwitchContext();
139
140 portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
141 }
142
vApplicationStackOverflowHook(xTaskHandle * pxTask,signed portCHAR * pcTaskName)143 __attribute__((weak)) void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTaskName )
144 {
145 for(;;);
146 }
147
vApplicationMallocFailedHook(void)148 __attribute__((weak)) void vApplicationMallocFailedHook( void )
149 {
150 for(;;);
151 }
152