Mbed Cloud example program for workshop in W27 2018.

Dependencies:   MMA7660 LM75B

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_plat_rtos.cpp Source File

pal_plat_rtos.cpp

00001 /*
00002 * Copyright (c) 2016 ARM Limited. All rights reserved.
00003 * SPDX-License-Identifier: Apache-2.0
00004 * Licensed under the Apache License, Version 2.0 (the License); you may
00005 * 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, WITHOUT
00012 * 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 
00019 
00020 #include "pal_types.h"
00021 #include "pal_rtos.h"
00022 #include "pal_plat_rtos.h"
00023 #include "pal_errors.h"
00024 #include "stdlib.h"
00025 #include "string.h"
00026 
00027 #include "mbed.h"
00028 
00029 #include "entropy_poll.h"
00030 
00031 
00032 /*
00033     mbedOS latest version RTOS support
00034 */
00035 #if defined(osRtxVersionAPI) && (osRtxVersionAPI >= 20000000)
00036 
00037 #include "cmsis_os2.h" // Revision:    V2.1
00038 
00039 
00040 #define PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(cmsisCode)\
00041     ((int32_t)((int32_t)cmsisCode + PAL_ERR_RTOS_ERROR_BASE))
00042 
00043 typedef struct palThreadFuncWrapper{
00044     palTimerFuncPtr         realThreadFunc;
00045     void*                   realThreadArgs;
00046     uint32_t                threadIndex;
00047 }palThreadFuncWrapper_t;
00048 
00049 //! Thread structure
00050 typedef struct palThread{
00051     palThreadID_t              threadID;
00052     uint32_t                   palThreadID;
00053     bool                       initialized;
00054     palThreadLocalStore_t*     threadStore; //! please see pal_rtos.h for documentation
00055     palThreadFuncWrapper_t     threadFuncWrapper;
00056     osThreadAttr_t             osThread;
00057     mbed_rtos_storage_thread_t osThreadStorage;
00058 } palThread_t;
00059 
00060 /*! Count number of created threads. Initiate to zero.
00061 */
00062 PAL_PRIVATE uint32_t g_threadCounter = 0;
00063 palThread_t g_palThreads[PAL_MAX_NUMBER_OF_THREADS] = {0};
00064 
00065 //! Timer structure
00066 typedef struct palTimer{
00067     palTimerID_t              timerID;
00068     osTimerAttr_t             osTimer;
00069     mbed_rtos_storage_timer_t osTimerStorage;
00070 } palTimer_t;
00071 
00072 //! Mutex structure
00073 typedef struct palMutex{
00074     palMutexID_t              mutexID;
00075     osMutexAttr_t             osMutex;
00076     mbed_rtos_storage_mutex_t osMutexStorage;
00077 }palMutex_t;
00078 
00079 //! Semaphore structure
00080 typedef struct palSemaphore{
00081     palSemaphoreID_t              semaphoreID;
00082     osSemaphoreAttr_t             osSemaphore;
00083     mbed_rtos_storage_semaphore_t osSemaphoreStorage;
00084 }palSemaphore_t;
00085 
00086 //! Memoey Pool structure
00087 typedef struct palMemPool{
00088     palMemoryPoolID_t            memoryPoolID;
00089     osMemoryPoolAttr_t           osPool;
00090     mbed_rtos_storage_mem_pool_t osPoolStorage;
00091     uint32_t                     blockSize;
00092 }palMemoryPool_t;
00093 
00094 //! Message Queue structure
00095 typedef struct palMessageQ{
00096     palMessageQID_t               messageQID;
00097     osMessageQueueAttr_t          osMessageQ;
00098     mbed_rtos_storage_msg_queue_t osMessageQStorage;
00099 }palMessageQ_t;
00100 
00101 //! thread cleanup timer argument structure
00102 typedef struct palThreadCleanupData {
00103     palTimerID_t timerID;
00104     palThreadID_t threadToCleanUp;
00105     void* threadStackMem;
00106 }palThreadCleanupData_t;
00107 
00108 
00109 
00110 inline PAL_PRIVATE int mapThreadPriorityToPlatSpecific(palThreadPriority_t priority)
00111 {
00112     int adjustedPriority = -1;
00113 
00114     switch (priority)
00115     {
00116         case PAL_osPriorityIdle:
00117             adjustedPriority = osPriorityIdle;
00118             break;
00119 
00120         case PAL_osPriorityLow:
00121             adjustedPriority = osPriorityLow;
00122             break;
00123 
00124         case PAL_osPriorityBelowNormal:
00125             adjustedPriority = osPriorityBelowNormal;
00126             break;
00127 
00128         case PAL_osPriorityNormal:
00129             adjustedPriority = osPriorityNormal;
00130             break;
00131 
00132         case PAL_osPriorityAboveNormal:
00133             adjustedPriority = osPriorityAboveNormal;
00134             break;
00135 
00136         case PAL_osPriorityHigh:
00137             adjustedPriority = osPriorityHigh;
00138             break;
00139 
00140         case PAL_osPriorityRealtime:
00141             adjustedPriority = osPriorityRealtime;
00142             break;
00143 
00144         case PAL_osPriorityError:
00145             adjustedPriority = osPriorityError;
00146             break;
00147 
00148         default:
00149             adjustedPriority = osPriorityNone;
00150             break;
00151     }
00152 
00153     return adjustedPriority;
00154 }
00155 
00156 
00157 inline PAL_PRIVATE palThreadPriority_t mapThreadPriorityToPalGeneric(int priority)
00158 {
00159     palThreadPriority_t adjustedPriority = PAL_osPriorityError;
00160 
00161     switch (priority)
00162     {
00163         case osPriorityIdle:
00164             adjustedPriority = PAL_osPriorityIdle;
00165             break;
00166 
00167         case osPriorityLow :
00168             adjustedPriority = PAL_osPriorityLow;        
00169             break;
00170 
00171         case osPriorityBelowNormal :
00172             adjustedPriority = PAL_osPriorityBelowNormal;        
00173             break;
00174 
00175         case osPriorityNormal :
00176             adjustedPriority = PAL_osPriorityNormal;        
00177             break;
00178 
00179         case osPriorityAboveNormal :
00180             adjustedPriority = PAL_osPriorityAboveNormal;        
00181             break;
00182 
00183         case osPriorityHigh :
00184             adjustedPriority = PAL_osPriorityHigh;        
00185             break;
00186 
00187         case osPriorityRealtime :
00188             adjustedPriority = PAL_osPriorityRealtime;        
00189             break;
00190 
00191         case osPriorityError:
00192         default:
00193             adjustedPriority = PAL_osPriorityError;        
00194             break;
00195     }
00196 
00197     return adjustedPriority;
00198 }
00199 
00200 
00201 inline PAL_PRIVATE void setDefaultThreadValues(palThread_t* thread)
00202 {
00203 #if PAL_UNIQUE_THREAD_PRIORITY
00204     palThreadPriority_t threadGenericPriority = mapThreadPriorityToPalGeneric(thread->osThread.priority);      
00205     g_palThreadPriorities[threadGenericPriority+PRIORITY_INDEX_OFFSET] = 0;
00206 #endif //PAL_UNIQUE_THREAD_PRIORITY     
00207     thread->threadStore = NULL;
00208     thread->threadFuncWrapper.realThreadArgs = NULL;
00209     thread->threadFuncWrapper.realThreadFunc = NULL;
00210     thread->threadFuncWrapper.threadIndex = 0;
00211 
00212     thread->threadID = NULLPTR;
00213     thread->palThreadID = 0;
00214     //! This line should be last thing to be done in this function.
00215     //! in order to prevent double accessing the same index between
00216     //! this function and the threadCreate function.
00217     thread->initialized = false;
00218 }
00219 
00220 /*! Clean thread data from the global thread data base (g_palThreads). Thread Safe API
00221 *
00222 * @param[in] index: the index in the data base to be cleaned.
00223 */
00224 PAL_PRIVATE void threadCleanUp( uint32_t threadID)
00225 {
00226     uint32_t status = PAL_SUCCESS;
00227     uint32_t threadIndex = PAL_GET_THREAD_INDEX(threadID);
00228 
00229     status = pal_osMutexWait(g_palThreadInitMutex, PAL_RTOS_WAIT_FOREVER);
00230     if (PAL_SUCCESS != status)
00231     {
00232          PAL_LOG(ERR,"thread cleanup: mutex wait failed!\n");
00233     }
00234     else{
00235         if ((NULL != g_palThreads) && (threadIndex < PAL_MAX_NUMBER_OF_THREADS) && (g_palThreads[threadIndex].palThreadID == threadID))
00236         {
00237             setDefaultThreadValues(&g_palThreads[threadIndex]);
00238         }
00239 
00240         status = pal_osMutexRelease(g_palThreadInitMutex);
00241         if (PAL_SUCCESS != status)
00242         {
00243              PAL_LOG(ERR,"thread cleanup: mutex release failed!\n");
00244         }
00245     }
00246     return;
00247 }
00248 
00249 
00250 
00251 /*! Thread Cleanup timer. This is a timer funciton dedicated to deallocating the thread stack in case if it exits naturally (not via thread Terminate).
00252 *
00253 *   @param[in] arg: data structure which contains the data about the thread to clean up.
00254 */
00255 PAL_PRIVATE void threadCleanupTimer(const void* arg)
00256 {
00257     osThreadState_t threadState = osThreadError;
00258     palThreadCleanupData_t* threadCleanupData = (palThreadCleanupData_t*) arg;
00259     palTimerID_t localtimerID = threadCleanupData->timerID;
00260 
00261     threadState = osThreadGetState((osThreadId_t)(threadCleanupData->threadToCleanUp));
00262     if ((threadState == osThreadTerminated) || (threadState == osThreadInactive)) // thread has ended, can clean up.
00263     {
00264         free(threadCleanupData->threadStackMem); // free the thread stack memory.
00265         free(threadCleanupData); // free the thread cleanup data.
00266         pal_osTimerDelete(&localtimerID);
00267     }
00268     else // Thread not ended yet, wait another PAL_RTOS_THREAD_CLEANUP_TIMER_MILISEC ms.
00269     {
00270         if (osThreadError == threadState)
00271         {
00272             PAL_LOG(DBG,"thread Cleanup Timer: error getting thread status\n");
00273         }
00274         else
00275         {
00276             palStatus_t status = pal_osTimerStart(threadCleanupData->timerID, PAL_RTOS_THREAD_CLEANUP_TIMER_MILISEC);
00277             if (PAL_SUCCESS != status)
00278             {
00279                 PAL_LOG(ERR,"thread Cleanup Timer: timer start failed -  thread stack memory leak likely!\n");
00280             }
00281         }
00282     }  
00283 
00284 }
00285 
00286 
00287 
00288 /*! Thread wrapper function, this function will be set as the thread function (for every thread)
00289 *   and it will get as an argument the real data about the thread and call the REAL thread function
00290 *   with the REAL argument.
00291 *
00292 *   @param[in] arg: data structure which contains the real data about the thread.
00293 */
00294 PAL_PRIVATE void threadFunctionWrapper(void* arg)
00295 {
00296     palThreadFuncWrapper_t* threadWrapper = (palThreadFuncWrapper_t*)arg;
00297     palThreadCleanupData_t* threadCleanupData = NULL;
00298     palTimerID_t localTimerID = 0;
00299 
00300     if (NULL != threadWrapper)
00301     {
00302         if(g_palThreads[threadWrapper->threadIndex].threadID == NULLPTR)
00303         {
00304             g_palThreads[threadWrapper->threadIndex].threadID = (palThreadID_t)osThreadGetId();
00305         }
00306         threadWrapper->realThreadFunc(threadWrapper->realThreadArgs);
00307 
00308         threadCleanupData = (palThreadCleanupData_t*)malloc(sizeof(palThreadCleanupData_t));
00309         if (NULL == threadCleanupData)
00310         {
00311             PAL_LOG(ERR,"thread cleanup: timer data allocation failed -  thread stack memory leak likely!\n");
00312         }
00313         else
00314         {
00315             palStatus_t status = pal_osTimerCreate(threadCleanupTimer, threadCleanupData, palOsTimerOnce, &localTimerID);
00316             if (PAL_SUCCESS != status)
00317             {
00318                 PAL_LOG(ERR,"thread cleanup: timer create failed -  thread stack memory leak likely!\n");
00319             }
00320             else
00321             {
00322                 threadCleanupData->timerID = localTimerID;
00323                 threadCleanupData->threadToCleanUp = g_palThreads[threadWrapper->threadIndex].threadID;
00324                 threadCleanupData->threadStackMem = g_palThreads[threadWrapper->threadIndex].osThread.stack_mem;
00325                 status = pal_osTimerStart(localTimerID, PAL_RTOS_THREAD_CLEANUP_TIMER_MILISEC);
00326                 if (PAL_SUCCESS != status)
00327                 {
00328                     PAL_LOG(ERR,"thread cleanup: timer start failed -  thread stack memory leak likely!\n");
00329                 }
00330             }
00331         }
00332         
00333         threadCleanUp(g_palThreads[threadWrapper->threadIndex].palThreadID); // clean up everything except deallocating stack
00334     }
00335 }
00336 
00337 
00338 void pal_plat_osReboot ()
00339 {
00340     NVIC_SystemReset();
00341 }
00342 
00343 
00344 palStatus_t pal_plat_RTOSInitialize (void* opaqueContext)
00345 {
00346     //Clean thread tables
00347     palStatus_t status = PAL_SUCCESS;    
00348 
00349      memset(g_palThreads,0,sizeof(palThread_t) * PAL_MAX_NUMBER_OF_THREADS);
00350 
00351     //Add implicit the running task as PAL main
00352     g_palThreads[0].initialized = true;
00353     g_palThreads[0].threadID = (palThreadID_t)osThreadGetId();
00354     g_palThreads[0].osThread.stack_mem = NULL;
00355 
00356     pal_osAtomicIncrement((int32_t*)&g_threadCounter,1);
00357     //palThreadID = 24 bits for thread counter  + lower 8 bits for thread index (= 0).
00358     g_palThreads[0].palThreadID = (g_threadCounter << 8 );
00359 
00360     return status;
00361 }
00362 
00363 
00364 
00365 palStatus_t pal_plat_RTOSDestroy (void)
00366 {
00367     return PAL_SUCCESS;
00368 }
00369 
00370 
00371 palStatus_t pal_plat_osDelay (uint32_t milliseconds)
00372 {
00373     palStatus_t status;
00374     osStatus_t platStatus = osDelay(milliseconds);
00375     if (osOK == platStatus)
00376     {
00377         status = PAL_SUCCESS;
00378     }
00379     else
00380     {
00381         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); //TODO(nirson01): error propagation MACRO??
00382     }
00383     return status;
00384 }
00385 
00386 uint64_t pal_plat_osKernelSysTick (void)
00387 {
00388     uint64_t result;
00389     result = osKernelGetTickCount();
00390     return result;
00391 }
00392 
00393 uint64_t pal_plat_osKernelSysTickMicroSec (uint64_t microseconds)
00394 {
00395     uint64_t result;
00396     result =  (((uint64_t)microseconds * (osKernelGetTickFreq())) / 1000000);
00397 
00398     return result;
00399 }
00400 
00401 uint64_t pal_plat_osKernelSysTickFrequency ()
00402 {
00403     return osKernelGetTickFreq();
00404 }
00405 
00406 palStatus_t pal_plat_osThreadCreate (palThreadFuncPtr function, void* funcArgument, palThreadPriority_t priority, uint32_t stackSize, uint32_t* stackPtr, palThreadLocalStore_t* store, palThreadID_t* threadID)
00407 {
00408     palStatus_t status = PAL_SUCCESS;
00409     uint32_t firstAvailableThreadIndex = PAL_MAX_NUMBER_OF_THREADS;
00410     uint32_t i;
00411     uint32_t *stackAllocPtr = NULL;
00412     osThreadId_t osThreadID = NULL;
00413     uint32_t localPalThreadID = 0;
00414 
00415 
00416     if (NULL == threadID || NULL == function || 0 == stackSize || priority > PAL_osPriorityRealtime)
00417     {
00418         return PAL_ERR_INVALID_ARGUMENT ;
00419     }
00420 
00421     status = pal_osMutexWait(g_palThreadInitMutex, PAL_RTOS_WAIT_FOREVER);
00422     if (PAL_SUCCESS == status)
00423     {
00424         for (i = 0; i < PAL_MAX_NUMBER_OF_THREADS; ++i)
00425         {
00426             if (!g_palThreads[i].initialized)
00427             {
00428                 g_palThreads[i].initialized = true;
00429                 firstAvailableThreadIndex = i;
00430                 break;
00431             }
00432         }
00433 
00434         if (firstAvailableThreadIndex >= PAL_MAX_NUMBER_OF_THREADS)
00435         {
00436             status = PAL_ERR_RTOS_RESOURCE ;
00437         }
00438 
00439         if (PAL_SUCCESS == status)
00440         {
00441             stackAllocPtr =  (uint32_t*)malloc(stackSize);
00442             if(NULL == stackAllocPtr)
00443             {
00444                 status = PAL_ERR_RTOS_RESOURCE ;
00445             }
00446         }
00447 
00448         if (PAL_SUCCESS != status)
00449         {
00450             // release mutex if error.
00451             status = pal_osMutexRelease(g_palThreadInitMutex);
00452         }
00453         else
00454         {
00455             g_palThreads[firstAvailableThreadIndex].threadStore = store;
00456             g_palThreads[firstAvailableThreadIndex].threadFuncWrapper.realThreadArgs = funcArgument;
00457             g_palThreads[firstAvailableThreadIndex].threadFuncWrapper.realThreadFunc = function;
00458             g_palThreads[firstAvailableThreadIndex].threadFuncWrapper.threadIndex = firstAvailableThreadIndex;
00459             g_palThreads[firstAvailableThreadIndex].osThread.priority = (osPriority_t)mapThreadPriorityToPlatSpecific(priority);
00460             g_palThreads[firstAvailableThreadIndex].osThread.stack_size = stackSize;
00461             g_palThreads[firstAvailableThreadIndex].osThread.stack_mem = stackAllocPtr;
00462             g_palThreads[firstAvailableThreadIndex].osThread.cb_mem =  &(g_palThreads[firstAvailableThreadIndex].osThreadStorage);
00463             g_palThreads[firstAvailableThreadIndex].osThread.cb_size = sizeof(g_palThreads[firstAvailableThreadIndex].osThreadStorage);
00464             g_palThreads[firstAvailableThreadIndex].palThreadID = ((firstAvailableThreadIndex) + ((pal_osAtomicIncrement((int32_t*)&g_threadCounter, 1)) << 8)); //palThreadID = 24 bits for thread counter + lower 8 bits for thread index.
00465             memset(&(g_palThreads[firstAvailableThreadIndex].osThreadStorage), 0, sizeof(g_palThreads[firstAvailableThreadIndex].osThreadStorage));
00466 
00467             localPalThreadID = g_palThreads[firstAvailableThreadIndex].palThreadID; // save Thread ID value localy in case thread exists (and table is cleared) before funciton completes.
00468 
00469             // release mutex before thread creation .
00470             status = pal_osMutexRelease(g_palThreadInitMutex);
00471 
00472             if (PAL_SUCCESS == status)
00473             {
00474                 osThreadID = osThreadNew(threadFunctionWrapper, &g_palThreads[firstAvailableThreadIndex].threadFuncWrapper, &g_palThreads[firstAvailableThreadIndex].osThread);
00475                 g_palThreads[firstAvailableThreadIndex].threadID = (palThreadID_t)osThreadID;
00476                 if(NULL == osThreadID)
00477                 {
00478                     //! in case of error in the thread creation, reset the data of the given index in the threads array.
00479                     threadCleanUp(g_palThreads[firstAvailableThreadIndex].palThreadID);
00480 
00481                     if (NULL != g_palThreads[firstAvailableThreadIndex].osThread.stack_mem)
00482                     {
00483                         free(g_palThreads[firstAvailableThreadIndex].osThread.stack_mem);
00484                         g_palThreads[firstAvailableThreadIndex].osThread.stack_mem = NULL;
00485                     }
00486                     status = PAL_ERR_GENERIC_FAILURE;
00487                     *threadID = PAL_INVALID_THREAD;
00488                 }
00489                 else
00490                 {
00491                     *threadID = localPalThreadID; // here we use the thread may have already exited and cleared the table so local copy of ID is used.
00492                 }
00493             }
00494         }
00495     }
00496     return status;
00497 }
00498 
00499 palThreadID_t pal_plat_osThreadGetId (void)
00500 {
00501     int i = 0;
00502     palThreadID_t osThreadID;
00503     palThreadID_t ret = PAL_INVALID_THREAD;
00504     osThreadID = (palThreadID_t)osThreadGetId();
00505 
00506     for(i= 0; i < PAL_MAX_NUMBER_OF_THREADS; i++)
00507     {
00508         if(osThreadID == g_palThreads[i].threadID)
00509         {
00510             ret = i;
00511             break;
00512         }
00513     }
00514     return ret;
00515 }
00516 
00517 palStatus_t pal_plat_osThreadTerminate (palThreadID_t* threadID)
00518 {
00519     palStatus_t status = PAL_ERR_INVALID_ARGUMENT ;
00520     osStatus_t platStatus = osOK;
00521     osThreadState_t threadState = osThreadError;
00522     uint32_t threadIndex = PAL_GET_THREAD_INDEX(*threadID);
00523 
00524     if ((PAL_INVALID_THREAD == *threadID) || (threadIndex >= PAL_MAX_NUMBER_OF_THREADS))
00525     {
00526         return PAL_ERR_INVALID_ARGUMENT ;
00527     }
00528 
00529     // if thread exited or was terminated already return success.
00530     if ((g_palThreads[threadIndex].palThreadID == 0 ) ||  // thread already exited 
00531         (g_palThreads[threadIndex].palThreadID != *threadID)|| // thread already exited and a new thread was created at the same index.
00532         (g_palThreads[threadIndex].threadID == (palThreadID_t)PAL_INVALID_THREAD))  // thread was terminsated.
00533     {
00534         return PAL_SUCCESS;
00535     }
00536 
00537     if ((palThreadID_t)osThreadGetId() != g_palThreads[threadIndex].threadID)
00538     {//Kill only if not trying to kill from running task
00539         if (g_palThreads[threadIndex].initialized)
00540         {
00541             if (g_palThreads[threadIndex].threadID != NULLPTR)
00542             {
00543                 threadState = osThreadGetState((osThreadId_t)(g_palThreads[threadIndex].threadID));
00544                 if ((threadState != osThreadTerminated) && (threadState != osThreadError) && (threadState != osThreadInactive))
00545                 {
00546                     platStatus = osThreadTerminate((osThreadId_t)(g_palThreads[threadIndex].threadID));
00547                 }
00548             }
00549 
00550             if (platStatus != osErrorISR) // osErrorISR: osThreadTerminate cannot be called from interrupt service routines.
00551             {
00552                 threadCleanUp( *threadID);
00553                 if (NULL != g_palThreads[threadIndex].osThread.stack_mem)
00554                 {
00555                     free(g_palThreads[threadIndex].osThread.stack_mem);
00556                     g_palThreads[threadIndex].osThread.stack_mem = NULL;
00557                 }
00558                 *threadID = PAL_INVALID_THREAD;
00559                 status = PAL_SUCCESS;
00560             }
00561             else
00562             {
00563                 status = PAL_ERR_RTOS_ISR ;
00564             }
00565         }
00566         else
00567         {
00568             // thread already tminated and cleaned up
00569             status = PAL_SUCCESS;
00570         }
00571     }
00572     else
00573     {
00574         status = PAL_ERR_RTOS_TASK ;
00575     }
00576 
00577     return status;
00578 }
00579 
00580 palThreadLocalStore_t* pal_plat_osThreadGetLocalStore (void)
00581 {
00582     palThreadLocalStore_t* localStore = NULL;
00583     palThreadID_t id = (uintptr_t)pal_osThreadGetId();
00584 
00585     if( g_palThreads[id].initialized)
00586     {
00587         localStore = g_palThreads[id].threadStore;
00588     }
00589     return localStore;
00590 }
00591 
00592 
00593 palStatus_t pal_plat_osTimerCreate (palTimerFuncPtr function, void* funcArgument, palTimerType_t timerType, palTimerID_t* timerID)
00594 {
00595     palStatus_t status = PAL_SUCCESS;
00596     palTimer_t* timer = NULL;
00597 
00598     if(NULL == timerID || NULL == function)
00599     {
00600         return PAL_ERR_INVALID_ARGUMENT ;
00601     }
00602 
00603     timer = (palTimer_t*)malloc(sizeof(palTimer_t));
00604     if (NULL == timer)
00605     {
00606         status = PAL_ERR_NO_MEMORY ;
00607     }
00608 
00609     if (PAL_SUCCESS == status)
00610     {
00611         timer->osTimer.name = NULL;
00612         timer->osTimer.attr_bits = 0;
00613         timer->osTimer.cb_mem = &timer->osTimerStorage;
00614         timer->osTimer.cb_size = sizeof(timer->osTimerStorage);
00615         memset(&timer->osTimerStorage, 0, sizeof(timer->osTimerStorage));
00616     
00617         timer->timerID = (uintptr_t)osTimerNew((osTimerFunc_t)function, (osTimerType_t)timerType, funcArgument, &timer->osTimer);
00618         if (NULLPTR == timer->timerID)
00619         {
00620             free(timer);
00621             timer = NULL;
00622             status = PAL_ERR_GENERIC_FAILURE;
00623         }
00624         else
00625         {
00626             *timerID = (palTimerID_t)timer;
00627         }
00628     }
00629     return status;
00630 }
00631 
00632 palStatus_t pal_plat_osTimerStart (palTimerID_t timerID, uint32_t millisec)
00633 {
00634     palStatus_t status = PAL_SUCCESS;
00635     osStatus_t platStatus = osOK;
00636     palTimer_t* timer = NULL;
00637     
00638     if (NULLPTR == timerID)
00639     {
00640         return PAL_ERR_INVALID_ARGUMENT ;
00641     }
00642 
00643     timer = (palTimer_t*)timerID;
00644     platStatus = osTimerStart((osTimerId_t)timer->timerID, millisec);
00645     if (osOK == (osStatus_t)platStatus)
00646     {
00647         status = PAL_SUCCESS;
00648     }
00649     else
00650     {
00651         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00652     }
00653 
00654     return status;
00655 }
00656 
00657 palStatus_t pal_plat_osTimerStop (palTimerID_t timerID)
00658 {
00659     palStatus_t status = PAL_SUCCESS;
00660     osStatus_t platStatus = osOK;
00661     palTimer_t* timer = NULL;
00662     
00663     if(NULLPTR == timerID)
00664     {
00665         return PAL_ERR_INVALID_ARGUMENT ;
00666     }
00667 
00668     timer = (palTimer_t*)timerID;
00669     platStatus = osTimerStop((osTimerId_t)timer->timerID);
00670     if (osOK == platStatus)
00671     {
00672         status = PAL_SUCCESS;
00673     }
00674     else
00675     {
00676         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00677     }
00678 
00679     return status;  
00680 }
00681 
00682 palStatus_t pal_plat_osTimerDelete (palTimerID_t* timerID)
00683 {
00684     palStatus_t status = PAL_SUCCESS;
00685     osStatus_t platStatus = osOK;
00686     palTimer_t* timer = NULL;
00687     
00688     if(NULL == timerID || NULLPTR == *timerID)
00689     {
00690         return PAL_ERR_INVALID_ARGUMENT ;
00691     }
00692 
00693     timer = (palTimer_t*)*timerID;
00694     platStatus = osTimerDelete((osTimerId_t)timer->timerID);
00695     if (osOK == platStatus)
00696     {
00697         free(timer);
00698         *timerID = NULLPTR;
00699         status = PAL_SUCCESS;
00700     }
00701     else
00702     {
00703         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00704     }
00705 
00706     return status;
00707 }
00708 
00709 
00710 palStatus_t pal_plat_osMutexCreate (palMutexID_t* mutexID)
00711 {
00712     palStatus_t status = PAL_SUCCESS;
00713     palMutex_t* mutex = NULL;
00714 
00715     if(NULL == mutexID)
00716     {
00717         return PAL_ERR_INVALID_ARGUMENT ;
00718     }
00719 
00720     mutex = (palMutex_t*)malloc(sizeof(palMutex_t));
00721     if (NULL == mutex)
00722     {
00723         status = PAL_ERR_NO_MEMORY ;
00724     }
00725 
00726     if (PAL_SUCCESS == status)
00727     {
00728         mutex->osMutex.name = NULL;
00729         mutex->osMutex.attr_bits = osMutexRecursive | osMutexRobust;
00730         mutex->osMutex.cb_mem = &mutex->osMutexStorage;
00731         mutex->osMutex.cb_size = sizeof(mutex->osMutexStorage);
00732         memset(&mutex->osMutexStorage, 0, sizeof(mutex->osMutexStorage));
00733 
00734         mutex->mutexID = (uintptr_t)osMutexNew(&mutex->osMutex);
00735         if (NULLPTR == mutex->mutexID)
00736         {
00737             free(mutex);
00738             mutex = NULL;
00739             status = PAL_ERR_GENERIC_FAILURE;
00740         }
00741         else
00742         {
00743             *mutexID = (palMutexID_t)mutex;
00744         }
00745     }
00746     return status;
00747 }
00748 
00749 
00750 palStatus_t pal_plat_osMutexWait (palMutexID_t mutexID, uint32_t millisec)
00751 {
00752     palStatus_t status = PAL_SUCCESS;
00753     osStatus_t platStatus = osOK;
00754     palMutex_t* mutex = NULL;
00755     
00756     if(NULLPTR == mutexID)
00757     {
00758         return PAL_ERR_INVALID_ARGUMENT ;
00759     }
00760 
00761     mutex = (palMutex_t*)mutexID;
00762     platStatus = osMutexAcquire((osMutexId_t)mutex->mutexID, millisec);
00763     if (osOK == platStatus)
00764     {
00765         status = PAL_SUCCESS;
00766     }
00767     else
00768     {
00769         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00770     }
00771 
00772     return status;
00773 }
00774 
00775 
00776 palStatus_t pal_plat_osMutexRelease (palMutexID_t mutexID)
00777 {
00778     palStatus_t status = PAL_SUCCESS;
00779     osStatus_t platStatus = osOK;
00780     palMutex_t* mutex = NULL;
00781     
00782     if(NULLPTR == mutexID)
00783     {
00784         return PAL_ERR_INVALID_ARGUMENT ;
00785     }
00786 
00787     mutex = (palMutex_t*)mutexID;
00788     platStatus = osMutexRelease((osMutexId_t)mutex->mutexID);
00789     if (osOK == platStatus)
00790     {
00791         status = PAL_SUCCESS;
00792     }
00793     else
00794     {
00795         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00796     }
00797 
00798     return status;
00799 }
00800 
00801 palStatus_t pal_plat_osMutexDelete (palMutexID_t* mutexID)
00802 {
00803     palStatus_t status = PAL_SUCCESS;
00804     osStatus_t platStatus = osOK;
00805     palMutex_t* mutex = NULL;
00806     
00807     if(NULL == mutexID || NULLPTR == *mutexID)
00808     {
00809         return PAL_ERR_INVALID_ARGUMENT ;
00810     }
00811 
00812     mutex = (palMutex_t*)*mutexID;
00813     platStatus = osMutexDelete((osMutexId_t)mutex->mutexID);
00814     if (osOK == platStatus)
00815     {
00816         free(mutex);
00817         *mutexID = NULLPTR;
00818         status = PAL_SUCCESS;
00819     }
00820     else
00821     {
00822         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00823     }
00824 
00825     return status;
00826 }
00827 
00828 palStatus_t pal_plat_osSemaphoreCreate (uint32_t count, palSemaphoreID_t* semaphoreID)
00829 {
00830     palStatus_t status = PAL_SUCCESS;
00831     palSemaphore_t* semaphore = NULL;
00832     if(NULL == semaphoreID)
00833     {
00834         return PAL_ERR_INVALID_ARGUMENT ;
00835     }
00836 
00837     semaphore = (palSemaphore_t*)malloc(sizeof(palSemaphore_t));
00838     if (NULL == semaphore)
00839     {
00840         status = PAL_ERR_NO_MEMORY ;
00841     }
00842 
00843     if(PAL_SUCCESS == status)
00844     {
00845         semaphore->osSemaphore.cb_mem = &semaphore->osSemaphoreStorage;
00846         semaphore->osSemaphore.cb_size = sizeof(semaphore->osSemaphoreStorage);
00847         memset(&semaphore->osSemaphoreStorage, 0, sizeof(semaphore->osSemaphoreStorage));
00848 
00849         semaphore->semaphoreID = (uintptr_t)osSemaphoreNew(PAL_MAX_SEMAPHORE_COUNT, count, &semaphore->osSemaphore);
00850         if (NULLPTR == semaphore->semaphoreID)
00851         {
00852             free(semaphore);
00853             semaphore = NULL;
00854             status = PAL_ERR_GENERIC_FAILURE;
00855         }
00856         else
00857         {
00858             *semaphoreID = (palSemaphoreID_t)semaphore;
00859         }
00860     }
00861     return status;  
00862 }
00863 
00864 palStatus_t pal_plat_osSemaphoreWait (palSemaphoreID_t semaphoreID, uint32_t millisec, int32_t* countersAvailable)
00865 {
00866     palStatus_t status = PAL_SUCCESS;
00867     palSemaphore_t* semaphore = NULL;
00868     osStatus_t platStatus;
00869     if(NULLPTR == semaphoreID)
00870     {
00871         return PAL_ERR_INVALID_ARGUMENT ;
00872     }   
00873 
00874     semaphore = (palSemaphore_t*)semaphoreID;
00875     platStatus = osSemaphoreAcquire((osSemaphoreId_t)semaphore->semaphoreID, millisec);
00876 
00877     if (osErrorTimeout == platStatus)
00878     {
00879         status = PAL_ERR_RTOS_TIMEOUT ;
00880     }
00881     else if (platStatus != osOK)
00882     {
00883         status = PAL_ERR_RTOS_PARAMETER;
00884     }
00885 
00886     if (NULL != countersAvailable)
00887     {
00888         *countersAvailable = osSemaphoreGetCount((osSemaphoreId_t)semaphore->semaphoreID);
00889     }
00890     return status;
00891 }
00892 
00893 palStatus_t pal_plat_osSemaphoreRelease (palSemaphoreID_t semaphoreID)
00894 {
00895     palStatus_t status = PAL_SUCCESS;
00896     osStatus_t platStatus = osOK;
00897     palSemaphore_t* semaphore = NULL;
00898 
00899     if(NULLPTR == semaphoreID)
00900     {
00901         return PAL_ERR_INVALID_ARGUMENT ;
00902     }
00903 
00904     semaphore = (palSemaphore_t*)semaphoreID;
00905     platStatus = osSemaphoreRelease((osSemaphoreId_t)semaphore->semaphoreID);
00906     if (osOK == platStatus)
00907     {
00908         status = PAL_SUCCESS;
00909     }
00910     else
00911     {
00912         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00913     }
00914 
00915     return status;
00916 }
00917 
00918 palStatus_t pal_plat_osSemaphoreDelete (palSemaphoreID_t* semaphoreID)
00919 {
00920     palStatus_t status = PAL_SUCCESS;
00921     osStatus_t platStatus = osOK;
00922     palSemaphore_t* semaphore = NULL;
00923     
00924     if(NULL == semaphoreID || NULLPTR == *semaphoreID)
00925     {
00926         return PAL_ERR_INVALID_ARGUMENT ;
00927     }
00928 
00929     semaphore = (palSemaphore_t*)*semaphoreID;
00930     platStatus = osSemaphoreDelete((osSemaphoreId_t)semaphore->semaphoreID);
00931     if (osOK == platStatus)
00932     {
00933         free(semaphore);
00934         *semaphoreID = NULLPTR;
00935         status = PAL_SUCCESS;
00936     }
00937     else
00938     {
00939         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00940     }
00941 
00942     return status;  
00943 }
00944 
00945 palStatus_t pal_plat_osPoolCreate (uint32_t blockSize, uint32_t blockCount, palMemoryPoolID_t* memoryPoolID)
00946 {
00947     palStatus_t status = PAL_SUCCESS;
00948     palMemoryPool_t* memoryPool = NULL;
00949     if(NULL == memoryPoolID)
00950     {
00951         return PAL_ERR_INVALID_ARGUMENT ;
00952     }
00953 
00954     //! allocate the memory pool structure
00955     memoryPool = (palMemoryPool_t*)malloc(sizeof(palMemoryPool_t));
00956     if (NULL == memoryPool)
00957     {
00958         status = PAL_ERR_NO_MEMORY ;
00959     }
00960 
00961     if(PAL_SUCCESS == status)
00962     {
00963         memoryPool->blockSize = blockSize;
00964         memoryPool->osPool.name = NULL;
00965         memoryPool->osPool.attr_bits = 0;
00966         memoryPool->osPool.cb_mem = &memoryPool->osPoolStorage;
00967         memoryPool->osPool.cb_size = sizeof(memoryPool->osPoolStorage);
00968         memset(&memoryPool->osPoolStorage, 0, sizeof(memoryPool->osPoolStorage));
00969         memoryPool->osPool.mp_size = blockSize * blockCount;
00970         memoryPool->osPool.mp_mem = (uint32_t*)malloc(memoryPool->osPool.mp_size);
00971         if (NULL == memoryPool->osPool.mp_mem)
00972         {
00973             free(memoryPool);
00974             *memoryPoolID = NULLPTR;
00975             status = PAL_ERR_NO_MEMORY ;
00976         }
00977         else
00978         {
00979             memset(memoryPool->osPool.mp_mem, 0, memoryPool->osPool.mp_size);
00980 
00981             memoryPool->memoryPoolID = (uintptr_t)osMemoryPoolNew(blockCount, blockSize, &memoryPool->osPool);
00982             if (NULLPTR == memoryPool->memoryPoolID)
00983             {
00984                 free(memoryPool->osPool.mp_mem);
00985                 free(memoryPool);
00986                 memoryPool = NULL;
00987                 status = PAL_ERR_GENERIC_FAILURE;
00988             }
00989             else
00990             {
00991                 *memoryPoolID = (palMemoryPoolID_t)memoryPool;
00992             }
00993         }
00994     }
00995     return status;      
00996 }
00997 
00998 void* pal_plat_osPoolAlloc (palMemoryPoolID_t memoryPoolID)
00999 {
01000     void* result = NULL;
01001     palMemoryPool_t* memoryPool = NULL;
01002     
01003     if(NULLPTR == memoryPoolID)
01004     {
01005         return NULL;
01006     }
01007 
01008     memoryPool = (palMemoryPool_t*)memoryPoolID;
01009     result = osMemoryPoolAlloc((osMemoryPoolId_t)memoryPool->memoryPoolID, 0);
01010 
01011     return result;
01012 }
01013 
01014 void* pal_plat_osPoolCAlloc (palMemoryPoolID_t memoryPoolID)
01015 {
01016     void* result = NULL;
01017     palMemoryPool_t* memoryPool = NULL;
01018     
01019     if(NULLPTR == memoryPoolID)
01020     {
01021         return NULL;
01022     }
01023 
01024     memoryPool = (palMemoryPool_t*)memoryPoolID;
01025     result = osMemoryPoolAlloc((osMemoryPoolId_t)memoryPool->memoryPoolID, 0);
01026     if (NULLPTR != result)
01027     {
01028         memset(result, 0, memoryPool->blockSize);
01029     }
01030 
01031     return result;  
01032 }
01033 
01034 palStatus_t pal_plat_osPoolFree (palMemoryPoolID_t memoryPoolID, void* block)
01035 {
01036     palStatus_t status = PAL_SUCCESS;
01037     osStatus_t platStatus = osOK;
01038     palMemoryPool_t* memoryPool = NULL;
01039     
01040     if(NULLPTR == memoryPoolID || NULL == block)
01041     {
01042         return PAL_ERR_INVALID_ARGUMENT ;
01043     }
01044 
01045     memoryPool = (palMemoryPool_t*)memoryPoolID;
01046     platStatus = osMemoryPoolFree((osMemoryPoolId_t)memoryPool->memoryPoolID, block);
01047     if (osOK == platStatus)
01048     {
01049         status = PAL_SUCCESS;
01050     }
01051     else
01052     {
01053         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
01054     }
01055 
01056     return status;  
01057 }
01058 
01059 palStatus_t pal_plat_osPoolDestroy (palMemoryPoolID_t* memoryPoolID)
01060 {
01061     palStatus_t status = PAL_SUCCESS;
01062     palMemoryPool_t* memoryPool = NULL;
01063     
01064     if(NULL == memoryPoolID || NULLPTR == *memoryPoolID)
01065     {
01066         return PAL_ERR_INVALID_ARGUMENT ;
01067     }   
01068 
01069     memoryPool = (palMemoryPool_t*)*memoryPoolID;
01070     free(memoryPool->osPool.mp_mem);
01071     free(memoryPool);
01072     *memoryPoolID = NULLPTR;
01073     return status;
01074 }
01075 
01076 palStatus_t pal_plat_osMessageQueueCreate (uint32_t messageQCount, palMessageQID_t* messageQID)
01077 {
01078     palStatus_t status = PAL_SUCCESS;
01079     palMessageQ_t* messageQ = NULL;
01080     if(NULL == messageQID)
01081     {
01082         return PAL_ERR_INVALID_ARGUMENT ;
01083     }
01084 
01085     //! allocate the message queue structure
01086     messageQ = (palMessageQ_t*)malloc(sizeof(palMessageQ_t));
01087     if (NULL == messageQ)
01088     {
01089         status = PAL_ERR_NO_MEMORY ;
01090     }
01091 
01092     if (PAL_SUCCESS == status)
01093     {
01094         messageQ->osMessageQ.name = NULL;
01095         messageQ->osMessageQ.attr_bits = 0;
01096         messageQ->osMessageQ.cb_size = sizeof(messageQ->osMessageQStorage);
01097         messageQ->osMessageQ.cb_mem = &messageQ->osMessageQStorage;
01098         memset(&messageQ->osMessageQStorage, 0, sizeof(messageQ->osMessageQStorage));
01099         messageQ->osMessageQ.mq_size = (sizeof(uint32_t) + sizeof(mbed_rtos_storage_message_t)) * messageQCount ;
01100         messageQ->osMessageQ.mq_mem = (uint32_t*)malloc(messageQ->osMessageQ.mq_size);
01101         if (NULL == messageQ->osMessageQ.mq_mem)
01102         {
01103             free(messageQ);
01104             messageQ = NULL;
01105             status = PAL_ERR_NO_MEMORY ;
01106         }
01107         else
01108         {
01109             memset(messageQ->osMessageQ.mq_mem, 0, messageQ->osMessageQ.mq_size);
01110 
01111             messageQ->messageQID = (uintptr_t)osMessageQueueNew(messageQCount, sizeof(uint32_t), &messageQ->osMessageQ);
01112             if (NULLPTR == messageQ->messageQID)
01113             {
01114                 free(messageQ->osMessageQ.mq_mem);
01115                 free(messageQ);
01116                 messageQ = NULL;
01117                 status = PAL_ERR_GENERIC_FAILURE;
01118             }
01119             else
01120             {
01121                 *messageQID = (palMessageQID_t)messageQ;
01122             }
01123         }
01124     }
01125     return status;      
01126 }
01127 
01128 palStatus_t pal_plat_osMessagePut (palMessageQID_t messageQID, uint32_t info, uint32_t timeout)
01129 {
01130     palStatus_t status = PAL_SUCCESS;
01131     osStatus_t platStatus = osOK;
01132     palMessageQ_t* messageQ = NULL;
01133     
01134     if(NULLPTR == messageQID)
01135     {
01136         return PAL_ERR_INVALID_ARGUMENT ;
01137     }
01138 
01139     messageQ = (palMessageQ_t*)messageQID;
01140     platStatus = osMessageQueuePut((osMessageQueueId_t)messageQ->messageQID, (void *)&info, 0, timeout);
01141     if (osOK == platStatus)
01142     {
01143         status = PAL_SUCCESS;
01144     }
01145     else
01146     {
01147         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
01148     }
01149 
01150     return status;  
01151 }
01152 
01153 palStatus_t pal_plat_osMessageGet (palMessageQID_t messageQID, uint32_t timeout, uint32_t* messageValue)
01154 {
01155     palStatus_t status = PAL_SUCCESS;
01156     osStatus_t platStatus;
01157     palMessageQ_t* messageQ = NULL;
01158 
01159     if (NULLPTR == messageQID || NULLPTR == messageValue)
01160     {
01161         return PAL_ERR_INVALID_ARGUMENT ;
01162     }
01163 
01164     messageQ = (palMessageQ_t*)messageQID;
01165     platStatus = osMessageQueueGet((osMessageQueueId_t)messageQ->messageQID, messageValue, NULL, timeout);
01166     if (osOK == platStatus)
01167     {
01168         status = PAL_SUCCESS;
01169     }
01170     else if (osErrorTimeout == platStatus)
01171     {
01172         status = PAL_ERR_RTOS_TIMEOUT ;
01173     }
01174     else if (osOK != platStatus)
01175     {
01176         status = PAL_ERR_RTOS_PARAMETER;
01177     }
01178 
01179     return status;
01180 }
01181 
01182 
01183 palStatus_t pal_plat_osMessageQueueDestroy (palMessageQID_t* messageQID)
01184 {
01185     palStatus_t status = PAL_SUCCESS;
01186     palMessageQ_t* messageQ = NULL;
01187     
01188     if(NULL == messageQID || NULLPTR == *messageQID)
01189     {
01190         return PAL_ERR_INVALID_ARGUMENT ;
01191     }   
01192 
01193     messageQ = (palMessageQ_t*)*messageQID;
01194     free(messageQ->osMessageQ.mq_mem);
01195     free(messageQ);
01196     *messageQID = NULLPTR;
01197     return status;
01198 }
01199 
01200 
01201 int32_t pal_plat_osAtomicIncrement (int32_t* valuePtr, int32_t increment)
01202 {
01203     if (increment >= 0)
01204     {
01205         return core_util_atomic_incr_u32((uint32_t*)valuePtr, increment);
01206     }
01207     else
01208     {
01209         return core_util_atomic_decr_u32((uint32_t*)valuePtr, 0 - increment);
01210     }
01211 }
01212 
01213 
01214  void *pal_plat_malloc (size_t len)
01215 {
01216     return malloc(len);
01217 }
01218 
01219 
01220  void pal_plat_free (void * buffer)
01221 {
01222     return free(buffer);
01223 }
01224 
01225 palStatus_t pal_plat_osRandomBuffer (uint8_t *randomBuf, size_t bufSizeBytes)
01226 {
01227     palStatus_t status = PAL_SUCCESS;
01228     int32_t platStatus = 0;
01229     size_t actualOutputLen = 0;
01230     platStatus = mbedtls_hardware_poll(NULL /*Not used by the function*/, randomBuf, bufSizeBytes, &actualOutputLen);
01231     if ((0 != platStatus) || (actualOutputLen != bufSizeBytes))
01232     {
01233         status = PAL_ERR_RTOS_TRNG_FAILED ;
01234     }
01235     return status;
01236 }
01237 
01238 #endif