Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_plat_rtos.cpp Source File

pal_plat_rtos.cpp

00001 /*******************************************************************************
00002  * Copyright 2016, 2017 ARM Ltd.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may 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,
00012  * WITHOUT 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 #include "pal.h"
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include "pal_plat_rtos.h"
00022 #include "mbed.h"
00023 #include "entropy_poll.h"
00024 
00025 #define TRACE_GROUP "PAL"
00026 
00027 /*
00028     mbedOS latest version RTOS support
00029 */
00030 #if defined(osRtxVersionAPI) && (osRtxVersionAPI >= 20000000)
00031 
00032 #include "cmsis_os2.h" // Revision:    V2.1
00033 #include <time.h>
00034 
00035 #define PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(cmsisCode)\
00036     ((int32_t)((int32_t)cmsisCode + PAL_ERR_RTOS_ERROR_BASE))
00037 
00038 #define PAL_THREAD_NAME_MAX_LEN 20 // max len for thread name which holds the pointer (as string) to dynamically allocated thread data
00039 #define PAL_THREAD_STACK_ALIGN(x) ((x % sizeof(uint64_t)) ? (x + ((sizeof(uint64_t)) - (x % sizeof(uint64_t)))) : x)
00040 
00041 typedef struct palThreadData 
00042 {
00043     osThreadId_t threadID;
00044     osThreadAttr_t threadAttr;
00045     mbed_rtos_storage_thread_t threadStore;
00046     palThreadFuncPtr userFunction;
00047     void* userFunctionArgument;
00048 } palThreadData_t;
00049 
00050 typedef struct palThreadCleanupData
00051 {
00052     palTimerID_t timerID;
00053     palThreadData_t* threadData;
00054 } palThreadCleanupData_t;
00055 
00056 PAL_PRIVATE palMutexID_t g_threadsMutex = NULLPTR;
00057 
00058 //! Timer structure
00059 typedef struct palTimer{
00060     palTimerID_t              timerID;
00061     osTimerAttr_t             osTimer;
00062     mbed_rtos_storage_timer_t osTimerStorage;
00063 } palTimer_t;
00064 
00065 //! Mutex structure
00066 typedef struct palMutex{
00067     palMutexID_t              mutexID;
00068     osMutexAttr_t             osMutex;
00069     mbed_rtos_storage_mutex_t osMutexStorage;
00070 }palMutex_t;
00071 
00072 //! Semaphore structure
00073 typedef struct palSemaphore{
00074     palSemaphoreID_t              semaphoreID;
00075     osSemaphoreAttr_t             osSemaphore;
00076     mbed_rtos_storage_semaphore_t osSemaphoreStorage;
00077 }palSemaphore_t;
00078 
00079 void pal_plat_osReboot()
00080 {
00081     NVIC_SystemReset();
00082 }
00083 
00084 palStatus_t pal_plat_RTOSInitialize(void* opaqueContext)
00085 {
00086     palStatus_t status = pal_osMutexCreate(&g_threadsMutex);
00087     return status;
00088 }
00089 
00090 palStatus_t pal_plat_RTOSDestroy(void)
00091 {
00092     palStatus_t status = PAL_SUCCESS; 
00093     if (NULLPTR != g_threadsMutex)
00094     {
00095         status = pal_osMutexDelete(&g_threadsMutex);
00096         g_threadsMutex = NULLPTR;
00097     }
00098     return status;
00099 }
00100 
00101 palStatus_t pal_plat_osDelay(uint32_t milliseconds)
00102 {
00103     palStatus_t status;
00104     osStatus_t platStatus = osDelay(milliseconds);
00105     if (osOK == platStatus)
00106     {
00107         status = PAL_SUCCESS;
00108     }
00109     else
00110     {
00111         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); //TODO(nirson01): error propagation MACRO??
00112     }
00113     return status;
00114 }
00115 
00116 uint64_t pal_plat_osKernelSysTick(void)
00117 {
00118     uint64_t result;
00119     result = osKernelGetTickCount();
00120     return result;
00121 }
00122 
00123 uint64_t pal_plat_osKernelSysTickMicroSec(uint64_t microseconds)
00124 {
00125     uint64_t result;
00126     result =  (((uint64_t)microseconds * (osKernelGetTickFreq())) / 1000000);
00127 
00128     return result;
00129 }
00130 
00131 uint64_t pal_plat_osKernelSysTickFrequency()
00132 {
00133     return osKernelGetTickFreq();
00134 }
00135 
00136 PAL_PRIVATE void timerFunctionThreadCleanup(const void* arg)
00137 {
00138     palStatus_t status;
00139     palThreadCleanupData_t* cleanupData = (palThreadCleanupData_t*)arg;
00140     palTimerID_t timerID = cleanupData->timerID;
00141     osThreadState_t threadState = osThreadGetState(cleanupData->threadData->threadID);
00142     if ((osThreadTerminated == threadState) || (osThreadInactive == threadState)) // thread has transitioned into its final state so clean up
00143     {
00144         free(cleanupData->threadData->threadAttr.stack_mem);
00145         free((void*)cleanupData->threadData->threadAttr.name);
00146         free(cleanupData->threadData);
00147         free(cleanupData);
00148         status = pal_osTimerDelete(&timerID);
00149         if (PAL_SUCCESS != status)
00150         {
00151             PAL_LOG_ERR("timerFunctionThreadCleanup timer delete failed\n");
00152         }
00153         goto end;
00154     }
00155 
00156     if (osThreadError == threadState)
00157     {
00158         PAL_LOG_ERR("timerFunctionThreadCleanup threadState is osThreadError\n");
00159         goto end;
00160     }
00161 
00162     status = pal_osTimerStart(timerID, PAL_RTOS_THREAD_CLEANUP_TIMER_MILISEC); // thread has not transitioned into its final so start the timer again
00163     if (PAL_SUCCESS != status)
00164     {
00165         PAL_LOG_ERR("timerFunctionThreadCleanup timer start failed\n");
00166     }
00167 end:
00168     return;
00169 }
00170 
00171 PAL_PRIVATE void threadFunction(void* arg)
00172 {
00173     palThreadData_t* threadData;
00174     palThreadFuncPtr userFunction;
00175     void* userFunctionArgument;
00176     palThreadCleanupData_t* cleanupData;
00177     palTimerID_t timerID;
00178     bool isMutexTaken = false;
00179     palStatus_t status = pal_osMutexWait(g_threadsMutex, PAL_RTOS_WAIT_FOREVER); // avoid race condition with thread terminate
00180     if (PAL_SUCCESS != status)
00181     {
00182         PAL_LOG_ERR("threadFunction mutex wait failed (pre)\n");
00183         goto end;
00184     }
00185 
00186     isMutexTaken = true;
00187     threadData = (palThreadData_t*)arg;
00188     userFunction = threadData->userFunction;
00189     userFunctionArgument = threadData->userFunctionArgument;
00190     status = pal_osMutexRelease(g_threadsMutex);
00191     if (PAL_SUCCESS != status)
00192     {
00193         PAL_LOG_ERR("threadFunction mutex release failed (pre)\n");
00194         goto end;
00195     }
00196 
00197     isMutexTaken = false;
00198     userFunction(userFunctionArgument); // invoke user function with user argument (use local vars)
00199     status = pal_osMutexWait(g_threadsMutex, PAL_RTOS_WAIT_FOREVER); // avoid race condition with thread terminate
00200     if (PAL_SUCCESS != status)
00201     {
00202         PAL_LOG_ERR("threadFunction mutex wait failed (post)\n");
00203         goto end;
00204     }
00205 
00206     isMutexTaken = true;
00207     cleanupData = (palThreadCleanupData_t*)malloc(sizeof(palThreadCleanupData_t));
00208     if (NULL == cleanupData)
00209     {
00210         PAL_LOG_ERR("threadFunction malloc palThreadCleanupData_t failed\n");
00211         goto end;
00212     }
00213 
00214     status = pal_osTimerCreate(timerFunctionThreadCleanup, cleanupData, palOsTimerOnce , &timerID);
00215     if (PAL_SUCCESS != status)
00216     {
00217         free(cleanupData);
00218         PAL_LOG_ERR("threadFunction create timer failed\n");
00219         goto end;
00220     }
00221 
00222     memset((void*)threadData->threadAttr.name, 0, PAL_THREAD_NAME_MAX_LEN); // clear the thread name which holds the address (as string) of the dynamically allocated palThreadData_t (rechecked in thread terminate)
00223     threadData->threadID = osThreadGetId();
00224     cleanupData->timerID = timerID;
00225     cleanupData->threadData = threadData;
00226     status = pal_osTimerStart(timerID, PAL_RTOS_THREAD_CLEANUP_TIMER_MILISEC);
00227     if (PAL_SUCCESS != status)
00228     {
00229         free(cleanupData); // timer failed to start so cleanup dynamically allocated palThreadCleanupData_t
00230         PAL_LOG_ERR("threadFunction timer start failed\n");
00231         status = pal_osTimerDelete(&timerID);
00232         if (PAL_SUCCESS != status)
00233         {
00234             PAL_LOG_ERR("threadFunction timer delete failed\n");
00235         }
00236     }
00237 end:
00238     if (isMutexTaken)
00239     {
00240         status = pal_osMutexRelease(g_threadsMutex);
00241         if (PAL_SUCCESS != status)
00242         {
00243             PAL_LOG_ERR("threadFunction mutex release failed (post)\n");
00244         }
00245     }
00246 }
00247 
00248 PAL_PRIVATE osPriority_t translatePriority(palThreadPriority_t priority)
00249 {
00250     osPriority_t translatedPriority;
00251     switch (priority)
00252     {
00253         case PAL_osPriorityIdle:
00254             translatedPriority = osPriorityIdle;
00255             break;
00256         case PAL_osPriorityLow:
00257             translatedPriority = osPriorityLow;
00258             break;
00259         case PAL_osPriorityReservedTRNG:
00260             translatedPriority = osPriorityLow1;
00261             break;
00262         case PAL_osPriorityBelowNormal:
00263             translatedPriority = osPriorityBelowNormal;
00264             break;
00265         case PAL_osPriorityNormal:
00266             translatedPriority = osPriorityNormal;
00267             break;
00268         case PAL_osPriorityAboveNormal:
00269             translatedPriority = osPriorityAboveNormal;
00270             break;
00271         case PAL_osPriorityReservedDNS :
00272             translatedPriority = osPriorityAboveNormal1;
00273             break;
00274         case PAL_osPriorityReservedSockets :
00275             translatedPriority = osPriorityAboveNormal2;
00276             break;
00277         case PAL_osPriorityHigh:
00278             translatedPriority = osPriorityHigh;
00279             break;
00280         case PAL_osPriorityReservedHighResTimer :
00281             translatedPriority = osPriorityRealtime;
00282             break;
00283         case PAL_osPriorityRealtime:
00284             translatedPriority = osPriorityRealtime1;
00285             break;
00286         case PAL_osPriorityError:
00287         default:
00288             translatedPriority = osPriorityError;
00289             break;
00290     }
00291     return translatedPriority;
00292 }
00293 
00294 palStatus_t pal_plat_osThreadCreate(palThreadFuncPtr function, void* funcArgument, palThreadPriority_t priority, uint32_t stackSize, palThreadID_t* threadID)
00295 {
00296     palStatus_t status = PAL_SUCCESS;
00297     void* threadStack = NULL;
00298     char* threadName = NULL;
00299     palThreadData_t* threadData = NULL;
00300     int bytesWritten;
00301     osThreadId_t sysThreadID;
00302     osPriority_t threadPriority = translatePriority(priority);
00303     if (osPriorityError == threadPriority)
00304     {
00305         status = PAL_ERR_RTOS_PRIORITY ;
00306         goto end;
00307     }
00308 
00309     stackSize = PAL_THREAD_STACK_ALIGN(stackSize);
00310     threadStack = malloc(stackSize);
00311     threadName = (char*)calloc((PAL_THREAD_NAME_MAX_LEN + 1), sizeof(char)); // name will hold the address of the dynamically allocated palThreadData_t (as string)
00312     threadData = (palThreadData_t*)malloc(sizeof(palThreadData_t));
00313     if ((NULL == threadData) || (NULL == threadStack) || (NULL == threadName))
00314     {
00315         status = PAL_ERR_RTOS_RESOURCE ;
00316         goto clean;
00317     }
00318 
00319     bytesWritten = snprintf(threadName, (PAL_THREAD_NAME_MAX_LEN + 1), "%p", threadData);
00320     if ((bytesWritten <= 0) || ((PAL_THREAD_NAME_MAX_LEN + 1) <= bytesWritten))
00321     {
00322         status = PAL_ERR_RTOS_RESOURCE ;
00323         goto clean;
00324     }
00325 
00326     memset(&(threadData->threadStore), 0, sizeof(threadData->threadStore));
00327     threadData->threadAttr.priority = threadPriority;
00328     threadData->threadAttr.stack_size = stackSize;
00329     threadData->threadAttr.stack_mem = threadStack;
00330     threadData->threadAttr.name = threadName;
00331     threadData->threadAttr.cb_mem= &(threadData->threadStore);
00332     threadData->threadAttr.cb_size = sizeof(threadData->threadStore);
00333     threadData->userFunction = function;
00334     threadData->userFunctionArgument = funcArgument;
00335 
00336     sysThreadID = osThreadNew(threadFunction, threadData, &(threadData->threadAttr));
00337     if (NULL == sysThreadID)
00338     {
00339         status = PAL_ERR_GENERIC_FAILURE ;
00340         goto clean;
00341     }
00342 
00343     *threadID = (palThreadID_t)sysThreadID;
00344     goto end;
00345 clean:
00346     free(threadStack);
00347     free(threadName);
00348     free(threadData);
00349 end:
00350     return status;
00351 }
00352 
00353 palThreadID_t pal_plat_osThreadGetId(void)
00354 {
00355     palThreadID_t threadID = (palThreadID_t)osThreadGetId();
00356     return threadID;
00357 }
00358 
00359 palStatus_t pal_plat_osThreadTerminate(palThreadID_t* threadID)
00360 {
00361     palStatus_t status;
00362     palThreadData_t* threadData = NULL;
00363     osThreadId_t sysThreadID = (osThreadId_t)*threadID;
00364     osStatus_t sysStatus;
00365     osThreadState_t threadState;
00366     const char* threadName;
00367     bool isMutexTaken = false;
00368     if (osThreadGetId() == sysThreadID) // self termination not allowed
00369     {
00370         status = PAL_ERR_RTOS_TASK ;
00371         goto end;   
00372     }
00373 
00374     status = pal_osMutexWait(g_threadsMutex, PAL_RTOS_WAIT_FOREVER); // avoid race condition with thread function
00375     if (PAL_SUCCESS != status)
00376     {
00377         PAL_LOG_ERR("thread terminate mutex wait failed\n");
00378         goto end;
00379     }
00380 
00381     isMutexTaken = true;
00382     threadState = osThreadGetState(sysThreadID);
00383     if ((osThreadTerminated == threadState) || (osThreadInactive == threadState) || (osThreadError == threadState)) // thread has already transitioned into its final state
00384     {
00385         goto end;
00386     }
00387 
00388     threadName = osThreadGetName(sysThreadID);
00389     if ((NULL == threadName) || (1 != sscanf(threadName, "%p", &threadData))) // this may happen if the thread has not tranistioned into its final state yet (altered in thread function)
00390     {
00391         goto end;
00392     }
00393 
00394     sysStatus = osThreadTerminate(sysThreadID);
00395     if (osErrorISR == sysStatus)
00396     {
00397         status = PAL_ERR_RTOS_ISR ;
00398         goto end;
00399     }
00400 
00401     free(threadData->threadAttr.stack_mem);
00402     free((void*)threadData->threadAttr.name);
00403     free(threadData);
00404 end:
00405     if (isMutexTaken)
00406     {
00407         if (PAL_SUCCESS != pal_osMutexRelease(g_threadsMutex))
00408         {
00409             PAL_LOG_ERR("thread terminate mutex release failed\n");
00410         }
00411     }
00412     return status;
00413 }
00414 
00415 palStatus_t pal_plat_osTimerCreate(palTimerFuncPtr function, void* funcArgument, palTimerType_t timerType, palTimerID_t* timerID)
00416 {
00417     palStatus_t status = PAL_SUCCESS;
00418     palTimer_t* timer = NULL;
00419    
00420     timer = (palTimer_t*)malloc(sizeof(palTimer_t));
00421     if (NULL == timer)
00422     {
00423         status = PAL_ERR_NO_MEMORY ;
00424     }
00425 
00426     if (PAL_SUCCESS == status)
00427     {
00428         timer->osTimer.name = NULL;
00429         timer->osTimer.attr_bits = 0;
00430         timer->osTimer.cb_mem = &timer->osTimerStorage;
00431         timer->osTimer.cb_size = sizeof(timer->osTimerStorage);
00432         memset(&timer->osTimerStorage, 0, sizeof(timer->osTimerStorage));
00433     
00434         timer->timerID = (uintptr_t)osTimerNew((osTimerFunc_t)function, (osTimerType_t)timerType, funcArgument, &timer->osTimer);
00435         if (NULLPTR == timer->timerID)
00436         {
00437             free(timer);
00438             timer = NULL;
00439             status = PAL_ERR_GENERIC_FAILURE ;
00440         }
00441         else
00442         {
00443             *timerID = (palTimerID_t)timer;
00444         }
00445     }
00446     return status;
00447 }
00448 
00449 palStatus_t pal_plat_osTimerStart(palTimerID_t timerID, uint32_t millisec)
00450 {
00451     palStatus_t status = PAL_SUCCESS;
00452     osStatus_t platStatus = osOK;
00453     palTimer_t* timer = NULL;
00454     
00455     timer = (palTimer_t*)timerID;
00456     platStatus = osTimerStart((osTimerId_t)timer->timerID, millisec);
00457     if (osOK == (osStatus_t)platStatus)
00458     {
00459         status = PAL_SUCCESS;
00460     }
00461     else
00462     {
00463         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00464     }
00465 
00466     return status;
00467 }
00468 
00469 palStatus_t pal_plat_osTimerStop(palTimerID_t timerID)
00470 {
00471     palStatus_t status = PAL_SUCCESS;
00472     osStatus_t platStatus = osOK;
00473     palTimer_t* timer = NULL;
00474     
00475     timer = (palTimer_t*)timerID;
00476     platStatus = osTimerStop((osTimerId_t)timer->timerID);
00477     if (osOK == platStatus)
00478     {
00479         status = PAL_SUCCESS;
00480     }
00481     else
00482     {
00483         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00484     }
00485 
00486     return status;  
00487 }
00488 
00489 palStatus_t pal_plat_osTimerDelete(palTimerID_t* timerID)
00490 {
00491     palStatus_t status = PAL_SUCCESS;
00492     osStatus_t platStatus = osOK;
00493     palTimer_t* timer = NULL;
00494     
00495     timer = (palTimer_t*)*timerID;
00496     platStatus = osTimerDelete((osTimerId_t)timer->timerID);
00497     if (osOK == platStatus)
00498     {
00499         free(timer);
00500         *timerID = NULLPTR;
00501         status = PAL_SUCCESS;
00502     }
00503     else
00504     {
00505         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00506     }
00507 
00508     return status;
00509 }
00510 
00511 
00512 palStatus_t pal_plat_osMutexCreate(palMutexID_t* mutexID)
00513 {
00514     palStatus_t status = PAL_SUCCESS;
00515     palMutex_t* mutex = NULL;
00516 
00517     mutex = (palMutex_t*)malloc(sizeof(palMutex_t));
00518     if (NULL == mutex)
00519     {
00520         status = PAL_ERR_NO_MEMORY ;
00521     }
00522 
00523     if (PAL_SUCCESS == status)
00524     {
00525         mutex->osMutex.name = NULL;
00526         mutex->osMutex.attr_bits = osMutexRecursive | osMutexRobust;
00527         mutex->osMutex.cb_mem = &mutex->osMutexStorage;
00528         mutex->osMutex.cb_size = sizeof(mutex->osMutexStorage);
00529         memset(&mutex->osMutexStorage, 0, sizeof(mutex->osMutexStorage));
00530 
00531         mutex->mutexID = (uintptr_t)osMutexNew(&mutex->osMutex);
00532         if (NULLPTR == mutex->mutexID)
00533         {
00534             free(mutex);
00535             mutex = NULL;
00536             status = PAL_ERR_GENERIC_FAILURE ;
00537         }
00538         else
00539         {
00540             *mutexID = (palMutexID_t)mutex;
00541         }
00542     }
00543     return status;
00544 }
00545 
00546 
00547 palStatus_t pal_plat_osMutexWait(palMutexID_t mutexID, uint32_t millisec)
00548 {
00549     palStatus_t status = PAL_SUCCESS;
00550     osStatus_t platStatus = osOK;
00551     palMutex_t* mutex = NULL;
00552     
00553     mutex = (palMutex_t*)mutexID;
00554     platStatus = osMutexAcquire((osMutexId_t)mutex->mutexID, millisec);
00555     if (osOK == platStatus)
00556     {
00557         status = PAL_SUCCESS;
00558     }
00559     else
00560     {
00561         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00562     }
00563 
00564     return status;
00565 }
00566 
00567 
00568 palStatus_t pal_plat_osMutexRelease(palMutexID_t mutexID)
00569 {
00570     palStatus_t status = PAL_SUCCESS;
00571     osStatus_t platStatus = osOK;
00572     palMutex_t* mutex = NULL;
00573     
00574     mutex = (palMutex_t*)mutexID;
00575     platStatus = osMutexRelease((osMutexId_t)mutex->mutexID);
00576     if (osOK == platStatus)
00577     {
00578         status = PAL_SUCCESS;
00579     }
00580     else
00581     {
00582         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00583     }
00584 
00585     return status;
00586 }
00587 
00588 palStatus_t pal_plat_osMutexDelete(palMutexID_t* mutexID)
00589 {
00590     palStatus_t status = PAL_SUCCESS;
00591     osStatus_t platStatus = osOK;
00592     palMutex_t* mutex = NULL;
00593     
00594     mutex = (palMutex_t*)*mutexID;
00595     platStatus = osMutexDelete((osMutexId_t)mutex->mutexID);
00596     if (osOK == platStatus)
00597     {
00598         free(mutex);
00599         *mutexID = NULLPTR;
00600         status = PAL_SUCCESS;
00601     }
00602     else
00603     {
00604         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00605     }
00606 
00607     return status;
00608 }
00609 
00610 palStatus_t pal_plat_osSemaphoreCreate(uint32_t count, palSemaphoreID_t* semaphoreID)
00611 {
00612     palStatus_t status = PAL_SUCCESS;
00613     palSemaphore_t* semaphore = NULL;
00614     
00615     semaphore = (palSemaphore_t*)malloc(sizeof(palSemaphore_t));
00616     if (NULL == semaphore)
00617     {
00618         status = PAL_ERR_NO_MEMORY ;
00619     }
00620 
00621     if(PAL_SUCCESS == status)
00622     {
00623         semaphore->osSemaphore.cb_mem = &semaphore->osSemaphoreStorage;
00624         semaphore->osSemaphore.cb_size = sizeof(semaphore->osSemaphoreStorage);
00625         memset(&semaphore->osSemaphoreStorage, 0, sizeof(semaphore->osSemaphoreStorage));
00626 
00627         semaphore->semaphoreID = (uintptr_t)osSemaphoreNew(PAL_MAX_SEMAPHORE_COUNT, count, &semaphore->osSemaphore);
00628         if (NULLPTR == semaphore->semaphoreID)
00629         {
00630             free(semaphore);
00631             semaphore = NULL;
00632             status = PAL_ERR_GENERIC_FAILURE ;
00633         }
00634         else
00635         {
00636             *semaphoreID = (palSemaphoreID_t)semaphore;
00637         }
00638     }
00639     return status;  
00640 }
00641 
00642 palStatus_t pal_plat_osSemaphoreWait(palSemaphoreID_t semaphoreID, uint32_t millisec, int32_t* countersAvailable)
00643 {
00644     palStatus_t status = PAL_SUCCESS;
00645     palSemaphore_t* semaphore = NULL;
00646     osStatus_t platStatus;
00647     
00648     semaphore = (palSemaphore_t*)semaphoreID;
00649     platStatus = osSemaphoreAcquire((osSemaphoreId_t)semaphore->semaphoreID, millisec);
00650 
00651     // Return a PAL_ERR_RTOS_TIMEOUT for the case where resource was busy during millisec time (osErrorTimeout)
00652     // as well as the case where the millisec arg is 0 and resource is busy (osErrorResource)
00653     if (osErrorTimeout == platStatus ||
00654         osErrorResource == platStatus)
00655     {
00656         status = PAL_ERR_RTOS_TIMEOUT ;
00657     }
00658     else if (platStatus != osOK)
00659     {
00660         status = PAL_ERR_RTOS_PARAMETER ;
00661     }
00662 
00663     if (NULL != countersAvailable)
00664     {
00665         *countersAvailable = osSemaphoreGetCount((osSemaphoreId_t)semaphore->semaphoreID);
00666     }
00667     return status;
00668 }
00669 
00670 palStatus_t pal_plat_osSemaphoreRelease(palSemaphoreID_t semaphoreID)
00671 {
00672     palStatus_t status = PAL_SUCCESS;
00673     osStatus_t platStatus = osOK;
00674     palSemaphore_t* semaphore = NULL;
00675 
00676     semaphore = (palSemaphore_t*)semaphoreID;
00677     platStatus = osSemaphoreRelease((osSemaphoreId_t)semaphore->semaphoreID);
00678     if (osOK == platStatus)
00679     {
00680         status = PAL_SUCCESS;
00681     }
00682     else
00683     {
00684         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00685     }
00686 
00687     return status;
00688 }
00689 
00690 palStatus_t pal_plat_osSemaphoreDelete(palSemaphoreID_t* semaphoreID)
00691 {
00692     palStatus_t status = PAL_SUCCESS;
00693     osStatus_t platStatus = osOK;
00694     palSemaphore_t* semaphore = NULL;
00695     
00696     semaphore = (palSemaphore_t*)*semaphoreID;
00697     platStatus = osSemaphoreDelete((osSemaphoreId_t)semaphore->semaphoreID);
00698     if (osOK == platStatus)
00699     {
00700         free(semaphore);
00701         *semaphoreID = NULLPTR;
00702         status = PAL_SUCCESS;
00703     }
00704     else
00705     {
00706         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00707     }
00708 
00709     return status;  
00710 }
00711 
00712 int32_t pal_plat_osAtomicIncrement(int32_t* valuePtr, int32_t increment)
00713 {
00714     if (increment >= 0)
00715     {
00716         return core_util_atomic_incr_u32((uint32_t*)valuePtr, increment);
00717     }
00718     else
00719     {
00720         return core_util_atomic_decr_u32((uint32_t*)valuePtr, 0 - increment);
00721     }
00722 }
00723 
00724 
00725  void *pal_plat_malloc(size_t len)
00726 {
00727     return malloc(len);
00728 }
00729 
00730 
00731  void pal_plat_free(void * buffer)
00732 {
00733     return free(buffer);
00734 }
00735 
00736 #if PAL_USE_HW_TRNG
00737 extern "C"
00738 palStatus_t pal_plat_osRandomBuffer(uint8_t *randomBuf, size_t bufSizeBytes, size_t* actualRandomSizeBytes)
00739 {
00740     palStatus_t status = PAL_SUCCESS;
00741     int32_t platStatus = 0;
00742     size_t actualOutputLen = 0;
00743     platStatus = mbedtls_hardware_poll(NULL /*Not used by the function*/, randomBuf, bufSizeBytes, &actualOutputLen);
00744     if ((0 != platStatus) || (0 == actualOutputLen))
00745     {
00746         status = PAL_ERR_RTOS_TRNG_FAILED ;
00747     }
00748     else if (actualOutputLen != bufSizeBytes)
00749     {
00750         status = PAL_ERR_RTOS_TRNG_PARTIAL_DATA ;
00751     }
00752 
00753     if (NULL != actualRandomSizeBytes)
00754     {
00755         *actualRandomSizeBytes = actualOutputLen;
00756     }
00757     return status;
00758 }
00759 #endif
00760 
00761 #if (PAL_USE_HW_RTC)
00762 palStatus_t pal_plat_osGetRtcTime(uint64_t *rtcGetTime)
00763 {
00764     palStatus_t ret = PAL_SUCCESS;
00765     if(rtcGetTime != NULL)
00766     {
00767         *rtcGetTime = (uint64_t)time(NULL);
00768     }
00769     else
00770     {
00771         ret = PAL_ERR_NULL_POINTER ;
00772     }
00773     return ret;
00774 }
00775 
00776 palStatus_t pal_plat_osSetRtcTime(uint64_t rtcSetTime)
00777 {
00778     palStatus_t status = PAL_SUCCESS;
00779     if (rtcSetTime < (uint64_t)PAL_MIN_RTC_SET_TIME)
00780     {
00781         status = PAL_ERR_INVALID_TIME ;
00782     }
00783     else
00784     {
00785         set_time(rtcSetTime);
00786     }
00787 
00788     return status;
00789 }
00790 
00791 palStatus_t pal_plat_rtcInit(void)
00792 {
00793     palStatus_t ret = PAL_SUCCESS;
00794     return ret;
00795 }
00796 
00797 palStatus_t pal_plat_rtcDeInit(void)
00798 {
00799     palStatus_t ret = PAL_SUCCESS;
00800     return ret;
00801 }
00802 #endif //#if (PAL_USE_HW_RTC)
00803 
00804 #endif