Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_plat_rtos.c Source File

pal_plat_rtos.c

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 /* PAL-RTOS porting for FreeRTOS-8.1.2
00018 *  This is porting code for PAL RTOS APIS for 
00019 *  FreeRTOS-8.1.2 version.
00020 */
00021 
00022 #include "board.h"
00023 #include "FreeRTOS.h"
00024 #include "event_groups.h"
00025 #include "semphr.h"
00026 #include "task.h"
00027 
00028 
00029 #include "pal.h"
00030 #include "pal_plat_rtos.h"
00031 #include <stdlib.h>
00032 
00033 #define TRACE_GROUP "PAL"
00034 
00035 #define PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(cmsisCode)\
00036     ((int32_t)(cmsisCode + PAL_ERR_RTOS_ERROR_BASE))
00037 
00038 #define PAL_TICK_TO_MILLI_FACTOR 1000
00039 
00040 extern palStatus_t pal_plat_getRandomBufferFromHW(uint8_t *randomBuf, size_t bufSizeBytes, size_t* actualRandomSizeBytes);
00041 
00042 /////////////////////////STATIC FUNCTION///////////////////////////
00043 /*! Get IPSR Register
00044 *
00045 * @param[in] Void
00046 * \returns uint32 - the content of the IPSR Register.
00047 *
00048 */
00049 PAL_PRIVATE PAL_INLINE uint32_t pal_plat_GetIPSR(void);
00050 /////////////////////////END STATIC FUNCTION///////////////////////////
00051 
00052 //! Timer structure
00053 typedef struct palTimer{
00054     palTimerID_t            timerID;
00055     //    uint32_t                internalTimerData[PAL_TIMER_DATA_SIZE];  ///< pointer to internal data
00056     TimerCallbackFunction_t function;
00057     void*                   functionArgs;
00058     uint32_t                timerType;
00059 } palTimer_t;
00060 
00061 //! Mutex structure
00062 typedef struct palMutex{
00063     palMutexID_t            mutexID;
00064 }palMutex_t;
00065 
00066 //! Semaphore structure
00067 typedef struct palSemaphore{
00068     palSemaphoreID_t        semaphoreID;
00069     uint32_t                maxCount;
00070 }palSemaphore_t;
00071 
00072 typedef struct palThreadData
00073 {
00074     palThreadFuncPtr userFunction;
00075     void* userFunctionArgument;
00076     TaskHandle_t sysThreadID;
00077 } palThreadData_t;
00078 
00079 #define PAL_MAX_CONCURRENT_THREADS 20
00080 
00081 PAL_PRIVATE palMutexID_t g_threadsMutex = NULLPTR;
00082 PAL_PRIVATE palThreadData_t* g_threadsArray[PAL_MAX_CONCURRENT_THREADS] = { 0 };
00083 
00084 #define PAL_THREADS_MUTEX_LOCK(status) \
00085     { \
00086         status = pal_osMutexWait(g_threadsMutex, PAL_RTOS_WAIT_FOREVER); \
00087         if (PAL_SUCCESS != status)\
00088         { \
00089             PAL_LOG_ERR("%s mutex wait failed\n", __FUNCTION__); \
00090         } \
00091     }
00092 
00093 #define PAL_THREADS_MUTEX_UNLOCK(status) \
00094     { \
00095         status = pal_osMutexRelease(g_threadsMutex); \
00096         if (PAL_SUCCESS != status)\
00097         { \
00098             PAL_LOG_ERR("%s mutex release failed\n", __FUNCTION__); \
00099         } \
00100     }
00101 
00102 PAL_PRIVATE void threadFree(palThreadData_t** threadData);
00103 
00104 PAL_PRIVATE PAL_INLINE uint32_t pal_plat_GetIPSR(void)
00105 {
00106     uint32_t result;
00107 
00108 #if defined (__CC_ARM)
00109     __asm volatile
00110     {
00111         MRS result, ipsr
00112     }
00113 #elif defined (__GNUC__)
00114     __asm volatile ("MRS %0, ipsr" : "=r" (result) );
00115 #endif
00116 
00117     return(result);
00118 }
00119 
00120 palStatus_t pal_plat_RTOSInitialize(void* opaqueContext)
00121 {
00122     palStatus_t status = pal_osMutexCreate(&g_threadsMutex);
00123     if (PAL_SUCCESS != status)
00124     {
00125         goto end;
00126     }
00127 
00128     PAL_THREADS_MUTEX_LOCK(status);
00129     if (PAL_SUCCESS != status)
00130     {
00131         goto end;
00132     }
00133     for (int i = 0; i < PAL_MAX_CONCURRENT_THREADS; i++)
00134     {
00135         if (g_threadsArray[i])
00136         {
00137             threadFree(&g_threadsArray[i]);
00138         }
00139     }
00140     PAL_THREADS_MUTEX_UNLOCK(status);
00141     if (PAL_SUCCESS != status)
00142     {
00143         goto end;
00144     }
00145 #if (PAL_USE_HW_RTC)
00146     if (PAL_SUCCESS == status)
00147     {
00148         status = pal_plat_rtcInit();        
00149     }
00150 #endif
00151 end:
00152     return status;
00153 }
00154 
00155 palStatus_t pal_plat_RTOSDestroy(void)
00156 {
00157     palStatus_t status = PAL_SUCCESS;
00158     if (NULLPTR != g_threadsMutex)
00159     {
00160         status = pal_osMutexDelete(&g_threadsMutex);
00161         g_threadsMutex = NULLPTR;
00162     }
00163 #if (PAL_USE_HW_RTC)
00164     if (PAL_SUCCESS == status)
00165     {
00166         status = pal_plat_rtcDeInit();
00167     }
00168 #endif
00169     return status;
00170 }
00171 
00172 palStatus_t pal_plat_osDelay(uint32_t milliseconds)
00173 {
00174     vTaskDelay(milliseconds / portTICK_PERIOD_MS);
00175     return PAL_SUCCESS;
00176 }
00177 
00178 
00179 uint64_t pal_plat_osKernelSysTick()
00180 {
00181 
00182     uint64_t result;
00183     if (pal_plat_GetIPSR() != 0)
00184     {
00185         result = xTaskGetTickCountFromISR();
00186     }
00187     else
00188     {
00189         result = xTaskGetTickCount();
00190     }
00191     return result;
00192 }
00193 
00194 uint64_t pal_plat_osKernelSysTickMicroSec(uint64_t microseconds)
00195 {
00196     uint64_t sysTicks = microseconds * configTICK_RATE_HZ / (PAL_TICK_TO_MILLI_FACTOR * PAL_TICK_TO_MILLI_FACTOR);
00197     return sysTicks;
00198 }
00199 
00200 uint64_t pal_plat_osKernelSysTickFrequency()
00201 {
00202     return configTICK_RATE_HZ;
00203 }
00204 
00205 PAL_PRIVATE PAL_INLINE palThreadData_t** threadAllocate(void)
00206 {
00207     palThreadData_t** threadData = NULL;
00208     for (int i = 0; i < PAL_MAX_CONCURRENT_THREADS; i++)
00209     {
00210         if (!g_threadsArray[i])
00211         {
00212             g_threadsArray[i] = (palThreadData_t*)calloc(1, sizeof(palThreadData_t));
00213             if (g_threadsArray[i])
00214             {
00215                 threadData = &g_threadsArray[i];
00216             }
00217             break;
00218         }
00219     }
00220     return threadData;
00221 }
00222 
00223 PAL_PRIVATE void threadFree(palThreadData_t** threadData)
00224 {
00225     (*threadData)->userFunction = NULL;
00226     (*threadData)->userFunctionArgument = NULL;
00227     (*threadData)->sysThreadID = NULL;
00228     free(*threadData);
00229     *threadData = NULL;
00230 }
00231 
00232 PAL_PRIVATE palThreadData_t** threadFind(const TaskHandle_t sysThreadID)
00233 {
00234     palThreadData_t** threadData = NULL;
00235     for (int i = 0; i < PAL_MAX_CONCURRENT_THREADS; i++)
00236     {
00237         if (sysThreadID == g_threadsArray[i]->sysThreadID)
00238         {
00239             threadData = &g_threadsArray[i];
00240             break;
00241         }
00242     }
00243     return threadData;
00244 }
00245 
00246 PAL_PRIVATE void threadFunction(void* arg)
00247 {
00248     palStatus_t status = PAL_SUCCESS;
00249     palThreadData_t** threadData;
00250     palThreadFuncPtr userFunction;
00251     void* userFunctionArgument;
00252     
00253     PAL_THREADS_MUTEX_LOCK(status);
00254     if (PAL_SUCCESS != status)
00255     {
00256         goto end;
00257     }
00258     threadData = (palThreadData_t**)arg;
00259     userFunction = (*threadData)->userFunction;
00260     userFunctionArgument = (*threadData)->userFunctionArgument;
00261     if (NULL == (*threadData)->sysThreadID) // maybe null if this thread has a higher priority than the thread which created this thread
00262     {
00263         (*threadData)->sysThreadID = xTaskGetCurrentTaskHandle(); // set the thread id
00264     }    
00265     PAL_THREADS_MUTEX_UNLOCK(status);
00266     if (PAL_SUCCESS != status)
00267     {
00268         goto end;
00269     }
00270     
00271     userFunction(userFunctionArgument); // invoke user function with user argument (use local vars) - note we're not under mutex lock anymore
00272     
00273     PAL_THREADS_MUTEX_LOCK(status);
00274     if (PAL_SUCCESS != status)
00275     {
00276         goto end;
00277     }
00278     threadFree(threadData); // clean up
00279     PAL_THREADS_MUTEX_UNLOCK(status)
00280 end:
00281     vTaskDelete(NULL);
00282 }
00283 
00284 palStatus_t pal_plat_osThreadCreate(palThreadFuncPtr function, void* funcArgument, palThreadPriority_t priority, uint32_t stackSize, palThreadID_t* threadID)
00285 {
00286     palStatus_t status = PAL_SUCCESS;
00287     palThreadData_t** threadData;
00288     TaskHandle_t sysThreadID = NULLPTR;    
00289 
00290     PAL_THREADS_MUTEX_LOCK(status);
00291     if (PAL_SUCCESS != status)
00292     {
00293         goto end;
00294     }
00295     threadData = threadAllocate(); // allocate thread data from the global array
00296     PAL_THREADS_MUTEX_UNLOCK(status);
00297     if (PAL_SUCCESS != status)
00298     {
00299         goto end;
00300     }
00301 
00302     if (NULL == threadData) // allocation failed or all array slots are occupied
00303     {
00304         status = PAL_ERR_RTOS_RESOURCE ;
00305         goto end;
00306     }
00307 
00308     (*threadData)->userFunction = function; // note that threadData is safe here (eventhough it's not mutex locked), no other thread will attempt to change it until the thread is either finished or terminated
00309     (*threadData)->userFunctionArgument = funcArgument;
00310     
00311     //Note: the stack in this API is handled as an array of "StackType_t" which can be of different sizes for different ports.
00312     //      in this specific port of (8.1.2) the "StackType_t" is defined to 4-bytes this is why we divide the "stackSize" parameter by "sizeof(uint32_t)".
00313     //      inside freeRTOS code, the stack size is calculated according to the following formula: "((size_t)usStackDepth) * sizeof(StackType_t)"
00314     //       where "usStackDepth" is equal to "stackSize / sizeof(uint32_t)"
00315     BaseType_t result = xTaskGenericCreate((TaskFunction_t)threadFunction,
00316         "palTask",
00317         (stackSize / sizeof(uint32_t)),
00318         threadData,
00319         (int16_t)priority,
00320         &sysThreadID,
00321         NULL, //if stack pointer is NULL then allocate the stack according to stack size
00322         NULL);
00323 
00324     PAL_THREADS_MUTEX_LOCK(status);
00325     if (PAL_SUCCESS != status)
00326     {
00327         goto end;
00328     }
00329     if (pdPASS == result)
00330     {        
00331         if ((NULL != *threadData) && (NULL == (*threadData)->sysThreadID)) // *threadData maybe null in case the thread has already finished and cleaned up, sysThreadID maybe null if the created thread is lower priority than the creating thread
00332         {
00333             (*threadData)->sysThreadID = sysThreadID; // set the thread id
00334         }
00335         *threadID = (palThreadID_t)sysThreadID;
00336     }   
00337     else
00338     {
00339         threadFree(threadData); // thread creation failed so clean up dynamic allocations etc.
00340         status = PAL_ERR_GENERIC_FAILURE ;
00341     }
00342     PAL_THREADS_MUTEX_UNLOCK(status);
00343 end:
00344     return status;
00345 }
00346 
00347 palThreadID_t pal_plat_osThreadGetId(void)
00348 {
00349     palThreadID_t threadID = (palThreadID_t)xTaskGetCurrentTaskHandle();
00350     return threadID;
00351 }
00352 
00353 palStatus_t pal_plat_osThreadTerminate(palThreadID_t* threadID)
00354 {
00355     palStatus_t status = PAL_ERR_RTOS_TASK ;
00356     TaskHandle_t sysThreadID = (TaskHandle_t)*threadID;
00357     palThreadData_t** threadData;
00358     if (xTaskGetCurrentTaskHandle() != sysThreadID) // self termination not allowed
00359     {
00360         PAL_THREADS_MUTEX_LOCK(status);
00361         if (PAL_SUCCESS != status)
00362         {
00363             goto end;
00364         }
00365         threadData = threadFind(sysThreadID);
00366         if (threadData) // thread may have ended or terminated already
00367         {
00368             vTaskDelete(sysThreadID);
00369             threadFree(threadData);
00370         }
00371         PAL_THREADS_MUTEX_UNLOCK(status);        
00372     }
00373 end:
00374     return status;
00375 }
00376 
00377 PAL_PRIVATE palTimer_t* s_timerArrays[PAL_MAX_NUM_OF_TIMERS] = {0};
00378 
00379 PAL_PRIVATE void pal_plat_osTimerWarpperFunction( TimerHandle_t xTimer )
00380 {
00381     int i;
00382     palTimer_t* timer = NULL;
00383     for(i=0 ; i< PAL_MAX_NUM_OF_TIMERS ; i++)
00384     {
00385         if (s_timerArrays[i]->timerID == (palTimerID_t)xTimer)
00386         {
00387             timer = s_timerArrays[i];
00388             timer->function(timer->functionArgs);
00389 
00390         }
00391     }
00392 }
00393 
00394 palStatus_t pal_plat_osTimerCreate(palTimerFuncPtr function, void* funcArgument, palTimerType_t timerType, palTimerID_t* timerID)
00395 {
00396     palStatus_t status = PAL_SUCCESS;
00397     palTimer_t* timer = NULL;
00398     int i;
00399     if(NULL == timerID || NULL == function)
00400     {
00401         return PAL_ERR_INVALID_ARGUMENT ;
00402     }
00403 
00404     timer = (palTimer_t*)malloc(sizeof(palTimer_t));
00405 
00406     if (NULL == timer)
00407     {
00408         status = PAL_ERR_NO_MEMORY ;
00409     }
00410     else
00411     {
00412         memset(timer,0,sizeof(palTimer_t));
00413     }
00414 
00415     if (PAL_SUCCESS == status)
00416     {
00417         for (i=0; i< PAL_MAX_NUM_OF_TIMERS; i++)
00418         {
00419             if (s_timerArrays[i] == NULL)
00420             {
00421                 s_timerArrays[i] = timer;
00422                 break;
00423             }
00424         }
00425         if (PAL_MAX_NUM_OF_TIMERS == i)
00426         {
00427             status = PAL_ERR_NO_MEMORY ;
00428         }
00429         if (PAL_SUCCESS == status)
00430         {
00431             timer->function = (TimerCallbackFunction_t)function;
00432             timer->functionArgs = funcArgument;
00433             timer->timerType = timerType;
00434 
00435             timer->timerID = (palTimerID_t)xTimerCreate(
00436                     "timer",
00437                     1, // xTimerPeriod - cannot be '0'
00438                     (const TickType_t)timerType, // 0 = osTimerOnce, 1 = osTimerPeriodic
00439                     NULL,
00440                     (TimerCallbackFunction_t)pal_plat_osTimerWarpperFunction
00441             );
00442         }
00443         if (NULLPTR == timer->timerID)
00444         {
00445             free(timer);
00446             timer = NULLPTR;
00447             PAL_LOG_ERR("Rtos timer create failure");
00448             status = PAL_ERR_GENERIC_FAILURE ;
00449         }
00450         else
00451         {
00452             *timerID = (palTimerID_t)timer;
00453         }
00454     }
00455     return status;
00456 }
00457 
00458 palStatus_t pal_plat_osTimerStart(palTimerID_t timerID, uint32_t millisec)
00459 {
00460     palStatus_t status = PAL_SUCCESS;
00461     palTimer_t* timer = NULL;
00462 
00463     if (NULLPTR == timerID)
00464     {
00465         return PAL_ERR_INVALID_ARGUMENT ;
00466     }
00467 
00468     timer = (palTimer_t*)timerID;
00469 
00470     if (pal_plat_GetIPSR() != 0)
00471     {
00472         BaseType_t pxHigherPriorityTaskWoken;
00473         status = xTimerChangePeriodFromISR(
00474                 (TimerHandle_t)(timer->timerID),
00475                 (millisec / portTICK_PERIOD_MS),
00476                 &pxHigherPriorityTaskWoken
00477         );
00478     }
00479     else
00480     {
00481         status =  xTimerChangePeriod((TimerHandle_t)(timer->timerID), (millisec / portTICK_PERIOD_MS), 0);
00482     }
00483 
00484     if (pdPASS != status)
00485     {
00486         status =  PAL_ERR_RTOS_PARAMETER ;
00487     }
00488     if (pdPASS == status)
00489     {
00490         if (pal_plat_GetIPSR() != 0)
00491         {
00492             BaseType_t pxHigherPriorityTaskWoken;
00493             status = xTimerStartFromISR((TimerHandle_t)(timer->timerID), &pxHigherPriorityTaskWoken);
00494         }
00495         else
00496         {
00497             status = xTimerStart((TimerHandle_t)(timer->timerID), 0);
00498         }
00499 
00500         if (pdPASS != status)
00501         {
00502             status =  PAL_ERR_RTOS_PARAMETER ;
00503         }
00504         else
00505         {
00506             status = PAL_SUCCESS;
00507         }
00508     }
00509     return status;
00510 }
00511 
00512 palStatus_t pal_plat_osTimerStop(palTimerID_t timerID)
00513 {
00514     palStatus_t status = PAL_SUCCESS;
00515     palTimer_t* timer = NULL;
00516 
00517     if(NULLPTR == timerID)
00518     {
00519         return PAL_ERR_INVALID_ARGUMENT ;
00520     }
00521 
00522     timer = (palTimer_t*)timerID;
00523 
00524     if (pal_plat_GetIPSR() != 0)
00525     {
00526         BaseType_t pxHigherPriorityTaskWoken;
00527         status = xTimerStopFromISR((TimerHandle_t)(timer->timerID), &pxHigherPriorityTaskWoken);
00528     }
00529     else
00530     {
00531         status = xTimerStop((TimerHandle_t)(timer->timerID), 0);
00532     }
00533 
00534 
00535     if (pdPASS != status)
00536     {
00537         status = PAL_ERR_RTOS_PARAMETER ;
00538     }
00539     else
00540     {
00541         status = PAL_SUCCESS;
00542     }
00543     return status;
00544 }
00545 
00546 palStatus_t pal_plat_osTimerDelete(palTimerID_t* timerID)
00547 {
00548     palStatus_t status = PAL_ERR_RTOS_PARAMETER ;
00549     palTimer_t* timer = NULL;
00550     int i;
00551 
00552     if(NULL == timerID || NULLPTR == *timerID)
00553     {
00554         return PAL_ERR_INVALID_ARGUMENT ;
00555     }
00556 
00557     timer = (palTimer_t*)*timerID;
00558 
00559     if (timer->timerID)
00560     {
00561         for(i=0 ; i< PAL_MAX_NUM_OF_TIMERS ; i++)
00562         {
00563             if (s_timerArrays[i] == timer)
00564             {
00565                 status = xTimerDelete((TimerHandle_t)(timer->timerID), 0);
00566                 free(timer);
00567                 s_timerArrays[i] = NULL;
00568                 *timerID = NULLPTR;
00569                 break;
00570             }
00571         }
00572 
00573         if (pdPASS == status)
00574         {
00575             status = PAL_SUCCESS;
00576         }
00577         else
00578         {
00579             status = PAL_ERR_RTOS_PARAMETER ;
00580         }
00581     }
00582     else
00583     {
00584         status = PAL_ERR_RTOS_PARAMETER ;
00585     }
00586 
00587     return status;
00588 }
00589 
00590 
00591 palStatus_t pal_plat_osMutexCreate(palMutexID_t* mutexID)
00592 {
00593 
00594     palStatus_t status = PAL_SUCCESS;
00595     palMutex_t* mutex = NULL;
00596     if(NULL == mutexID)
00597     {
00598         return PAL_ERR_INVALID_ARGUMENT ;
00599     }
00600 
00601     mutex = (palMutex_t*)malloc(sizeof(palMutex_t));
00602     if (NULL == mutex)
00603     {
00604         status = PAL_ERR_NO_MEMORY ;
00605     }
00606 
00607     if (PAL_SUCCESS == status)
00608     {
00609 
00610         mutex->mutexID = (uintptr_t) xSemaphoreCreateRecursiveMutex();
00611         if (NULLPTR == mutex->mutexID)
00612         {
00613             free(mutex);
00614             mutex = NULL;
00615             PAL_LOG_ERR("Rtos mutex create failure");
00616             status = PAL_ERR_GENERIC_FAILURE ;
00617         }
00618         *mutexID = (palMutexID_t)mutex;
00619     }
00620     return status;
00621 }
00622 
00623 
00624 palStatus_t pal_plat_osMutexWait(palMutexID_t mutexID, uint32_t millisec)
00625 {
00626 
00627     palStatus_t status = PAL_SUCCESS;
00628     palMutex_t* mutex = NULL;
00629     BaseType_t res = pdTRUE;
00630 
00631     if(NULLPTR == mutexID)
00632     {
00633         return PAL_ERR_INVALID_ARGUMENT ;
00634     }
00635 
00636     mutex = (palMutex_t*)mutexID;
00637     if (pal_plat_GetIPSR() != 0)
00638     {
00639         BaseType_t pxHigherPriorityTaskWoken;
00640         res = xSemaphoreTakeFromISR(mutex->mutexID, &pxHigherPriorityTaskWoken);
00641     }
00642     else
00643     {
00644         res = xSemaphoreTakeRecursive((QueueHandle_t)(mutex->mutexID), (millisec / portTICK_PERIOD_MS) );
00645     }
00646 
00647     if (pdTRUE == res)
00648     {
00649         status = PAL_SUCCESS;
00650     }
00651     else
00652     {
00653         status = PAL_ERR_RTOS_TIMEOUT ;
00654     }
00655 
00656     return status;
00657 }
00658 
00659 
00660 palStatus_t pal_plat_osMutexRelease(palMutexID_t mutexID)
00661 {
00662     palStatus_t status = PAL_SUCCESS;
00663     palMutex_t* mutex = NULL;
00664     BaseType_t res = pdTRUE;
00665 
00666     if(NULLPTR == mutexID)
00667     {
00668         return PAL_ERR_INVALID_ARGUMENT ;
00669     }
00670 
00671     mutex = (palMutex_t*)mutexID;
00672     if (pal_plat_GetIPSR() != 0)
00673     {
00674         BaseType_t pxHigherPriorityTaskWoken;
00675         res = xSemaphoreGiveFromISR(mutex->mutexID, &pxHigherPriorityTaskWoken);
00676     }
00677     else
00678     {
00679         res = xSemaphoreGiveRecursive((QueueHandle_t)(mutex->mutexID));
00680     }
00681 
00682     if (pdTRUE == res)
00683     {
00684         status = PAL_SUCCESS;
00685     }
00686     else
00687     {
00688         PAL_LOG_ERR("Rtos mutex release failure %ld", res);
00689         status = PAL_ERR_GENERIC_FAILURE ;
00690     }
00691     return status;
00692 }
00693 
00694 palStatus_t pal_plat_osMutexDelete(palMutexID_t* mutexID)
00695 {
00696     palStatus_t status = PAL_SUCCESS;
00697     palMutex_t* mutex = NULL;
00698 
00699     if(NULL == mutexID || NULLPTR == *mutexID)
00700     {
00701         return PAL_ERR_INVALID_ARGUMENT ;
00702     }
00703 
00704     mutex = (palMutex_t*)*mutexID;
00705     if (NULLPTR != mutex->mutexID)
00706     {
00707         vSemaphoreDelete(mutex->mutexID);
00708         free(mutex);
00709         *mutexID = NULLPTR;
00710         status = PAL_SUCCESS;
00711     }
00712     else
00713     {
00714         PAL_LOG_ERR("Rtos mutex delete failure");
00715         status = PAL_ERR_GENERIC_FAILURE ;
00716     }
00717     return status;
00718 }
00719 
00720 palStatus_t pal_plat_osSemaphoreCreate(uint32_t count, palSemaphoreID_t* semaphoreID)
00721 {
00722     palStatus_t status = PAL_SUCCESS;
00723     palSemaphore_t* semaphore = NULL;
00724 
00725     if(NULL == semaphoreID)
00726     {
00727         return PAL_ERR_INVALID_ARGUMENT ;
00728     }
00729 
00730     semaphore = (palSemaphore_t*)malloc(sizeof(palSemaphore_t));
00731     if (NULL == semaphore)
00732     {
00733         status = PAL_ERR_NO_MEMORY ;
00734     }
00735 
00736     if(PAL_SUCCESS == status)
00737     {
00738         semaphore->semaphoreID = (uintptr_t)xSemaphoreCreateCounting(PAL_SEMAPHORE_MAX_COUNT, count);
00739         semaphore->maxCount = PAL_SEMAPHORE_MAX_COUNT;
00740         if (NULLPTR == semaphore->semaphoreID)
00741         {
00742             free(semaphore);
00743             semaphore = NULLPTR;
00744             PAL_LOG_ERR("Rtos semaphore create error");
00745             status = PAL_ERR_GENERIC_FAILURE ;
00746         }
00747         else
00748         {
00749             *semaphoreID = (palSemaphoreID_t)semaphore;
00750         }
00751     }
00752     return status;
00753 }
00754 
00755 palStatus_t pal_plat_osSemaphoreWait(palSemaphoreID_t semaphoreID, uint32_t millisec, int32_t* countersAvailable)
00756 {
00757     palStatus_t status = PAL_SUCCESS;
00758     palSemaphore_t* semaphore = NULL;
00759     int32_t tmpCounters = 0;
00760     BaseType_t res = pdTRUE;
00761 
00762     if(NULLPTR == semaphoreID)
00763     {
00764         return PAL_ERR_INVALID_ARGUMENT ;
00765     }
00766 
00767     semaphore = (palSemaphore_t*)semaphoreID;
00768     if (pal_plat_GetIPSR() != 0)
00769     {
00770         BaseType_t pxHigherPriorityTaskWoken;
00771         res = xSemaphoreTakeFromISR(semaphore->semaphoreID, &pxHigherPriorityTaskWoken);
00772     }
00773     else
00774     {
00775         if (millisec == PAL_RTOS_WAIT_FOREVER)
00776         {
00777             res = xSemaphoreTake(semaphore->semaphoreID, portMAX_DELAY);
00778         }
00779         else
00780         {
00781             res = xSemaphoreTake(semaphore->semaphoreID, millisec / portTICK_PERIOD_MS);
00782         }
00783     }
00784 
00785     if (pdTRUE == res)
00786     {
00787         
00788         tmpCounters = uxQueueMessagesWaiting((QueueHandle_t)(semaphore->semaphoreID));
00789     }
00790     else
00791     {
00792         tmpCounters = 0;
00793         status = PAL_ERR_RTOS_TIMEOUT ;
00794     }
00795 
00796     if (NULL != countersAvailable)
00797     {
00798         //because mbedOS returns the number available BEFORE the current take, we have to add 1 here.
00799         *countersAvailable = tmpCounters;
00800     }
00801     return status;
00802 }
00803 
00804 palStatus_t pal_plat_osSemaphoreRelease(palSemaphoreID_t semaphoreID)
00805 {
00806     palStatus_t status = PAL_SUCCESS;
00807     palSemaphore_t* semaphore = NULL;
00808     BaseType_t res = pdTRUE;
00809     int32_t tmpCounters = 0;
00810 
00811     if(NULLPTR == semaphoreID)
00812     {
00813         return PAL_ERR_INVALID_ARGUMENT ;
00814     }
00815 
00816     semaphore = (palSemaphore_t*)semaphoreID;
00817 
00818     tmpCounters = uxQueueMessagesWaiting((QueueHandle_t)(semaphore->semaphoreID));
00819 
00820     if(tmpCounters < semaphore->maxCount)
00821     {
00822         if (pal_plat_GetIPSR() != 0)
00823         {
00824             BaseType_t pxHigherPriorityTaskWoken;
00825             res = xSemaphoreGiveFromISR(semaphore->semaphoreID, &pxHigherPriorityTaskWoken);
00826         }
00827         else
00828         {
00829             res = xSemaphoreGive(semaphore->semaphoreID);
00830         }
00831 
00832         if (pdTRUE != res)
00833         {   
00834             status = PAL_ERR_RTOS_PARAMETER ;
00835         }
00836     }
00837     else 
00838     {
00839         status = PAL_ERR_RTOS_RESOURCE ;
00840     }
00841     
00842     return status;
00843 }
00844 
00845 palStatus_t pal_plat_osSemaphoreDelete(palSemaphoreID_t* semaphoreID)
00846 {
00847     palStatus_t status = PAL_SUCCESS;
00848     palSemaphore_t* semaphore = NULL;
00849 
00850     if(NULL == semaphoreID || NULLPTR == *semaphoreID)
00851     {
00852         return PAL_ERR_INVALID_ARGUMENT ;
00853     }
00854 
00855     semaphore = (palSemaphore_t*)*semaphoreID;
00856     if (NULLPTR != semaphore->semaphoreID)
00857     {
00858         vSemaphoreDelete(semaphore->semaphoreID);
00859         free(semaphore);
00860         *semaphoreID = NULLPTR;
00861         status = PAL_SUCCESS;
00862     }
00863     else
00864     {
00865         PAL_LOG_ERR("Rtos semaphore destroy error");
00866         status = PAL_ERR_GENERIC_FAILURE ;
00867     }
00868     return status;
00869 }
00870 
00871 
00872 void *pal_plat_malloc(size_t len)
00873 {
00874     return malloc(len);
00875 }
00876 
00877 
00878 void pal_plat_free(void * buffer)
00879 {
00880     free(buffer);
00881 }
00882 
00883 
00884 palStatus_t pal_plat_osRandomBuffer(uint8_t *randomBuf, size_t bufSizeBytes, size_t* actualRandomSizeBytes)
00885 {
00886     palStatus_t status = PAL_SUCCESS;
00887 
00888     status = pal_plat_getRandomBufferFromHW(randomBuf, bufSizeBytes, actualRandomSizeBytes);
00889     return status;
00890 }
00891 
00892