Simple interface for Mbed Cloud Client

Dependents:  

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 
00022 #include "pal_plat_rtos.h"
00023 #include "mbed.h"
00024 
00025 #include "entropy_poll.h"
00026 
00027 
00028 /*
00029     mbedOS latest version RTOS support
00030 */
00031 #if defined(osRtxVersionAPI) && (osRtxVersionAPI >= 20000000)
00032 
00033 #include "cmsis_os2.h" // Revision:    V2.1
00034 #include <time.h>
00035 
00036 #define PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(cmsisCode)\
00037     ((int32_t)((int32_t)cmsisCode + PAL_ERR_RTOS_ERROR_BASE))
00038 
00039 typedef struct threadPortData 
00040 {
00041     osThreadId_t osThreadID;
00042     osThreadAttr_t osThread;
00043     mbed_rtos_storage_thread_t osThreadStorage;
00044 } threadPortData_t;
00045 
00046 //! Timer structure
00047 typedef struct palTimer{
00048     palTimerID_t              timerID;
00049     osTimerAttr_t             osTimer;
00050     mbed_rtos_storage_timer_t osTimerStorage;
00051 } palTimer_t;
00052 
00053 //! Mutex structure
00054 typedef struct palMutex{
00055     palMutexID_t              mutexID;
00056     osMutexAttr_t             osMutex;
00057     mbed_rtos_storage_mutex_t osMutexStorage;
00058 }palMutex_t;
00059 
00060 //! Semaphore structure
00061 typedef struct palSemaphore{
00062     palSemaphoreID_t              semaphoreID;
00063     osSemaphoreAttr_t             osSemaphore;
00064     mbed_rtos_storage_semaphore_t osSemaphoreStorage;
00065 }palSemaphore_t;
00066 
00067 
00068 typedef struct palThreadCleanupData
00069 {
00070     palTimerID_t timerID;
00071     threadPortData_t* portData;
00072 } palThreadCleanupData_t;
00073 
00074 PAL_PRIVATE int16_t g_threadPriorityMap[PAL_NUMBER_OF_THREAD_PRIORITIES] = 
00075 { 
00076     (int16_t)osPriorityIdle,         // PAL_osPriorityIdle
00077     (int16_t)osPriorityLow,          // PAL_osPriorityLow
00078     (int16_t)osPriorityLow1,         // PAL_osPriorityReservedTRNG
00079     (int16_t)osPriorityBelowNormal,  // PAL_osPriorityBelowNormal
00080     (int16_t)osPriorityNormal,       // PAL_osPriorityNormal
00081     (int16_t)osPriorityAboveNormal,  // PAL_osPriorityAboveNormal
00082     (int16_t)osPriorityAboveNormal1, // PAL_osPriorityReservedDNS,
00083     (int16_t)osPriorityAboveNormal2, // PAL_osPriorityReservedSockets
00084     (int16_t)osPriorityHigh,         // PAL_osPriorityHigh
00085     (int16_t)osPriorityRealtime,     // PAL_osPriorityReservedHighResTimer
00086     (int16_t)osPriorityRealtime1     // PAL_osPriorityRealtime
00087 };
00088 
00089 PAL_PRIVATE void threadCleanupTimer(const void* arg)
00090 {
00091     palStatus_t status;
00092     osThreadState_t threadState;
00093     palThreadCleanupData_t* threadCleanupData = (palThreadCleanupData_t*)arg;
00094     palTimerID_t timerID = threadCleanupData->timerID;
00095 
00096     threadState = osThreadGetState(threadCleanupData->portData->osThreadID);
00097     if ((osThreadTerminated == threadState) || (osThreadInactive == threadState)) // thread has ended
00098     {
00099         free(threadCleanupData->portData->osThread.stack_mem);
00100         free(threadCleanupData->portData);
00101         free(threadCleanupData);
00102         status = pal_osTimerDelete(&timerID);
00103         if (PAL_SUCCESS != status)
00104         {
00105             PAL_LOG(ERR, "threadCleanupTimer: pal_osTimerDelete failed\n");
00106         }
00107     }
00108     else // thread has not ended so wait another PAL_RTOS_THREAD_CLEANUP_TIMER_MILISEC
00109     {
00110         if (osThreadError == threadState)
00111         {
00112             PAL_LOG(ERR, "threadCleanupTimer: threadState = osThreadError\n");
00113         }
00114         else
00115         {
00116             status = pal_osTimerStart(timerID, PAL_RTOS_THREAD_CLEANUP_TIMER_MILISEC);
00117             if (PAL_SUCCESS != status)
00118             {
00119                 PAL_LOG(ERR, "threadCleanupTimer: pal_osTimerStart failed\n");
00120             }
00121         }
00122     }
00123 }
00124 
00125 PAL_PRIVATE void threadFunction(void* arg)
00126 {
00127     palThreadServiceBridge_t* bridge = (palThreadServiceBridge_t*)arg;
00128     bridge->function(bridge->threadData );
00129 }
00130 
00131 void pal_plat_osReboot ()
00132 {
00133     NVIC_SystemReset();
00134 }
00135 
00136 palStatus_t pal_plat_RTOSInitialize (void* opaqueContext)
00137 {
00138     return PAL_SUCCESS;
00139 }
00140 
00141 palStatus_t pal_plat_RTOSDestroy (void)
00142 {
00143     return PAL_SUCCESS;
00144 }
00145 
00146 palStatus_t pal_plat_osDelay (uint32_t milliseconds)
00147 {
00148     palStatus_t status;
00149     osStatus_t platStatus = osDelay(milliseconds);
00150     if (osOK == platStatus)
00151     {
00152         status = PAL_SUCCESS;
00153     }
00154     else
00155     {
00156         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); //TODO(nirson01): error propagation MACRO??
00157     }
00158     return status;
00159 }
00160 
00161 uint64_t pal_plat_osKernelSysTick (void)
00162 {
00163     uint64_t result;
00164     result = osKernelGetTickCount();
00165     return result;
00166 }
00167 
00168 uint64_t pal_plat_osKernelSysTickMicroSec (uint64_t microseconds)
00169 {
00170     uint64_t result;
00171     result =  (((uint64_t)microseconds * (osKernelGetTickFreq())) / 1000000);
00172 
00173     return result;
00174 }
00175 
00176 uint64_t pal_plat_osKernelSysTickFrequency ()
00177 {
00178     return osKernelGetTickFreq();
00179 }
00180 
00181 int16_t pal_plat_osThreadTranslatePriority (palThreadPriority_t priority)
00182 {
00183     return g_threadPriorityMap[priority];
00184 }
00185 
00186 palStatus_t pal_plat_osThreadDataInitialize (palThreadPortData* portData, int16_t priority, uint32_t stackSize)
00187 {
00188     palStatus_t status = PAL_SUCCESS;
00189     threadPortData_t* data = (threadPortData_t*)calloc(1, sizeof(threadPortData_t));
00190     uint32_t* stack = (uint32_t*)malloc(stackSize);
00191     if ((NULL == data) || (NULL == stack))
00192     {
00193         free(data);
00194         free(stack);
00195         status = PAL_ERR_RTOS_RESOURCE ;
00196     }
00197     else
00198     {
00199         data->osThread.priority = (osPriority_t)priority;
00200         data->osThread.stack_size = stackSize;
00201         data->osThread.stack_mem = stack;
00202         data->osThread.cb_mem = &(data->osThreadStorage);
00203         data->osThread.cb_size = sizeof(data->osThreadStorage);
00204         memset(&(data->osThreadStorage), 0, sizeof(data->osThreadStorage));
00205         *portData = (palThreadPortData)data;
00206     }
00207     return status;
00208 }
00209 
00210 palStatus_t pal_plat_osThreadRun (palThreadServiceBridge_t* bridge, palThreadID_t* osThreadID)
00211 {
00212     palStatus_t status = PAL_SUCCESS;
00213     threadPortData_t* portData = (threadPortData_t*)(bridge->threadData ->portData );
00214     osThreadId_t threadID = osThreadNew(threadFunction, bridge, &(portData->osThread));
00215     if (NULL == threadID)
00216     {
00217         free(portData->osThread.stack_mem);
00218         free(portData);
00219         status = PAL_ERR_GENERIC_FAILURE;
00220     }
00221     else
00222     {
00223         portData->osThreadID = threadID;
00224         *osThreadID = (palThreadID_t)threadID;
00225     }
00226     return status;
00227 }
00228 
00229 palStatus_t pal_plat_osThreadDataCleanup (palThreadData_t* threadData)
00230 {
00231     palStatus_t status = PAL_SUCCESS;
00232     threadPortData_t* portData = (threadPortData_t*)(threadData->portData );
00233     palTimerID_t timerID = NULLPTR;
00234     palThreadCleanupData_t* threadCleanupData = (palThreadCleanupData_t*)malloc(sizeof(palThreadCleanupData_t));
00235     if (NULL == threadCleanupData)
00236     {
00237         status = PAL_ERR_RTOS_RESOURCE ;
00238     }
00239     else
00240     {
00241         // mbedOS threads do not clean up on their own & also cannot clean up from self (thread), therefore we clean up using a timer
00242         status = pal_osTimerCreate(threadCleanupTimer, threadCleanupData, palOsTimerOnce, &timerID);
00243         if (PAL_SUCCESS == status)
00244         {
00245             threadCleanupData->timerID = timerID;
00246             threadCleanupData->portData = portData;
00247             if (NULL == portData->osThreadID)
00248             {
00249                 portData->osThreadID = (osThreadId_t)threadData->osThreadID ;
00250             }
00251             status = pal_osTimerStart(timerID, PAL_RTOS_THREAD_CLEANUP_TIMER_MILISEC);
00252         }
00253     }    
00254     return status;
00255 }
00256 
00257 palThreadID_t pal_plat_osThreadGetId (void)
00258 {
00259     palThreadID_t osThreadID = (palThreadID_t)osThreadGetId();
00260     return osThreadID;
00261 }
00262 
00263 palStatus_t pal_plat_osThreadTerminate (palThreadData_t* threadData)
00264 {
00265     palStatus_t status = PAL_ERR_RTOS_TASK ;
00266     osStatus_t osStatus = osOK;
00267     osThreadState_t threadState = osThreadError;
00268     threadPortData_t* portData = NULL;
00269     osThreadId_t threadID = (osThreadId_t)(threadData->osThreadID );
00270     if (osThreadGetId() != threadID) // terminate only if not trying to terminate from self
00271     {
00272         threadState = osThreadGetState(threadID);
00273         if ((osThreadTerminated != threadState) && (osThreadError != threadState) && (osThreadInactive != threadState))
00274         {
00275             osStatus = osThreadTerminate(threadID);
00276         }
00277 
00278         if (osErrorISR == osStatus)
00279         {
00280             status = PAL_ERR_RTOS_ISR ;
00281         }
00282         else
00283         {
00284             portData = (threadPortData_t*)(threadData->portData );
00285             free(portData->osThread.stack_mem);
00286             free(portData);
00287             status = PAL_SUCCESS;
00288         }
00289     }
00290     return status;
00291 }
00292 
00293 palStatus_t pal_plat_osTimerCreate (palTimerFuncPtr function, void* funcArgument, palTimerType_t timerType, palTimerID_t* timerID)
00294 {
00295     palStatus_t status = PAL_SUCCESS;
00296     palTimer_t* timer = NULL;
00297    
00298     timer = (palTimer_t*)malloc(sizeof(palTimer_t));
00299     if (NULL == timer)
00300     {
00301         status = PAL_ERR_NO_MEMORY ;
00302     }
00303 
00304     if (PAL_SUCCESS == status)
00305     {
00306         timer->osTimer.name = NULL;
00307         timer->osTimer.attr_bits = 0;
00308         timer->osTimer.cb_mem = &timer->osTimerStorage;
00309         timer->osTimer.cb_size = sizeof(timer->osTimerStorage);
00310         memset(&timer->osTimerStorage, 0, sizeof(timer->osTimerStorage));
00311     
00312         timer->timerID = (uintptr_t)osTimerNew((osTimerFunc_t)function, (osTimerType_t)timerType, funcArgument, &timer->osTimer);
00313         if (NULLPTR == timer->timerID)
00314         {
00315             free(timer);
00316             timer = NULL;
00317             status = PAL_ERR_GENERIC_FAILURE;
00318         }
00319         else
00320         {
00321             *timerID = (palTimerID_t)timer;
00322         }
00323     }
00324     return status;
00325 }
00326 
00327 palStatus_t pal_plat_osTimerStart (palTimerID_t timerID, uint32_t millisec)
00328 {
00329     palStatus_t status = PAL_SUCCESS;
00330     osStatus_t platStatus = osOK;
00331     palTimer_t* timer = NULL;
00332     
00333     timer = (palTimer_t*)timerID;
00334     platStatus = osTimerStart((osTimerId_t)timer->timerID, millisec);
00335     if (osOK == (osStatus_t)platStatus)
00336     {
00337         status = PAL_SUCCESS;
00338     }
00339     else
00340     {
00341         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00342     }
00343 
00344     return status;
00345 }
00346 
00347 palStatus_t pal_plat_osTimerStop (palTimerID_t timerID)
00348 {
00349     palStatus_t status = PAL_SUCCESS;
00350     osStatus_t platStatus = osOK;
00351     palTimer_t* timer = NULL;
00352     
00353     timer = (palTimer_t*)timerID;
00354     platStatus = osTimerStop((osTimerId_t)timer->timerID);
00355     if (osOK == platStatus)
00356     {
00357         status = PAL_SUCCESS;
00358     }
00359     else
00360     {
00361         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00362     }
00363 
00364     return status;  
00365 }
00366 
00367 palStatus_t pal_plat_osTimerDelete (palTimerID_t* timerID)
00368 {
00369     palStatus_t status = PAL_SUCCESS;
00370     osStatus_t platStatus = osOK;
00371     palTimer_t* timer = NULL;
00372     
00373     timer = (palTimer_t*)*timerID;
00374     platStatus = osTimerDelete((osTimerId_t)timer->timerID);
00375     if (osOK == platStatus)
00376     {
00377         free(timer);
00378         *timerID = NULLPTR;
00379         status = PAL_SUCCESS;
00380     }
00381     else
00382     {
00383         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00384     }
00385 
00386     return status;
00387 }
00388 
00389 
00390 palStatus_t pal_plat_osMutexCreate (palMutexID_t* mutexID)
00391 {
00392     palStatus_t status = PAL_SUCCESS;
00393     palMutex_t* mutex = NULL;
00394 
00395     mutex = (palMutex_t*)malloc(sizeof(palMutex_t));
00396     if (NULL == mutex)
00397     {
00398         status = PAL_ERR_NO_MEMORY ;
00399     }
00400 
00401     if (PAL_SUCCESS == status)
00402     {
00403         mutex->osMutex.name = NULL;
00404         mutex->osMutex.attr_bits = osMutexRecursive | osMutexRobust;
00405         mutex->osMutex.cb_mem = &mutex->osMutexStorage;
00406         mutex->osMutex.cb_size = sizeof(mutex->osMutexStorage);
00407         memset(&mutex->osMutexStorage, 0, sizeof(mutex->osMutexStorage));
00408 
00409         mutex->mutexID = (uintptr_t)osMutexNew(&mutex->osMutex);
00410         if (NULLPTR == mutex->mutexID)
00411         {
00412             free(mutex);
00413             mutex = NULL;
00414             status = PAL_ERR_GENERIC_FAILURE;
00415         }
00416         else
00417         {
00418             *mutexID = (palMutexID_t)mutex;
00419         }
00420     }
00421     return status;
00422 }
00423 
00424 
00425 palStatus_t pal_plat_osMutexWait (palMutexID_t mutexID, uint32_t millisec)
00426 {
00427     palStatus_t status = PAL_SUCCESS;
00428     osStatus_t platStatus = osOK;
00429     palMutex_t* mutex = NULL;
00430     
00431     mutex = (palMutex_t*)mutexID;
00432     platStatus = osMutexAcquire((osMutexId_t)mutex->mutexID, millisec);
00433     if (osOK == platStatus)
00434     {
00435         status = PAL_SUCCESS;
00436     }
00437     else
00438     {
00439         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00440     }
00441 
00442     return status;
00443 }
00444 
00445 
00446 palStatus_t pal_plat_osMutexRelease (palMutexID_t mutexID)
00447 {
00448     palStatus_t status = PAL_SUCCESS;
00449     osStatus_t platStatus = osOK;
00450     palMutex_t* mutex = NULL;
00451     
00452     mutex = (palMutex_t*)mutexID;
00453     platStatus = osMutexRelease((osMutexId_t)mutex->mutexID);
00454     if (osOK == platStatus)
00455     {
00456         status = PAL_SUCCESS;
00457     }
00458     else
00459     {
00460         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00461     }
00462 
00463     return status;
00464 }
00465 
00466 palStatus_t pal_plat_osMutexDelete (palMutexID_t* mutexID)
00467 {
00468     palStatus_t status = PAL_SUCCESS;
00469     osStatus_t platStatus = osOK;
00470     palMutex_t* mutex = NULL;
00471     
00472     mutex = (palMutex_t*)*mutexID;
00473     platStatus = osMutexDelete((osMutexId_t)mutex->mutexID);
00474     if (osOK == platStatus)
00475     {
00476         free(mutex);
00477         *mutexID = NULLPTR;
00478         status = PAL_SUCCESS;
00479     }
00480     else
00481     {
00482         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00483     }
00484 
00485     return status;
00486 }
00487 
00488 palStatus_t pal_plat_osSemaphoreCreate (uint32_t count, palSemaphoreID_t* semaphoreID)
00489 {
00490     palStatus_t status = PAL_SUCCESS;
00491     palSemaphore_t* semaphore = NULL;
00492     
00493     semaphore = (palSemaphore_t*)malloc(sizeof(palSemaphore_t));
00494     if (NULL == semaphore)
00495     {
00496         status = PAL_ERR_NO_MEMORY ;
00497     }
00498 
00499     if(PAL_SUCCESS == status)
00500     {
00501         semaphore->osSemaphore.cb_mem = &semaphore->osSemaphoreStorage;
00502         semaphore->osSemaphore.cb_size = sizeof(semaphore->osSemaphoreStorage);
00503         memset(&semaphore->osSemaphoreStorage, 0, sizeof(semaphore->osSemaphoreStorage));
00504 
00505         semaphore->semaphoreID = (uintptr_t)osSemaphoreNew(PAL_MAX_SEMAPHORE_COUNT, count, &semaphore->osSemaphore);
00506         if (NULLPTR == semaphore->semaphoreID)
00507         {
00508             free(semaphore);
00509             semaphore = NULL;
00510             status = PAL_ERR_GENERIC_FAILURE;
00511         }
00512         else
00513         {
00514             *semaphoreID = (palSemaphoreID_t)semaphore;
00515         }
00516     }
00517     return status;  
00518 }
00519 
00520 palStatus_t pal_plat_osSemaphoreWait (palSemaphoreID_t semaphoreID, uint32_t millisec, int32_t* countersAvailable)
00521 {
00522     palStatus_t status = PAL_SUCCESS;
00523     palSemaphore_t* semaphore = NULL;
00524     osStatus_t platStatus;
00525     
00526     semaphore = (palSemaphore_t*)semaphoreID;
00527     platStatus = osSemaphoreAcquire((osSemaphoreId_t)semaphore->semaphoreID, millisec);
00528 
00529     if (osErrorTimeout == platStatus)
00530     {
00531         status = PAL_ERR_RTOS_TIMEOUT ;
00532     }
00533     else if (platStatus != osOK)
00534     {
00535         status = PAL_ERR_RTOS_PARAMETER ;
00536     }
00537 
00538     if (NULL != countersAvailable)
00539     {
00540         *countersAvailable = osSemaphoreGetCount((osSemaphoreId_t)semaphore->semaphoreID);
00541     }
00542     return status;
00543 }
00544 
00545 palStatus_t pal_plat_osSemaphoreRelease (palSemaphoreID_t semaphoreID)
00546 {
00547     palStatus_t status = PAL_SUCCESS;
00548     osStatus_t platStatus = osOK;
00549     palSemaphore_t* semaphore = NULL;
00550 
00551     semaphore = (palSemaphore_t*)semaphoreID;
00552     platStatus = osSemaphoreRelease((osSemaphoreId_t)semaphore->semaphoreID);
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 palStatus_t pal_plat_osSemaphoreDelete (palSemaphoreID_t* semaphoreID)
00566 {
00567     palStatus_t status = PAL_SUCCESS;
00568     osStatus_t platStatus = osOK;
00569     palSemaphore_t* semaphore = NULL;
00570     
00571     semaphore = (palSemaphore_t*)*semaphoreID;
00572     platStatus = osSemaphoreDelete((osSemaphoreId_t)semaphore->semaphoreID);
00573     if (osOK == platStatus)
00574     {
00575         free(semaphore);
00576         *semaphoreID = NULLPTR;
00577         status = PAL_SUCCESS;
00578     }
00579     else
00580     {
00581         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00582     }
00583 
00584     return status;  
00585 }
00586 
00587 int32_t pal_plat_osAtomicIncrement (int32_t* valuePtr, int32_t increment)
00588 {
00589     if (increment >= 0)
00590     {
00591         return core_util_atomic_incr_u32((uint32_t*)valuePtr, increment);
00592     }
00593     else
00594     {
00595         return core_util_atomic_decr_u32((uint32_t*)valuePtr, 0 - increment);
00596     }
00597 }
00598 
00599 
00600  void *pal_plat_malloc (size_t len)
00601 {
00602     return malloc(len);
00603 }
00604 
00605 
00606  void pal_plat_free (void * buffer)
00607 {
00608     return free(buffer);
00609 }
00610 
00611 palStatus_t pal_plat_osRandomBuffer (uint8_t *randomBuf, size_t bufSizeBytes, size_t* actualRandomSizeBytes)
00612 {
00613     palStatus_t status = PAL_SUCCESS;
00614     int32_t platStatus = 0;
00615     size_t actualOutputLen = 0;
00616     platStatus = mbedtls_hardware_poll(NULL /*Not used by the function*/, randomBuf, bufSizeBytes, &actualOutputLen);
00617     if ((0 != platStatus) || (0 == actualOutputLen))
00618     {
00619         status = PAL_ERR_RTOS_TRNG_FAILED ;
00620     }
00621     else if (actualOutputLen != bufSizeBytes)
00622     {
00623         status = PAL_ERR_RTOS_TRNG_PARTIAL_DATA ;
00624     }
00625 
00626     if (NULL != actualRandomSizeBytes)
00627     {
00628         *actualRandomSizeBytes = actualOutputLen;
00629     }
00630     return status;
00631 }
00632 
00633 #if (PAL_USE_HW_RTC)
00634 palStatus_t pal_plat_osGetRtcTime(uint64_t *rtcGetTime)
00635 {
00636     palStatus_t ret = PAL_SUCCESS;
00637     if(rtcGetTime != NULL)
00638     {
00639         *rtcGetTime = (uint64_t)time(NULL);
00640     }
00641     else
00642     {
00643         ret = PAL_ERR_NULL_POINTER ;
00644     }
00645     return ret;
00646 }
00647 
00648 palStatus_t pal_plat_osSetRtcTime(uint64_t rtcSetTime)
00649 {
00650     palStatus_t status = PAL_SUCCESS;
00651     if (rtcSetTime < (uint64_t)PAL_MIN_RTC_SET_TIME)
00652     {
00653         status = PAL_ERR_INVALID_TIME ;
00654     }
00655     else
00656     {
00657         set_time(rtcSetTime);
00658     }
00659 
00660     return status;
00661 }
00662 
00663 palStatus_t pal_plat_rtcInit(void)
00664 {
00665     palStatus_t ret = PAL_SUCCESS;
00666     return ret;
00667 }
00668 
00669 palStatus_t pal_plat_rtcDeInit(void)
00670 {
00671     palStatus_t ret = PAL_SUCCESS;
00672     return ret;
00673 }
00674 #endif //#if (PAL_USE_HW_RTC)
00675 
00676 
00677 #endif