Toyomasa Watarai
/
Mbed-example-WS-W27
Mbed Cloud example program for workshop in W27 2018.
Embed:
(wiki syntax)
Show/hide line numbers
pal_plat_rtos.cpp
00001 /* 00002 * Copyright (c) 2016 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 00018 00019 00020 #include "pal_types.h" 00021 #include "pal_rtos.h" 00022 #include "pal_plat_rtos.h" 00023 #include "pal_errors.h" 00024 #include "stdlib.h" 00025 #include "string.h" 00026 00027 #include "mbed.h" 00028 00029 #include "entropy_poll.h" 00030 00031 00032 /* 00033 mbedOS latest version RTOS support 00034 */ 00035 #if defined(osRtxVersionAPI) && (osRtxVersionAPI >= 20000000) 00036 00037 #include "cmsis_os2.h" // Revision: V2.1 00038 00039 00040 #define PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(cmsisCode)\ 00041 ((int32_t)((int32_t)cmsisCode + PAL_ERR_RTOS_ERROR_BASE)) 00042 00043 typedef struct palThreadFuncWrapper{ 00044 palTimerFuncPtr realThreadFunc; 00045 void* realThreadArgs; 00046 uint32_t threadIndex; 00047 }palThreadFuncWrapper_t; 00048 00049 //! Thread structure 00050 typedef struct palThread{ 00051 palThreadID_t threadID; 00052 uint32_t palThreadID; 00053 bool initialized; 00054 palThreadLocalStore_t* threadStore; //! please see pal_rtos.h for documentation 00055 palThreadFuncWrapper_t threadFuncWrapper; 00056 osThreadAttr_t osThread; 00057 mbed_rtos_storage_thread_t osThreadStorage; 00058 } palThread_t; 00059 00060 /*! Count number of created threads. Initiate to zero. 00061 */ 00062 PAL_PRIVATE uint32_t g_threadCounter = 0; 00063 palThread_t g_palThreads[PAL_MAX_NUMBER_OF_THREADS] = {0}; 00064 00065 //! Timer structure 00066 typedef struct palTimer{ 00067 palTimerID_t timerID; 00068 osTimerAttr_t osTimer; 00069 mbed_rtos_storage_timer_t osTimerStorage; 00070 } palTimer_t; 00071 00072 //! Mutex structure 00073 typedef struct palMutex{ 00074 palMutexID_t mutexID; 00075 osMutexAttr_t osMutex; 00076 mbed_rtos_storage_mutex_t osMutexStorage; 00077 }palMutex_t; 00078 00079 //! Semaphore structure 00080 typedef struct palSemaphore{ 00081 palSemaphoreID_t semaphoreID; 00082 osSemaphoreAttr_t osSemaphore; 00083 mbed_rtos_storage_semaphore_t osSemaphoreStorage; 00084 }palSemaphore_t; 00085 00086 //! Memoey Pool structure 00087 typedef struct palMemPool{ 00088 palMemoryPoolID_t memoryPoolID; 00089 osMemoryPoolAttr_t osPool; 00090 mbed_rtos_storage_mem_pool_t osPoolStorage; 00091 uint32_t blockSize; 00092 }palMemoryPool_t; 00093 00094 //! Message Queue structure 00095 typedef struct palMessageQ{ 00096 palMessageQID_t messageQID; 00097 osMessageQueueAttr_t osMessageQ; 00098 mbed_rtos_storage_msg_queue_t osMessageQStorage; 00099 }palMessageQ_t; 00100 00101 //! thread cleanup timer argument structure 00102 typedef struct palThreadCleanupData { 00103 palTimerID_t timerID; 00104 palThreadID_t threadToCleanUp; 00105 void* threadStackMem; 00106 }palThreadCleanupData_t; 00107 00108 00109 00110 inline PAL_PRIVATE int mapThreadPriorityToPlatSpecific(palThreadPriority_t priority) 00111 { 00112 int adjustedPriority = -1; 00113 00114 switch (priority) 00115 { 00116 case PAL_osPriorityIdle: 00117 adjustedPriority = osPriorityIdle; 00118 break; 00119 00120 case PAL_osPriorityLow: 00121 adjustedPriority = osPriorityLow; 00122 break; 00123 00124 case PAL_osPriorityBelowNormal: 00125 adjustedPriority = osPriorityBelowNormal; 00126 break; 00127 00128 case PAL_osPriorityNormal: 00129 adjustedPriority = osPriorityNormal; 00130 break; 00131 00132 case PAL_osPriorityAboveNormal: 00133 adjustedPriority = osPriorityAboveNormal; 00134 break; 00135 00136 case PAL_osPriorityHigh: 00137 adjustedPriority = osPriorityHigh; 00138 break; 00139 00140 case PAL_osPriorityRealtime: 00141 adjustedPriority = osPriorityRealtime; 00142 break; 00143 00144 case PAL_osPriorityError: 00145 adjustedPriority = osPriorityError; 00146 break; 00147 00148 default: 00149 adjustedPriority = osPriorityNone; 00150 break; 00151 } 00152 00153 return adjustedPriority; 00154 } 00155 00156 00157 inline PAL_PRIVATE palThreadPriority_t mapThreadPriorityToPalGeneric(int priority) 00158 { 00159 palThreadPriority_t adjustedPriority = PAL_osPriorityError; 00160 00161 switch (priority) 00162 { 00163 case osPriorityIdle: 00164 adjustedPriority = PAL_osPriorityIdle; 00165 break; 00166 00167 case osPriorityLow : 00168 adjustedPriority = PAL_osPriorityLow; 00169 break; 00170 00171 case osPriorityBelowNormal : 00172 adjustedPriority = PAL_osPriorityBelowNormal; 00173 break; 00174 00175 case osPriorityNormal : 00176 adjustedPriority = PAL_osPriorityNormal; 00177 break; 00178 00179 case osPriorityAboveNormal : 00180 adjustedPriority = PAL_osPriorityAboveNormal; 00181 break; 00182 00183 case osPriorityHigh : 00184 adjustedPriority = PAL_osPriorityHigh; 00185 break; 00186 00187 case osPriorityRealtime : 00188 adjustedPriority = PAL_osPriorityRealtime; 00189 break; 00190 00191 case osPriorityError: 00192 default: 00193 adjustedPriority = PAL_osPriorityError; 00194 break; 00195 } 00196 00197 return adjustedPriority; 00198 } 00199 00200 00201 inline PAL_PRIVATE void setDefaultThreadValues(palThread_t* thread) 00202 { 00203 #if PAL_UNIQUE_THREAD_PRIORITY 00204 palThreadPriority_t threadGenericPriority = mapThreadPriorityToPalGeneric(thread->osThread.priority); 00205 g_palThreadPriorities[threadGenericPriority+PRIORITY_INDEX_OFFSET] = 0; 00206 #endif //PAL_UNIQUE_THREAD_PRIORITY 00207 thread->threadStore = NULL; 00208 thread->threadFuncWrapper.realThreadArgs = NULL; 00209 thread->threadFuncWrapper.realThreadFunc = NULL; 00210 thread->threadFuncWrapper.threadIndex = 0; 00211 00212 thread->threadID = NULLPTR; 00213 thread->palThreadID = 0; 00214 //! This line should be last thing to be done in this function. 00215 //! in order to prevent double accessing the same index between 00216 //! this function and the threadCreate function. 00217 thread->initialized = false; 00218 } 00219 00220 /*! Clean thread data from the global thread data base (g_palThreads). Thread Safe API 00221 * 00222 * @param[in] index: the index in the data base to be cleaned. 00223 */ 00224 PAL_PRIVATE void threadCleanUp( uint32_t threadID) 00225 { 00226 uint32_t status = PAL_SUCCESS; 00227 uint32_t threadIndex = PAL_GET_THREAD_INDEX(threadID); 00228 00229 status = pal_osMutexWait(g_palThreadInitMutex, PAL_RTOS_WAIT_FOREVER); 00230 if (PAL_SUCCESS != status) 00231 { 00232 PAL_LOG(ERR,"thread cleanup: mutex wait failed!\n"); 00233 } 00234 else{ 00235 if ((NULL != g_palThreads) && (threadIndex < PAL_MAX_NUMBER_OF_THREADS) && (g_palThreads[threadIndex].palThreadID == threadID)) 00236 { 00237 setDefaultThreadValues(&g_palThreads[threadIndex]); 00238 } 00239 00240 status = pal_osMutexRelease(g_palThreadInitMutex); 00241 if (PAL_SUCCESS != status) 00242 { 00243 PAL_LOG(ERR,"thread cleanup: mutex release failed!\n"); 00244 } 00245 } 00246 return; 00247 } 00248 00249 00250 00251 /*! Thread Cleanup timer. This is a timer funciton dedicated to deallocating the thread stack in case if it exits naturally (not via thread Terminate). 00252 * 00253 * @param[in] arg: data structure which contains the data about the thread to clean up. 00254 */ 00255 PAL_PRIVATE void threadCleanupTimer(const void* arg) 00256 { 00257 osThreadState_t threadState = osThreadError; 00258 palThreadCleanupData_t* threadCleanupData = (palThreadCleanupData_t*) arg; 00259 palTimerID_t localtimerID = threadCleanupData->timerID; 00260 00261 threadState = osThreadGetState((osThreadId_t)(threadCleanupData->threadToCleanUp)); 00262 if ((threadState == osThreadTerminated) || (threadState == osThreadInactive)) // thread has ended, can clean up. 00263 { 00264 free(threadCleanupData->threadStackMem); // free the thread stack memory. 00265 free(threadCleanupData); // free the thread cleanup data. 00266 pal_osTimerDelete(&localtimerID); 00267 } 00268 else // Thread not ended yet, wait another PAL_RTOS_THREAD_CLEANUP_TIMER_MILISEC ms. 00269 { 00270 if (osThreadError == threadState) 00271 { 00272 PAL_LOG(DBG,"thread Cleanup Timer: error getting thread status\n"); 00273 } 00274 else 00275 { 00276 palStatus_t status = pal_osTimerStart(threadCleanupData->timerID, PAL_RTOS_THREAD_CLEANUP_TIMER_MILISEC); 00277 if (PAL_SUCCESS != status) 00278 { 00279 PAL_LOG(ERR,"thread Cleanup Timer: timer start failed - thread stack memory leak likely!\n"); 00280 } 00281 } 00282 } 00283 00284 } 00285 00286 00287 00288 /*! Thread wrapper function, this function will be set as the thread function (for every thread) 00289 * and it will get as an argument the real data about the thread and call the REAL thread function 00290 * with the REAL argument. 00291 * 00292 * @param[in] arg: data structure which contains the real data about the thread. 00293 */ 00294 PAL_PRIVATE void threadFunctionWrapper(void* arg) 00295 { 00296 palThreadFuncWrapper_t* threadWrapper = (palThreadFuncWrapper_t*)arg; 00297 palThreadCleanupData_t* threadCleanupData = NULL; 00298 palTimerID_t localTimerID = 0; 00299 00300 if (NULL != threadWrapper) 00301 { 00302 if(g_palThreads[threadWrapper->threadIndex].threadID == NULLPTR) 00303 { 00304 g_palThreads[threadWrapper->threadIndex].threadID = (palThreadID_t)osThreadGetId(); 00305 } 00306 threadWrapper->realThreadFunc(threadWrapper->realThreadArgs); 00307 00308 threadCleanupData = (palThreadCleanupData_t*)malloc(sizeof(palThreadCleanupData_t)); 00309 if (NULL == threadCleanupData) 00310 { 00311 PAL_LOG(ERR,"thread cleanup: timer data allocation failed - thread stack memory leak likely!\n"); 00312 } 00313 else 00314 { 00315 palStatus_t status = pal_osTimerCreate(threadCleanupTimer, threadCleanupData, palOsTimerOnce, &localTimerID); 00316 if (PAL_SUCCESS != status) 00317 { 00318 PAL_LOG(ERR,"thread cleanup: timer create failed - thread stack memory leak likely!\n"); 00319 } 00320 else 00321 { 00322 threadCleanupData->timerID = localTimerID; 00323 threadCleanupData->threadToCleanUp = g_palThreads[threadWrapper->threadIndex].threadID; 00324 threadCleanupData->threadStackMem = g_palThreads[threadWrapper->threadIndex].osThread.stack_mem; 00325 status = pal_osTimerStart(localTimerID, PAL_RTOS_THREAD_CLEANUP_TIMER_MILISEC); 00326 if (PAL_SUCCESS != status) 00327 { 00328 PAL_LOG(ERR,"thread cleanup: timer start failed - thread stack memory leak likely!\n"); 00329 } 00330 } 00331 } 00332 00333 threadCleanUp(g_palThreads[threadWrapper->threadIndex].palThreadID); // clean up everything except deallocating stack 00334 } 00335 } 00336 00337 00338 void pal_plat_osReboot () 00339 { 00340 NVIC_SystemReset(); 00341 } 00342 00343 00344 palStatus_t pal_plat_RTOSInitialize (void* opaqueContext) 00345 { 00346 //Clean thread tables 00347 palStatus_t status = PAL_SUCCESS; 00348 00349 memset(g_palThreads,0,sizeof(palThread_t) * PAL_MAX_NUMBER_OF_THREADS); 00350 00351 //Add implicit the running task as PAL main 00352 g_palThreads[0].initialized = true; 00353 g_palThreads[0].threadID = (palThreadID_t)osThreadGetId(); 00354 g_palThreads[0].osThread.stack_mem = NULL; 00355 00356 pal_osAtomicIncrement((int32_t*)&g_threadCounter,1); 00357 //palThreadID = 24 bits for thread counter + lower 8 bits for thread index (= 0). 00358 g_palThreads[0].palThreadID = (g_threadCounter << 8 ); 00359 00360 return status; 00361 } 00362 00363 00364 00365 palStatus_t pal_plat_RTOSDestroy (void) 00366 { 00367 return PAL_SUCCESS; 00368 } 00369 00370 00371 palStatus_t pal_plat_osDelay (uint32_t milliseconds) 00372 { 00373 palStatus_t status; 00374 osStatus_t platStatus = osDelay(milliseconds); 00375 if (osOK == platStatus) 00376 { 00377 status = PAL_SUCCESS; 00378 } 00379 else 00380 { 00381 status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); //TODO(nirson01): error propagation MACRO?? 00382 } 00383 return status; 00384 } 00385 00386 uint64_t pal_plat_osKernelSysTick (void) 00387 { 00388 uint64_t result; 00389 result = osKernelGetTickCount(); 00390 return result; 00391 } 00392 00393 uint64_t pal_plat_osKernelSysTickMicroSec (uint64_t microseconds) 00394 { 00395 uint64_t result; 00396 result = (((uint64_t)microseconds * (osKernelGetTickFreq())) / 1000000); 00397 00398 return result; 00399 } 00400 00401 uint64_t pal_plat_osKernelSysTickFrequency () 00402 { 00403 return osKernelGetTickFreq(); 00404 } 00405 00406 palStatus_t pal_plat_osThreadCreate (palThreadFuncPtr function, void* funcArgument, palThreadPriority_t priority, uint32_t stackSize, uint32_t* stackPtr, palThreadLocalStore_t* store, palThreadID_t* threadID) 00407 { 00408 palStatus_t status = PAL_SUCCESS; 00409 uint32_t firstAvailableThreadIndex = PAL_MAX_NUMBER_OF_THREADS; 00410 uint32_t i; 00411 uint32_t *stackAllocPtr = NULL; 00412 osThreadId_t osThreadID = NULL; 00413 uint32_t localPalThreadID = 0; 00414 00415 00416 if (NULL == threadID || NULL == function || 0 == stackSize || priority > PAL_osPriorityRealtime) 00417 { 00418 return PAL_ERR_INVALID_ARGUMENT ; 00419 } 00420 00421 status = pal_osMutexWait(g_palThreadInitMutex, PAL_RTOS_WAIT_FOREVER); 00422 if (PAL_SUCCESS == status) 00423 { 00424 for (i = 0; i < PAL_MAX_NUMBER_OF_THREADS; ++i) 00425 { 00426 if (!g_palThreads[i].initialized) 00427 { 00428 g_palThreads[i].initialized = true; 00429 firstAvailableThreadIndex = i; 00430 break; 00431 } 00432 } 00433 00434 if (firstAvailableThreadIndex >= PAL_MAX_NUMBER_OF_THREADS) 00435 { 00436 status = PAL_ERR_RTOS_RESOURCE ; 00437 } 00438 00439 if (PAL_SUCCESS == status) 00440 { 00441 stackAllocPtr = (uint32_t*)malloc(stackSize); 00442 if(NULL == stackAllocPtr) 00443 { 00444 status = PAL_ERR_RTOS_RESOURCE ; 00445 } 00446 } 00447 00448 if (PAL_SUCCESS != status) 00449 { 00450 // release mutex if error. 00451 status = pal_osMutexRelease(g_palThreadInitMutex); 00452 } 00453 else 00454 { 00455 g_palThreads[firstAvailableThreadIndex].threadStore = store; 00456 g_palThreads[firstAvailableThreadIndex].threadFuncWrapper.realThreadArgs = funcArgument; 00457 g_palThreads[firstAvailableThreadIndex].threadFuncWrapper.realThreadFunc = function; 00458 g_palThreads[firstAvailableThreadIndex].threadFuncWrapper.threadIndex = firstAvailableThreadIndex; 00459 g_palThreads[firstAvailableThreadIndex].osThread.priority = (osPriority_t)mapThreadPriorityToPlatSpecific(priority); 00460 g_palThreads[firstAvailableThreadIndex].osThread.stack_size = stackSize; 00461 g_palThreads[firstAvailableThreadIndex].osThread.stack_mem = stackAllocPtr; 00462 g_palThreads[firstAvailableThreadIndex].osThread.cb_mem = &(g_palThreads[firstAvailableThreadIndex].osThreadStorage); 00463 g_palThreads[firstAvailableThreadIndex].osThread.cb_size = sizeof(g_palThreads[firstAvailableThreadIndex].osThreadStorage); 00464 g_palThreads[firstAvailableThreadIndex].palThreadID = ((firstAvailableThreadIndex) + ((pal_osAtomicIncrement((int32_t*)&g_threadCounter, 1)) << 8)); //palThreadID = 24 bits for thread counter + lower 8 bits for thread index. 00465 memset(&(g_palThreads[firstAvailableThreadIndex].osThreadStorage), 0, sizeof(g_palThreads[firstAvailableThreadIndex].osThreadStorage)); 00466 00467 localPalThreadID = g_palThreads[firstAvailableThreadIndex].palThreadID; // save Thread ID value localy in case thread exists (and table is cleared) before funciton completes. 00468 00469 // release mutex before thread creation . 00470 status = pal_osMutexRelease(g_palThreadInitMutex); 00471 00472 if (PAL_SUCCESS == status) 00473 { 00474 osThreadID = osThreadNew(threadFunctionWrapper, &g_palThreads[firstAvailableThreadIndex].threadFuncWrapper, &g_palThreads[firstAvailableThreadIndex].osThread); 00475 g_palThreads[firstAvailableThreadIndex].threadID = (palThreadID_t)osThreadID; 00476 if(NULL == osThreadID) 00477 { 00478 //! in case of error in the thread creation, reset the data of the given index in the threads array. 00479 threadCleanUp(g_palThreads[firstAvailableThreadIndex].palThreadID); 00480 00481 if (NULL != g_palThreads[firstAvailableThreadIndex].osThread.stack_mem) 00482 { 00483 free(g_palThreads[firstAvailableThreadIndex].osThread.stack_mem); 00484 g_palThreads[firstAvailableThreadIndex].osThread.stack_mem = NULL; 00485 } 00486 status = PAL_ERR_GENERIC_FAILURE; 00487 *threadID = PAL_INVALID_THREAD; 00488 } 00489 else 00490 { 00491 *threadID = localPalThreadID; // here we use the thread may have already exited and cleared the table so local copy of ID is used. 00492 } 00493 } 00494 } 00495 } 00496 return status; 00497 } 00498 00499 palThreadID_t pal_plat_osThreadGetId (void) 00500 { 00501 int i = 0; 00502 palThreadID_t osThreadID; 00503 palThreadID_t ret = PAL_INVALID_THREAD; 00504 osThreadID = (palThreadID_t)osThreadGetId(); 00505 00506 for(i= 0; i < PAL_MAX_NUMBER_OF_THREADS; i++) 00507 { 00508 if(osThreadID == g_palThreads[i].threadID) 00509 { 00510 ret = i; 00511 break; 00512 } 00513 } 00514 return ret; 00515 } 00516 00517 palStatus_t pal_plat_osThreadTerminate (palThreadID_t* threadID) 00518 { 00519 palStatus_t status = PAL_ERR_INVALID_ARGUMENT ; 00520 osStatus_t platStatus = osOK; 00521 osThreadState_t threadState = osThreadError; 00522 uint32_t threadIndex = PAL_GET_THREAD_INDEX(*threadID); 00523 00524 if ((PAL_INVALID_THREAD == *threadID) || (threadIndex >= PAL_MAX_NUMBER_OF_THREADS)) 00525 { 00526 return PAL_ERR_INVALID_ARGUMENT ; 00527 } 00528 00529 // if thread exited or was terminated already return success. 00530 if ((g_palThreads[threadIndex].palThreadID == 0 ) || // thread already exited 00531 (g_palThreads[threadIndex].palThreadID != *threadID)|| // thread already exited and a new thread was created at the same index. 00532 (g_palThreads[threadIndex].threadID == (palThreadID_t)PAL_INVALID_THREAD)) // thread was terminsated. 00533 { 00534 return PAL_SUCCESS; 00535 } 00536 00537 if ((palThreadID_t)osThreadGetId() != g_palThreads[threadIndex].threadID) 00538 {//Kill only if not trying to kill from running task 00539 if (g_palThreads[threadIndex].initialized) 00540 { 00541 if (g_palThreads[threadIndex].threadID != NULLPTR) 00542 { 00543 threadState = osThreadGetState((osThreadId_t)(g_palThreads[threadIndex].threadID)); 00544 if ((threadState != osThreadTerminated) && (threadState != osThreadError) && (threadState != osThreadInactive)) 00545 { 00546 platStatus = osThreadTerminate((osThreadId_t)(g_palThreads[threadIndex].threadID)); 00547 } 00548 } 00549 00550 if (platStatus != osErrorISR) // osErrorISR: osThreadTerminate cannot be called from interrupt service routines. 00551 { 00552 threadCleanUp( *threadID); 00553 if (NULL != g_palThreads[threadIndex].osThread.stack_mem) 00554 { 00555 free(g_palThreads[threadIndex].osThread.stack_mem); 00556 g_palThreads[threadIndex].osThread.stack_mem = NULL; 00557 } 00558 *threadID = PAL_INVALID_THREAD; 00559 status = PAL_SUCCESS; 00560 } 00561 else 00562 { 00563 status = PAL_ERR_RTOS_ISR ; 00564 } 00565 } 00566 else 00567 { 00568 // thread already tminated and cleaned up 00569 status = PAL_SUCCESS; 00570 } 00571 } 00572 else 00573 { 00574 status = PAL_ERR_RTOS_TASK ; 00575 } 00576 00577 return status; 00578 } 00579 00580 palThreadLocalStore_t* pal_plat_osThreadGetLocalStore (void) 00581 { 00582 palThreadLocalStore_t* localStore = NULL; 00583 palThreadID_t id = (uintptr_t)pal_osThreadGetId(); 00584 00585 if( g_palThreads[id].initialized) 00586 { 00587 localStore = g_palThreads[id].threadStore; 00588 } 00589 return localStore; 00590 } 00591 00592 00593 palStatus_t pal_plat_osTimerCreate (palTimerFuncPtr function, void* funcArgument, palTimerType_t timerType, palTimerID_t* timerID) 00594 { 00595 palStatus_t status = PAL_SUCCESS; 00596 palTimer_t* timer = NULL; 00597 00598 if(NULL == timerID || NULL == function) 00599 { 00600 return PAL_ERR_INVALID_ARGUMENT ; 00601 } 00602 00603 timer = (palTimer_t*)malloc(sizeof(palTimer_t)); 00604 if (NULL == timer) 00605 { 00606 status = PAL_ERR_NO_MEMORY ; 00607 } 00608 00609 if (PAL_SUCCESS == status) 00610 { 00611 timer->osTimer.name = NULL; 00612 timer->osTimer.attr_bits = 0; 00613 timer->osTimer.cb_mem = &timer->osTimerStorage; 00614 timer->osTimer.cb_size = sizeof(timer->osTimerStorage); 00615 memset(&timer->osTimerStorage, 0, sizeof(timer->osTimerStorage)); 00616 00617 timer->timerID = (uintptr_t)osTimerNew((osTimerFunc_t)function, (osTimerType_t)timerType, funcArgument, &timer->osTimer); 00618 if (NULLPTR == timer->timerID) 00619 { 00620 free(timer); 00621 timer = NULL; 00622 status = PAL_ERR_GENERIC_FAILURE; 00623 } 00624 else 00625 { 00626 *timerID = (palTimerID_t)timer; 00627 } 00628 } 00629 return status; 00630 } 00631 00632 palStatus_t pal_plat_osTimerStart (palTimerID_t timerID, uint32_t millisec) 00633 { 00634 palStatus_t status = PAL_SUCCESS; 00635 osStatus_t platStatus = osOK; 00636 palTimer_t* timer = NULL; 00637 00638 if (NULLPTR == timerID) 00639 { 00640 return PAL_ERR_INVALID_ARGUMENT ; 00641 } 00642 00643 timer = (palTimer_t*)timerID; 00644 platStatus = osTimerStart((osTimerId_t)timer->timerID, millisec); 00645 if (osOK == (osStatus_t)platStatus) 00646 { 00647 status = PAL_SUCCESS; 00648 } 00649 else 00650 { 00651 status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); 00652 } 00653 00654 return status; 00655 } 00656 00657 palStatus_t pal_plat_osTimerStop (palTimerID_t timerID) 00658 { 00659 palStatus_t status = PAL_SUCCESS; 00660 osStatus_t platStatus = osOK; 00661 palTimer_t* timer = NULL; 00662 00663 if(NULLPTR == timerID) 00664 { 00665 return PAL_ERR_INVALID_ARGUMENT ; 00666 } 00667 00668 timer = (palTimer_t*)timerID; 00669 platStatus = osTimerStop((osTimerId_t)timer->timerID); 00670 if (osOK == platStatus) 00671 { 00672 status = PAL_SUCCESS; 00673 } 00674 else 00675 { 00676 status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); 00677 } 00678 00679 return status; 00680 } 00681 00682 palStatus_t pal_plat_osTimerDelete (palTimerID_t* timerID) 00683 { 00684 palStatus_t status = PAL_SUCCESS; 00685 osStatus_t platStatus = osOK; 00686 palTimer_t* timer = NULL; 00687 00688 if(NULL == timerID || NULLPTR == *timerID) 00689 { 00690 return PAL_ERR_INVALID_ARGUMENT ; 00691 } 00692 00693 timer = (palTimer_t*)*timerID; 00694 platStatus = osTimerDelete((osTimerId_t)timer->timerID); 00695 if (osOK == platStatus) 00696 { 00697 free(timer); 00698 *timerID = NULLPTR; 00699 status = PAL_SUCCESS; 00700 } 00701 else 00702 { 00703 status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); 00704 } 00705 00706 return status; 00707 } 00708 00709 00710 palStatus_t pal_plat_osMutexCreate (palMutexID_t* mutexID) 00711 { 00712 palStatus_t status = PAL_SUCCESS; 00713 palMutex_t* mutex = NULL; 00714 00715 if(NULL == mutexID) 00716 { 00717 return PAL_ERR_INVALID_ARGUMENT ; 00718 } 00719 00720 mutex = (palMutex_t*)malloc(sizeof(palMutex_t)); 00721 if (NULL == mutex) 00722 { 00723 status = PAL_ERR_NO_MEMORY ; 00724 } 00725 00726 if (PAL_SUCCESS == status) 00727 { 00728 mutex->osMutex.name = NULL; 00729 mutex->osMutex.attr_bits = osMutexRecursive | osMutexRobust; 00730 mutex->osMutex.cb_mem = &mutex->osMutexStorage; 00731 mutex->osMutex.cb_size = sizeof(mutex->osMutexStorage); 00732 memset(&mutex->osMutexStorage, 0, sizeof(mutex->osMutexStorage)); 00733 00734 mutex->mutexID = (uintptr_t)osMutexNew(&mutex->osMutex); 00735 if (NULLPTR == mutex->mutexID) 00736 { 00737 free(mutex); 00738 mutex = NULL; 00739 status = PAL_ERR_GENERIC_FAILURE; 00740 } 00741 else 00742 { 00743 *mutexID = (palMutexID_t)mutex; 00744 } 00745 } 00746 return status; 00747 } 00748 00749 00750 palStatus_t pal_plat_osMutexWait (palMutexID_t mutexID, uint32_t millisec) 00751 { 00752 palStatus_t status = PAL_SUCCESS; 00753 osStatus_t platStatus = osOK; 00754 palMutex_t* mutex = NULL; 00755 00756 if(NULLPTR == mutexID) 00757 { 00758 return PAL_ERR_INVALID_ARGUMENT ; 00759 } 00760 00761 mutex = (palMutex_t*)mutexID; 00762 platStatus = osMutexAcquire((osMutexId_t)mutex->mutexID, millisec); 00763 if (osOK == platStatus) 00764 { 00765 status = PAL_SUCCESS; 00766 } 00767 else 00768 { 00769 status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); 00770 } 00771 00772 return status; 00773 } 00774 00775 00776 palStatus_t pal_plat_osMutexRelease (palMutexID_t mutexID) 00777 { 00778 palStatus_t status = PAL_SUCCESS; 00779 osStatus_t platStatus = osOK; 00780 palMutex_t* mutex = NULL; 00781 00782 if(NULLPTR == mutexID) 00783 { 00784 return PAL_ERR_INVALID_ARGUMENT ; 00785 } 00786 00787 mutex = (palMutex_t*)mutexID; 00788 platStatus = osMutexRelease((osMutexId_t)mutex->mutexID); 00789 if (osOK == platStatus) 00790 { 00791 status = PAL_SUCCESS; 00792 } 00793 else 00794 { 00795 status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); 00796 } 00797 00798 return status; 00799 } 00800 00801 palStatus_t pal_plat_osMutexDelete (palMutexID_t* mutexID) 00802 { 00803 palStatus_t status = PAL_SUCCESS; 00804 osStatus_t platStatus = osOK; 00805 palMutex_t* mutex = NULL; 00806 00807 if(NULL == mutexID || NULLPTR == *mutexID) 00808 { 00809 return PAL_ERR_INVALID_ARGUMENT ; 00810 } 00811 00812 mutex = (palMutex_t*)*mutexID; 00813 platStatus = osMutexDelete((osMutexId_t)mutex->mutexID); 00814 if (osOK == platStatus) 00815 { 00816 free(mutex); 00817 *mutexID = NULLPTR; 00818 status = PAL_SUCCESS; 00819 } 00820 else 00821 { 00822 status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); 00823 } 00824 00825 return status; 00826 } 00827 00828 palStatus_t pal_plat_osSemaphoreCreate (uint32_t count, palSemaphoreID_t* semaphoreID) 00829 { 00830 palStatus_t status = PAL_SUCCESS; 00831 palSemaphore_t* semaphore = NULL; 00832 if(NULL == semaphoreID) 00833 { 00834 return PAL_ERR_INVALID_ARGUMENT ; 00835 } 00836 00837 semaphore = (palSemaphore_t*)malloc(sizeof(palSemaphore_t)); 00838 if (NULL == semaphore) 00839 { 00840 status = PAL_ERR_NO_MEMORY ; 00841 } 00842 00843 if(PAL_SUCCESS == status) 00844 { 00845 semaphore->osSemaphore.cb_mem = &semaphore->osSemaphoreStorage; 00846 semaphore->osSemaphore.cb_size = sizeof(semaphore->osSemaphoreStorage); 00847 memset(&semaphore->osSemaphoreStorage, 0, sizeof(semaphore->osSemaphoreStorage)); 00848 00849 semaphore->semaphoreID = (uintptr_t)osSemaphoreNew(PAL_MAX_SEMAPHORE_COUNT, count, &semaphore->osSemaphore); 00850 if (NULLPTR == semaphore->semaphoreID) 00851 { 00852 free(semaphore); 00853 semaphore = NULL; 00854 status = PAL_ERR_GENERIC_FAILURE; 00855 } 00856 else 00857 { 00858 *semaphoreID = (palSemaphoreID_t)semaphore; 00859 } 00860 } 00861 return status; 00862 } 00863 00864 palStatus_t pal_plat_osSemaphoreWait (palSemaphoreID_t semaphoreID, uint32_t millisec, int32_t* countersAvailable) 00865 { 00866 palStatus_t status = PAL_SUCCESS; 00867 palSemaphore_t* semaphore = NULL; 00868 osStatus_t platStatus; 00869 if(NULLPTR == semaphoreID) 00870 { 00871 return PAL_ERR_INVALID_ARGUMENT ; 00872 } 00873 00874 semaphore = (palSemaphore_t*)semaphoreID; 00875 platStatus = osSemaphoreAcquire((osSemaphoreId_t)semaphore->semaphoreID, millisec); 00876 00877 if (osErrorTimeout == platStatus) 00878 { 00879 status = PAL_ERR_RTOS_TIMEOUT ; 00880 } 00881 else if (platStatus != osOK) 00882 { 00883 status = PAL_ERR_RTOS_PARAMETER; 00884 } 00885 00886 if (NULL != countersAvailable) 00887 { 00888 *countersAvailable = osSemaphoreGetCount((osSemaphoreId_t)semaphore->semaphoreID); 00889 } 00890 return status; 00891 } 00892 00893 palStatus_t pal_plat_osSemaphoreRelease (palSemaphoreID_t semaphoreID) 00894 { 00895 palStatus_t status = PAL_SUCCESS; 00896 osStatus_t platStatus = osOK; 00897 palSemaphore_t* semaphore = NULL; 00898 00899 if(NULLPTR == semaphoreID) 00900 { 00901 return PAL_ERR_INVALID_ARGUMENT ; 00902 } 00903 00904 semaphore = (palSemaphore_t*)semaphoreID; 00905 platStatus = osSemaphoreRelease((osSemaphoreId_t)semaphore->semaphoreID); 00906 if (osOK == platStatus) 00907 { 00908 status = PAL_SUCCESS; 00909 } 00910 else 00911 { 00912 status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); 00913 } 00914 00915 return status; 00916 } 00917 00918 palStatus_t pal_plat_osSemaphoreDelete (palSemaphoreID_t* semaphoreID) 00919 { 00920 palStatus_t status = PAL_SUCCESS; 00921 osStatus_t platStatus = osOK; 00922 palSemaphore_t* semaphore = NULL; 00923 00924 if(NULL == semaphoreID || NULLPTR == *semaphoreID) 00925 { 00926 return PAL_ERR_INVALID_ARGUMENT ; 00927 } 00928 00929 semaphore = (palSemaphore_t*)*semaphoreID; 00930 platStatus = osSemaphoreDelete((osSemaphoreId_t)semaphore->semaphoreID); 00931 if (osOK == platStatus) 00932 { 00933 free(semaphore); 00934 *semaphoreID = NULLPTR; 00935 status = PAL_SUCCESS; 00936 } 00937 else 00938 { 00939 status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); 00940 } 00941 00942 return status; 00943 } 00944 00945 palStatus_t pal_plat_osPoolCreate (uint32_t blockSize, uint32_t blockCount, palMemoryPoolID_t* memoryPoolID) 00946 { 00947 palStatus_t status = PAL_SUCCESS; 00948 palMemoryPool_t* memoryPool = NULL; 00949 if(NULL == memoryPoolID) 00950 { 00951 return PAL_ERR_INVALID_ARGUMENT ; 00952 } 00953 00954 //! allocate the memory pool structure 00955 memoryPool = (palMemoryPool_t*)malloc(sizeof(palMemoryPool_t)); 00956 if (NULL == memoryPool) 00957 { 00958 status = PAL_ERR_NO_MEMORY ; 00959 } 00960 00961 if(PAL_SUCCESS == status) 00962 { 00963 memoryPool->blockSize = blockSize; 00964 memoryPool->osPool.name = NULL; 00965 memoryPool->osPool.attr_bits = 0; 00966 memoryPool->osPool.cb_mem = &memoryPool->osPoolStorage; 00967 memoryPool->osPool.cb_size = sizeof(memoryPool->osPoolStorage); 00968 memset(&memoryPool->osPoolStorage, 0, sizeof(memoryPool->osPoolStorage)); 00969 memoryPool->osPool.mp_size = blockSize * blockCount; 00970 memoryPool->osPool.mp_mem = (uint32_t*)malloc(memoryPool->osPool.mp_size); 00971 if (NULL == memoryPool->osPool.mp_mem) 00972 { 00973 free(memoryPool); 00974 *memoryPoolID = NULLPTR; 00975 status = PAL_ERR_NO_MEMORY ; 00976 } 00977 else 00978 { 00979 memset(memoryPool->osPool.mp_mem, 0, memoryPool->osPool.mp_size); 00980 00981 memoryPool->memoryPoolID = (uintptr_t)osMemoryPoolNew(blockCount, blockSize, &memoryPool->osPool); 00982 if (NULLPTR == memoryPool->memoryPoolID) 00983 { 00984 free(memoryPool->osPool.mp_mem); 00985 free(memoryPool); 00986 memoryPool = NULL; 00987 status = PAL_ERR_GENERIC_FAILURE; 00988 } 00989 else 00990 { 00991 *memoryPoolID = (palMemoryPoolID_t)memoryPool; 00992 } 00993 } 00994 } 00995 return status; 00996 } 00997 00998 void* pal_plat_osPoolAlloc (palMemoryPoolID_t memoryPoolID) 00999 { 01000 void* result = NULL; 01001 palMemoryPool_t* memoryPool = NULL; 01002 01003 if(NULLPTR == memoryPoolID) 01004 { 01005 return NULL; 01006 } 01007 01008 memoryPool = (palMemoryPool_t*)memoryPoolID; 01009 result = osMemoryPoolAlloc((osMemoryPoolId_t)memoryPool->memoryPoolID, 0); 01010 01011 return result; 01012 } 01013 01014 void* pal_plat_osPoolCAlloc (palMemoryPoolID_t memoryPoolID) 01015 { 01016 void* result = NULL; 01017 palMemoryPool_t* memoryPool = NULL; 01018 01019 if(NULLPTR == memoryPoolID) 01020 { 01021 return NULL; 01022 } 01023 01024 memoryPool = (palMemoryPool_t*)memoryPoolID; 01025 result = osMemoryPoolAlloc((osMemoryPoolId_t)memoryPool->memoryPoolID, 0); 01026 if (NULLPTR != result) 01027 { 01028 memset(result, 0, memoryPool->blockSize); 01029 } 01030 01031 return result; 01032 } 01033 01034 palStatus_t pal_plat_osPoolFree (palMemoryPoolID_t memoryPoolID, void* block) 01035 { 01036 palStatus_t status = PAL_SUCCESS; 01037 osStatus_t platStatus = osOK; 01038 palMemoryPool_t* memoryPool = NULL; 01039 01040 if(NULLPTR == memoryPoolID || NULL == block) 01041 { 01042 return PAL_ERR_INVALID_ARGUMENT ; 01043 } 01044 01045 memoryPool = (palMemoryPool_t*)memoryPoolID; 01046 platStatus = osMemoryPoolFree((osMemoryPoolId_t)memoryPool->memoryPoolID, block); 01047 if (osOK == platStatus) 01048 { 01049 status = PAL_SUCCESS; 01050 } 01051 else 01052 { 01053 status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); 01054 } 01055 01056 return status; 01057 } 01058 01059 palStatus_t pal_plat_osPoolDestroy (palMemoryPoolID_t* memoryPoolID) 01060 { 01061 palStatus_t status = PAL_SUCCESS; 01062 palMemoryPool_t* memoryPool = NULL; 01063 01064 if(NULL == memoryPoolID || NULLPTR == *memoryPoolID) 01065 { 01066 return PAL_ERR_INVALID_ARGUMENT ; 01067 } 01068 01069 memoryPool = (palMemoryPool_t*)*memoryPoolID; 01070 free(memoryPool->osPool.mp_mem); 01071 free(memoryPool); 01072 *memoryPoolID = NULLPTR; 01073 return status; 01074 } 01075 01076 palStatus_t pal_plat_osMessageQueueCreate (uint32_t messageQCount, palMessageQID_t* messageQID) 01077 { 01078 palStatus_t status = PAL_SUCCESS; 01079 palMessageQ_t* messageQ = NULL; 01080 if(NULL == messageQID) 01081 { 01082 return PAL_ERR_INVALID_ARGUMENT ; 01083 } 01084 01085 //! allocate the message queue structure 01086 messageQ = (palMessageQ_t*)malloc(sizeof(palMessageQ_t)); 01087 if (NULL == messageQ) 01088 { 01089 status = PAL_ERR_NO_MEMORY ; 01090 } 01091 01092 if (PAL_SUCCESS == status) 01093 { 01094 messageQ->osMessageQ.name = NULL; 01095 messageQ->osMessageQ.attr_bits = 0; 01096 messageQ->osMessageQ.cb_size = sizeof(messageQ->osMessageQStorage); 01097 messageQ->osMessageQ.cb_mem = &messageQ->osMessageQStorage; 01098 memset(&messageQ->osMessageQStorage, 0, sizeof(messageQ->osMessageQStorage)); 01099 messageQ->osMessageQ.mq_size = (sizeof(uint32_t) + sizeof(mbed_rtos_storage_message_t)) * messageQCount ; 01100 messageQ->osMessageQ.mq_mem = (uint32_t*)malloc(messageQ->osMessageQ.mq_size); 01101 if (NULL == messageQ->osMessageQ.mq_mem) 01102 { 01103 free(messageQ); 01104 messageQ = NULL; 01105 status = PAL_ERR_NO_MEMORY ; 01106 } 01107 else 01108 { 01109 memset(messageQ->osMessageQ.mq_mem, 0, messageQ->osMessageQ.mq_size); 01110 01111 messageQ->messageQID = (uintptr_t)osMessageQueueNew(messageQCount, sizeof(uint32_t), &messageQ->osMessageQ); 01112 if (NULLPTR == messageQ->messageQID) 01113 { 01114 free(messageQ->osMessageQ.mq_mem); 01115 free(messageQ); 01116 messageQ = NULL; 01117 status = PAL_ERR_GENERIC_FAILURE; 01118 } 01119 else 01120 { 01121 *messageQID = (palMessageQID_t)messageQ; 01122 } 01123 } 01124 } 01125 return status; 01126 } 01127 01128 palStatus_t pal_plat_osMessagePut (palMessageQID_t messageQID, uint32_t info, uint32_t timeout) 01129 { 01130 palStatus_t status = PAL_SUCCESS; 01131 osStatus_t platStatus = osOK; 01132 palMessageQ_t* messageQ = NULL; 01133 01134 if(NULLPTR == messageQID) 01135 { 01136 return PAL_ERR_INVALID_ARGUMENT ; 01137 } 01138 01139 messageQ = (palMessageQ_t*)messageQID; 01140 platStatus = osMessageQueuePut((osMessageQueueId_t)messageQ->messageQID, (void *)&info, 0, timeout); 01141 if (osOK == platStatus) 01142 { 01143 status = PAL_SUCCESS; 01144 } 01145 else 01146 { 01147 status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); 01148 } 01149 01150 return status; 01151 } 01152 01153 palStatus_t pal_plat_osMessageGet (palMessageQID_t messageQID, uint32_t timeout, uint32_t* messageValue) 01154 { 01155 palStatus_t status = PAL_SUCCESS; 01156 osStatus_t platStatus; 01157 palMessageQ_t* messageQ = NULL; 01158 01159 if (NULLPTR == messageQID || NULLPTR == messageValue) 01160 { 01161 return PAL_ERR_INVALID_ARGUMENT ; 01162 } 01163 01164 messageQ = (palMessageQ_t*)messageQID; 01165 platStatus = osMessageQueueGet((osMessageQueueId_t)messageQ->messageQID, messageValue, NULL, timeout); 01166 if (osOK == platStatus) 01167 { 01168 status = PAL_SUCCESS; 01169 } 01170 else if (osErrorTimeout == platStatus) 01171 { 01172 status = PAL_ERR_RTOS_TIMEOUT ; 01173 } 01174 else if (osOK != platStatus) 01175 { 01176 status = PAL_ERR_RTOS_PARAMETER; 01177 } 01178 01179 return status; 01180 } 01181 01182 01183 palStatus_t pal_plat_osMessageQueueDestroy (palMessageQID_t* messageQID) 01184 { 01185 palStatus_t status = PAL_SUCCESS; 01186 palMessageQ_t* messageQ = NULL; 01187 01188 if(NULL == messageQID || NULLPTR == *messageQID) 01189 { 01190 return PAL_ERR_INVALID_ARGUMENT ; 01191 } 01192 01193 messageQ = (palMessageQ_t*)*messageQID; 01194 free(messageQ->osMessageQ.mq_mem); 01195 free(messageQ); 01196 *messageQID = NULLPTR; 01197 return status; 01198 } 01199 01200 01201 int32_t pal_plat_osAtomicIncrement (int32_t* valuePtr, int32_t increment) 01202 { 01203 if (increment >= 0) 01204 { 01205 return core_util_atomic_incr_u32((uint32_t*)valuePtr, increment); 01206 } 01207 else 01208 { 01209 return core_util_atomic_decr_u32((uint32_t*)valuePtr, 0 - increment); 01210 } 01211 } 01212 01213 01214 void *pal_plat_malloc (size_t len) 01215 { 01216 return malloc(len); 01217 } 01218 01219 01220 void pal_plat_free (void * buffer) 01221 { 01222 return free(buffer); 01223 } 01224 01225 palStatus_t pal_plat_osRandomBuffer (uint8_t *randomBuf, size_t bufSizeBytes) 01226 { 01227 palStatus_t status = PAL_SUCCESS; 01228 int32_t platStatus = 0; 01229 size_t actualOutputLen = 0; 01230 platStatus = mbedtls_hardware_poll(NULL /*Not used by the function*/, randomBuf, bufSizeBytes, &actualOutputLen); 01231 if ((0 != platStatus) || (actualOutputLen != bufSizeBytes)) 01232 { 01233 status = PAL_ERR_RTOS_TRNG_FAILED ; 01234 } 01235 return status; 01236 } 01237 01238 #endif
Generated on Tue Jul 12 2022 16:22:10 by 1.7.2