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