Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

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