1 /*
2 * FreeRTOS Kernel V10.2.1
3 * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
6 * this software and associated documentation files (the "Software"), to deal in
7 * the Software without restriction, including without limitation the rights to
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 * the Software, and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * http://www.FreeRTOS.org
23 * http://aws.amazon.com/freertos
24 *
25 * 1 tab == 4 spaces!
26 */
27
28 /* Standard includes. */
29 #include <stdlib.h>
30 #include <string.h>
31
32 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
33 all the API functions to use the MPU wrappers. That should only be done when
34 task.h is included from an application file. */
35 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
36
37
38 /* esp_osal includes. */
39 #include "esp_osal.h"
40 #include "task.h"
41 #include "timers.h"
42 #include "stack_macros.h"
43 #include "los_task.h"
44 #include "los_sched.h"
45 #include "xtensa_rtos.h"
46 #include "esp_task_wdt.h"
47
48 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
49 /*-----------------------------------------------------------*/
50 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
51
xTaskCreatePinnedToCore(TaskFunction_t pvTaskCode,const char * const pcName,const uint32_t usStackDepth,void * const pvParameters,UBaseType_t uxPriority,TaskHandle_t * const pvCreatedTask,const BaseType_t xCoreID)52 BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pvTaskCode,
53 const char * const pcName,
54 const uint32_t usStackDepth,
55 void * const pvParameters,
56 UBaseType_t uxPriority,
57 TaskHandle_t * const pvCreatedTask,
58 const BaseType_t xCoreID)
59 {
60 UINT32 taskID1 = 0, ret;
61 TSK_INIT_PARAM_S attr = { 0 };
62 static char defName[] = {"null"};
63 attr.pfnTaskEntry = (TSK_ENTRY_FUNC)(int)pvTaskCode;
64 attr.uwStackSize = usStackDepth + 256;
65 attr.pcName = pcName ? pcName : defName;
66 attr.usTaskPrio = configMAX_PRIORITIES - 1 - uxPriority;// ((uxPriority * 31) / configMAX_PRIORITIES);
67 attr.uwArg = (UINT32)pvParameters;
68 if(attr.uwStackSize < 4096)attr.uwStackSize = 4096;
69 ret = LOS_TaskCreate(&taskID1, &attr);
70 if(pvCreatedTask) *pvCreatedTask = (TaskHandle_t)taskID1;
71 // esp_rom_printf("\n\e[1;36mxTaskCreate.%s stack=%d Priority=%d id=%d\e[0m\n",pcName,usStackDepth,uxPriority,taskID1);
72 return (LOS_OK == ret) ? pdPASS : errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
73 }
74
75 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
76 /*----------------------------------------------------------*/
__getreent(void)77 struct _reent* __getreent(void) {return _GLOBAL_REENT;}
78 /*----------------------------------------------------------*/
79 extern unsigned port_interruptNesting[];
80 #if 0
81 static portMUX_TYPE Kernel_spinlock = portMUX_INITIALIZER_UNLOCKED;
82 UINT32 ArchIntLock(VOID)
83 {
84 if(port_interruptNesting[0]) {
85 taskENTER_CRITICAL_ISR(&Kernel_spinlock);
86 }else {
87 taskENTER_CRITICAL(&Kernel_spinlock);
88 }
89 return 0;
90 }
91 VOID ArchIntRestore(UINT32 intSave)
92 {
93 if(port_interruptNesting[0]) {
94 taskEXIT_CRITICAL_ISR(&Kernel_spinlock);
95 }else {
96 taskEXIT_CRITICAL(&Kernel_spinlock);
97 }
98 }
99 #else
100 //UINT32 ArchIntLock(VOID) {return portENTER_CRITICAL_NESTED();}
101 //VOID ArchIntRestore(UINT32 intSave) {portEXIT_CRITICAL_NESTED(intSave);}
ArchIntLock(VOID)102 UINT32 ArchIntLock(VOID)
103 {
104 UINT32 tmp;
105 __asm__ __volatile__("rsil %0, 3\n": "=a"(tmp): :"memory");
106 return tmp;
107 }
ArchIntRestore(UINT32 intSave)108 VOID ArchIntRestore(UINT32 intSave)
109 {
110 __asm__ __volatile__("wsr %0, ps\n": :"a"(intSave):"memory");
111 }
112 #endif
113
xTaskGetAffinity(TaskHandle_t xTask)114 BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
115 {
116 return 0;
117 }
118
pcTaskGetName(TaskHandle_t xTaskToQuery)119 char *pcTaskGetName( TaskHandle_t xTaskToQuery )
120 {
121 return LOS_TaskNameGet((UINT32)xTaskToQuery);
122 }
123
xTaskGetIdleTaskHandleForCPU(UBaseType_t cpuid)124 TaskHandle_t xTaskGetIdleTaskHandleForCPU( UBaseType_t cpuid )
125 {
126 return (TaskHandle_t)g_idleTaskID;
127 }
128
ArchIsIntActive(VOID)129 UINT32 ArchIsIntActive(VOID)
130 {
131 return port_interruptNesting[0];
132 }
133 /*----------------------------------------------------------*/
134 // xMPU_SETTINGS
135 #if ( portUSING_MPU_WRAPPERS == 1 )
136 _Static_assert(sizeof(xMPU_SETTINGS) >= sizeof(((LosTaskCB *)0)->MPUSettings),"sizeof(xMPU_SETTINGS) < sizeof(LosTaskCB.MPUSettings)");
137 _Static_assert(sizeof(xMPU_SETTINGS) <= sizeof(((LosTaskCB *)0)->MPUSettings),"sizeof(xMPU_SETTINGS) > sizeof(LosTaskCB.MPUSettings)");
138
139 _Static_assert(CP_TOPOFSTACK_OFFS >= (int)&((LosTaskCB *)0)->MPUSettings[0],"CP_TOPOFSTACK_OFFS < offset(LosTaskCB.MPUSettings)");
140 _Static_assert(CP_TOPOFSTACK_OFFS <= (int)&((LosTaskCB *)0)->MPUSettings[0],"CP_TOPOFSTACK_OFFS > offset(LosTaskCB.MPUSettings)");
141 #endif
142
vPortStoreTaskSettings(StackType_t * pxBottomOfStack,uint32_t usStackDepth,UINT32 taskID)143 void vPortStoreTaskSettings(StackType_t *pxBottomOfStack, uint32_t usStackDepth, UINT32 taskID)
144 {
145 // static_assert
146 LosTaskCB *pxNewTCB = OS_TCB_FROM_TID(taskID);
147 #if ( portUSING_MPU_WRAPPERS == 1 )
148 vPortStoreTaskMPUSettings( pxNewTCB->MPUSettings, NULL, pxBottomOfStack, usStackDepth );
149 // vPortStoreTaskMPUSettings((((char *)pxBottomOfStack) + sizeof(void *)), NULL, pxBottomOfStack, usStackDepth );
150 #endif
151 #if ( configUSE_MUTEXES == 1 )
152 {
153 pxNewTCB->basePriority = pxNewTCB->priority;
154 // pxNewTCB->mutexesHeld = 0;
155 }
156 #endif /* configUSE_MUTEXES */
157 }
xTaskGetSchedulerState(void)158 BaseType_t IRAM_ATTR xTaskGetSchedulerState( void )
159 {
160 extern BOOL g_taskScheduled;
161 extern UINT16 g_losTaskLock;
162 return g_taskScheduled ? (LOS_CHECK_SCHEDULE ? taskSCHEDULER_RUNNING : taskSCHEDULER_SUSPENDED) : taskSCHEDULER_NOT_STARTED;
163 }
vTaskDelete(TaskHandle_t xTaskToDelete)164 void vTaskDelete( TaskHandle_t xTaskToDelete )
165 {
166 if(!xTaskToDelete) LOS_TaskDelete(LOS_CurTaskIDGet());
167 else LOS_TaskDelete((UINT32)xTaskToDelete);
168 }
vTaskDelay(const TickType_t xTicksToDelay)169 void vTaskDelay( const TickType_t xTicksToDelay )
170 {
171 LOS_TaskDelay(xTicksToDelay);
172 }
xTaskGetCurrentTaskHandle(void)173 TaskHandle_t xTaskGetCurrentTaskHandle( void )
174 {
175 return (TaskHandle_t)LOS_CurTaskIDGet();
176 }
177
xTaskGetCurrentTaskHandleForCPU(BaseType_t cpuid)178 TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t cpuid )
179 {
180 return (TaskHandle_t)LOS_CurTaskIDGet();
181 }
182
183 #if 0
184 // TaskHandle_t xTaskGetCurrentTaskHandle( void );
185 struct {
186 TaskHandle_t handle;
187 void *pvValue;
188 }pthread_tls[4];
189 static volatile unsigned char pthread_tlsi = 0;
190 static void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex )
191 {
192 unsigned char maxi = pthread_tlsi;
193 if(!xTaskToQuery) xTaskToQuery = xTaskGetCurrentTaskHandle();
194 // ESP_LOGW("STL", "Get.handle:%p\n",xTaskToQuery);
195 for(unsigned char i = 0;i < maxi;++i) {
196 if(xTaskToQuery == pthread_tls[i].handle) return pthread_tls[i].pvValue;
197 }
198 return NULL;
199 }
200 static void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue , void *xDelCallback)
201 {
202 unsigned char maxi = pthread_tlsi;
203 if(!xTaskToSet) xTaskToSet = xTaskGetCurrentTaskHandle();
204 // ESP_LOGW("STL", "Set.handle:%p value:%p\n",xTaskToSet,pvValue);
205 for(unsigned char i = 0;i < maxi;++i) {
206 if(xTaskToSet == pthread_tls[i].handle) {pthread_tls[i].pvValue = pvValue;return;}
207 }
208 pthread_tlsi = maxi + 1;
209 pthread_tls[maxi].handle = xTaskToSet;
210 pthread_tls[maxi].pvValue = pvValue;
211 }
212 #else
pvTaskGetThreadLocalStoragePointer(TaskHandle_t handle,BaseType_t xIndex)213 void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t handle, BaseType_t xIndex )
214 {
215 UINT32 taskID = (UINT32)handle;
216 LosTaskCB *pxTCB;
217 if(!taskID) taskID = LOS_CurTaskIDGet();
218 if(xIndex >= sizeof(pxTCB->LocalStoragePointer)/sizeof(pxTCB->LocalStoragePointer[0])){
219 esp_rom_printf("\n\e[1;36m%s.xIndex=%d",__func__, xIndex);
220 return NULL;
221 }
222 pxTCB = OS_TCB_FROM_TID(taskID);
223 return pxTCB ? pxTCB->LocalStoragePointer[xIndex] : NULL;
224 }
vTaskSetThreadLocalStoragePointerAndDelCallback(TaskHandle_t handle,BaseType_t xIndex,void * pvValue,TlsDeleteCallbackFunction_t pvDelCallback)225 void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t handle, BaseType_t xIndex, void *pvValue, TlsDeleteCallbackFunction_t pvDelCallback)
226 {
227 UINT32 taskID = (UINT32)handle;
228 LosTaskCB *pxTCB;
229 if(!taskID) taskID = LOS_CurTaskIDGet();
230 if(xIndex >= sizeof(pxTCB->LocalStoragePointer)/sizeof(pxTCB->LocalStoragePointer[0])){
231 esp_rom_printf("\n\e[1;36m%s.xIndex=%d\e[0m\n",__func__, xIndex);
232 return;
233 }
234 pxTCB = OS_TCB_FROM_TID(taskID);
235 if(pxTCB) {
236 pxTCB->LocalStoragePointer[xIndex] = pvValue;
237 if(xIndex < sizeof(pxTCB->LocalDelCallback)/sizeof(pxTCB->LocalDelCallback[0])){
238 pxTCB->LocalDelCallback[xIndex] = (void *)pvDelCallback;
239 }
240 }
241 }
TaskDeleteExtensionHook(void * tcb)242 void TaskDeleteExtensionHook(void *tcb)
243 {
244 LosTaskCB *pxTCB = (LosTaskCB *)tcb;
245 if(pxTCB) {
246 for(unsigned i = 0;i < sizeof(pxTCB->LocalDelCallback)/sizeof(pxTCB->LocalDelCallback[0]); ++i) {
247 if(pxTCB->LocalDelCallback[i]) {
248 ((TlsDeleteCallbackFunction_t)pxTCB->LocalDelCallback[i])(i,pxTCB->LocalStoragePointer[i]);
249 }
250 }
251 }
252 }
253 #endif
254
255