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_legacy.cpp Source File

pal_plat_rtos_legacy.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 legacy RTOS support
00034 ********************************************************************************/
00035 #if !(defined(osRtxVersionAPI) && (osRtxVersionAPI >= 20000000))
00036 
00037 #define PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(cmsisCode)\
00038     ((int32_t)((int32_t)cmsisCode + PAL_ERR_RTOS_ERROR_BASE))
00039 
00040 //! the size of the memory to allocate was taken from CMSIS header (cmsis_os.h)
00041 #define PAL_RTOS_MEMORY_POOL_SIZE(blockSize, blockCount)\
00042     (sizeof(uint32_t)*(3+((blockSize+3)/4)*(blockCount)))
00043 
00044 //! the size of the memory to allocate was taken from CMSIS header (cmsis_os.h)
00045 #define PAL_RTOS_MESSAGE_Q_SIZE(messageQSize)\
00046     (sizeof(uint32_t)*(4 + messageQSize))
00047 
00048 
00049 #ifdef PAL_RTOS_WAIT_FOREVER
00050 #undef PAL_RTOS_WAIT_FOREVER
00051 #define PAL_RTOS_WAIT_FOREVER osWaitForever
00052 #endif //PAL_RTOS_WAIT_FOREVER
00053 
00054 //! This definitions should be under #ifdef for different CORTEX-X processors.
00055 //! The current vaules are for cortex-M these are the sizes of the internal data array in definitions arrays
00056 #define PAL_TIMER_DATA_SIZE 6
00057 #define PAL_MUTEX_DATA_SIZE 4
00058 #define PAL_SEMAPHORE_DATA_SIZE 2
00059 #define PAL_NUM_OF_THREAD_INSTANCES 1
00060 
00061 PAL_PRIVATE uint8_t g_randomBuffer[PAL_INITIAL_RANDOM_SIZE] = {0};
00062 PAL_PRIVATE bool g_randInitiated = false;
00063 
00064 typedef struct palThreadFuncWrapper{
00065     palTimerFuncPtr         realThreadFunc;
00066     void*                   realThreadArgs;
00067     uint32_t                threadIndex;
00068 }palThreadFuncWrapper_t;
00069 
00070 //! Thread structure
00071 typedef struct palThread{
00072     palThreadID_t           threadID;
00073     bool                    initialized;
00074     palThreadLocalStore_t*  threadStore; //! please see pal_rtos.h for documentation
00075     palThreadFuncWrapper_t  threadFuncWrapper;
00076     osThreadDef_t           osThread;
00077     bool                    taskCompleted; //The task has completed and exit
00078 } palThread_t;
00079 
00080 
00081 palThread_t g_palThreads[PAL_MAX_NUMBER_OF_THREADS] = {0};
00082 
00083 //! Timer structure
00084 typedef struct palTimer{
00085     palTimerID_t            timerID;
00086     uint32_t                internalTimerData[PAL_TIMER_DATA_SIZE];  ///< pointer to internal data
00087     osTimerDef_t            osTimer;
00088 } palTimer_t;
00089 
00090 //! Mutex structure
00091 typedef struct palMutex{
00092     palMutexID_t            mutexID;
00093     uint32_t                internalMutexData[PAL_MUTEX_DATA_SIZE];
00094     osMutexDef_t            osMutex;
00095 }palMutex_t;
00096 
00097 //! Semaphore structure
00098 typedef struct palSemaphore{
00099     palSemaphoreID_t        semaphoreID;
00100     uint32_t                internalSemaphoreData[PAL_SEMAPHORE_DATA_SIZE];
00101     osSemaphoreDef_t        osSemaphore;
00102 }palSemaphore_t;
00103 
00104 
00105 //! Memoey Pool structure
00106 typedef struct palMemPool{
00107     palMemoryPoolID_t       memoryPoolID;
00108     osPoolDef_t             osPool;
00109 }palMemoryPool_t;
00110 
00111 //! Message Queue structure
00112 typedef struct palMessageQ{
00113     palMessageQID_t         messageQID;
00114     osMessageQDef_t         osMessageQ;
00115 }palMessageQ_t;
00116 
00117 
00118 inline PAL_PRIVATE void setDefaultThreadValues(palThread_t* thread)
00119 {
00120 #if PAL_UNIQUE_THREAD_PRIORITY      
00121     g_palThreadPriorities[thread->osThread.tpriority+PRIORITY_INDEX_OFFSET] = false;
00122 #endif //PAL_UNIQUE_THREAD_PRIORITY     
00123     thread->threadStore = NULL;
00124     thread->threadFuncWrapper.realThreadArgs = NULL;
00125     thread->threadFuncWrapper.realThreadFunc = NULL;
00126     thread->threadFuncWrapper.threadIndex = 0;
00127     thread->osThread.pthread = NULL;
00128     thread->osThread.tpriority = (osPriority)PAL_osPriorityError;
00129     thread->osThread.instances = PAL_NUM_OF_THREAD_INSTANCES;
00130     thread->osThread.stacksize = 0;
00131 #if __MBED_CMSIS_RTOS_CM
00132     if(thread->osThread.stack_pointer != NULL)
00133     {
00134         free(thread->osThread.stack_pointer);
00135     }
00136 #else
00137     thread->osThread.stack_pointer = NULL;
00138 #endif
00139     thread->threadID = NULLPTR;
00140     thread->taskCompleted = false;
00141     //! This line should be last thing to be done in this function.
00142     //! in order to prevent double accessing the same index between
00143     //! this function and the threadCreate function.
00144     thread->initialized = false;
00145 }
00146 
00147 /*! Clean thread data from the global thread data base (g_palThreads). Thread Safe API
00148 *
00149 * @param[in] dbPointer: data base pointer.
00150 * @param[in] index: the index in the data base to be cleaned.
00151 */
00152 PAL_PRIVATE void threadCleanUp(void* dbPointer, uint32_t index)
00153 {
00154     palThread_t* threadsDB = (palThread_t*)dbPointer;
00155 
00156     if (NULL == dbPointer || index >= PAL_MAX_NUMBER_OF_THREADS)
00157     {
00158         return;
00159     }
00160     setDefaultThreadValues(&threadsDB[index]);
00161 }
00162 
00163 /*! Thread wrapper function, this function will be set as the thread function (for every thread)
00164 *   and it will get as an argument the real data about the thread and call the REAL thread function
00165 *   with the REAL argument.
00166 *
00167 *   @param[in] arg: data structure which contains the real data about the thread.
00168 */
00169 PAL_PRIVATE void threadFunctionWrapper(void const* arg)
00170 {
00171     palThreadFuncWrapper_t* threadWrapper = (palThreadFuncWrapper_t*)arg;
00172 
00173     if (NULL != threadWrapper)
00174     {
00175         if(g_palThreads[threadWrapper->threadIndex].threadID == NULLPTR)
00176         {
00177             g_palThreads[threadWrapper->threadIndex].threadID = (palThreadID_t)osThreadGetId();
00178         }
00179         threadWrapper->realThreadFunc(threadWrapper->realThreadArgs);
00180         g_palThreads[threadWrapper->threadIndex].taskCompleted = true;
00181     }
00182 }
00183 
00184 
00185 void pal_plat_osReboot ()
00186 {
00187     NVIC_SystemReset();
00188 }
00189 
00190 
00191 palStatus_t pal_plat_RTOSInitialize (void* opaqueContext)
00192 {
00193     //Clean thread tables
00194     palStatus_t status = PAL_SUCCESS;
00195     int32_t platStatus = 0;
00196     size_t actualOutputLen = 0;
00197 
00198     memset(g_palThreads,0,sizeof(palThread_t) * PAL_MAX_NUMBER_OF_THREADS);
00199 
00200     //Add implicit the running task as PAL main
00201     g_palThreads[0].initialized = true;
00202     g_palThreads[0].threadID = (palThreadID_t)osThreadGetId();
00203     g_palThreads[0].osThread.stack_pointer = NULL;
00204 
00205 
00206     platStatus = mbedtls_hardware_poll(NULL /*Not used by the function*/, g_randomBuffer, sizeof(g_randomBuffer), &actualOutputLen);
00207     if (0 != platStatus || actualOutputLen != sizeof(g_randomBuffer))
00208     {
00209         status = PAL_ERR_RTOS_TRNG_FAILED ;
00210     }
00211     else
00212     {
00213         g_randInitiated = true;
00214     }
00215 
00216     return status;
00217 }
00218 
00219 
00220 
00221 
00222 
00223 palStatus_t pal_plat_RTOSDestroy (void)
00224 {
00225     return PAL_SUCCESS;
00226 }
00227 
00228 palStatus_t pal_plat_osDelay (uint32_t milliseconds)
00229 {
00230     palStatus_t status;
00231     osStatus platStatus = osDelay(milliseconds);
00232     if (osEventTimeout == platStatus)
00233     {
00234         status = PAL_SUCCESS;
00235     }
00236     else
00237     {
00238         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus); //TODO(nirson01): error propagation MACRO??
00239     }
00240     return status;
00241 }
00242 
00243 uint64_t pal_plat_osKernelSysTick (void)
00244 {
00245     uint64_t result;
00246     result = osKernelSysTick();
00247     return result;
00248 }
00249 
00250 uint64_t pal_plat_osKernelSysTickMicroSec (uint64_t microseconds)
00251 {
00252     uint64_t result;
00253     result = osKernelSysTickMicroSec(microseconds);
00254     return result;
00255 }
00256 
00257 uint64_t pal_plat_osKernelSysTickFrequency ()
00258 {
00259     return osKernelSysTickFrequency;
00260 }
00261 
00262 palStatus_t pal_plat_osThreadCreate (palThreadFuncPtr function, void* funcArgument, palThreadPriority_t priority, uint32_t stackSize, uint32_t* stackPtr, palThreadLocalStore_t* store, palThreadID_t* threadID)
00263 {
00264     palStatus_t status = PAL_SUCCESS;
00265     uint32_t firstAvailableThreadIndex = PAL_MAX_NUMBER_OF_THREADS;
00266     uint32_t i;
00267     uint32_t *stackAllocPtr = NULL;
00268     osThreadId osThreadID = NULL;
00269 
00270     if (NULL == threadID || NULL == function || 0 == stackSize || priority > PAL_osPriorityRealtime)
00271     {
00272         return PAL_ERR_INVALID_ARGUMENT ;
00273     }
00274 
00275     for (i = 0; i < PAL_MAX_NUMBER_OF_THREADS; ++i)
00276     {
00277         if (!g_palThreads[i].initialized)
00278         {
00279             g_palThreads[i].initialized = true;
00280             firstAvailableThreadIndex = i;
00281             break;
00282         }
00283     }
00284 
00285     if (firstAvailableThreadIndex >= PAL_MAX_NUMBER_OF_THREADS)
00286     {
00287         status = PAL_ERR_RTOS_RESOURCE ;
00288     }
00289 
00290 #if __MBED_CMSIS_RTOS_CM
00291     if (PAL_SUCCESS == status)
00292     {
00293         stackAllocPtr =  (uint32_t*)malloc(stackSize);
00294 
00295         if(NULL == stackAllocPtr)
00296         {
00297             status = PAL_ERR_RTOS_RESOURCE ;
00298         }
00299     }
00300 #endif
00301     if (PAL_SUCCESS == status)
00302     {
00303         g_palThreads[firstAvailableThreadIndex].threadStore = store;
00304         g_palThreads[firstAvailableThreadIndex].threadFuncWrapper.realThreadArgs = funcArgument;
00305         g_palThreads[firstAvailableThreadIndex].threadFuncWrapper.realThreadFunc = function;
00306         g_palThreads[firstAvailableThreadIndex].threadFuncWrapper.threadIndex = firstAvailableThreadIndex;
00307         g_palThreads[firstAvailableThreadIndex].osThread.pthread = threadFunctionWrapper;
00308         g_palThreads[firstAvailableThreadIndex].osThread.tpriority = (osPriority)priority;
00309         g_palThreads[firstAvailableThreadIndex].osThread.instances = PAL_NUM_OF_THREAD_INSTANCES;
00310         g_palThreads[firstAvailableThreadIndex].osThread.stacksize = stackSize;
00311 #if __MBED_CMSIS_RTOS_CM
00312             g_palThreads[firstAvailableThreadIndex].osThread.stack_pointer = stackAllocPtr;
00313 #else
00314             g_palThreads[firstAvailableThreadIndex].osThread.stack_pointer = stackPtr;
00315 #endif
00316 
00317 #if PAL_UNIQUE_THREAD_PRIORITY      
00318         g_palThreadPriorities[priority+PRIORITY_INDEX_OFFSET] = true;
00319 #endif //PAL_UNIQUE_THREAD_PRIORITY     
00320 
00321     
00322         osThreadID = osThreadCreate(&g_palThreads[firstAvailableThreadIndex].osThread, &g_palThreads[firstAvailableThreadIndex].threadFuncWrapper);
00323         
00324         if(NULL == osThreadID)
00325         {
00326             //! in case of error in the thread creation, reset the data of the given index in the threads array.
00327             threadCleanUp(g_palThreads, firstAvailableThreadIndex);
00328             status = PAL_ERR_GENERIC_FAILURE;
00329             *threadID = PAL_INVALID_THREAD;
00330         }
00331         else
00332         {
00333             *threadID = firstAvailableThreadIndex;
00334         }
00335 
00336     }
00337     return status;
00338 }
00339 
00340 palThreadID_t pal_plat_osThreadGetId (void)
00341 {
00342     int i = 0;
00343     palThreadID_t osThreadID;
00344     palThreadID_t ret = PAL_INVALID_THREAD;
00345     osThreadID = (palThreadID_t)osThreadGetId();
00346 
00347     for(i= 0; i < PAL_MAX_NUMBER_OF_THREADS; i++)
00348     {
00349         if(osThreadID == g_palThreads[i].threadID)
00350         {
00351             ret = i;
00352             break;
00353         }
00354     }
00355     return ret;
00356 }
00357 
00358 palStatus_t pal_plat_osThreadTerminate (palThreadID_t* threadID)
00359 {
00360     palStatus_t status = PAL_ERR_INVALID_ARGUMENT ;
00361     osStatus platStatus = osOK;
00362 
00363     if (*threadID >= PAL_MAX_NUMBER_OF_THREADS)
00364     {
00365         return status;
00366     }
00367 
00368     if ((palThreadID_t)osThreadGetId() != g_palThreads[*threadID].threadID)
00369     {//Kill only if not trying to kill from running task
00370         if (g_palThreads[*threadID].initialized)
00371         {
00372             if ((g_palThreads[*threadID].threadID != NULL) && ( g_palThreads[*threadID].taskCompleted == false))
00373             {
00374                 platStatus = osThreadTerminate((osThreadId)(g_palThreads[*threadID].threadID));
00375             }
00376             if (platStatus != osErrorISR) // osErrorISR: osThreadTerminate cannot be called from interrupt service routines.
00377             {
00378                 threadCleanUp(g_palThreads, *threadID);
00379             }
00380             else 
00381             {
00382                 status = PAL_ERR_RTOS_ISR ;
00383             }
00384         }
00385         *threadID = PAL_INVALID_THREAD;
00386         status = PAL_SUCCESS;
00387     }
00388     else
00389     {
00390         status = PAL_ERR_RTOS_TASK ;
00391     }
00392 
00393     return status;
00394 }
00395 
00396 palThreadLocalStore_t* pal_plat_osThreadGetLocalStore (void)
00397 {
00398     palThreadLocalStore_t* localStore = NULL;
00399     palThreadID_t id = (uintptr_t)pal_osThreadGetId();
00400 
00401     if( g_palThreads[id].initialized)
00402     {
00403         localStore = g_palThreads[id].threadStore;
00404     }
00405     return localStore;
00406 }
00407 
00408 
00409 palStatus_t pal_plat_osTimerCreate (palTimerFuncPtr function, void* funcArgument, palTimerType_t timerType, palTimerID_t* timerID)
00410 {
00411     palStatus_t status = PAL_SUCCESS;
00412     palTimer_t* timer = NULL;
00413 
00414     if(NULL == timerID || NULL == function)
00415     {
00416         return PAL_ERR_INVALID_ARGUMENT ;
00417     }
00418 
00419     timer = (palTimer_t*)malloc(sizeof(palTimer_t));
00420     if (NULL == timer)
00421     {
00422         status = PAL_ERR_NO_MEMORY ;
00423     }
00424 
00425     if (PAL_SUCCESS == status)
00426     {
00427         timer->osTimer.ptimer = function;
00428         timer->osTimer.timer = timer->internalTimerData;
00429         memset(timer->osTimer.timer, 0, sizeof(uint32_t)*PAL_TIMER_DATA_SIZE);
00430     
00431         timer->timerID = (uintptr_t)osTimerCreate(&timer->osTimer, (os_timer_type)timerType, funcArgument);
00432         if (NULLPTR == timer->timerID)
00433         {
00434             free(timer);
00435             timer = NULL;
00436             status = PAL_ERR_GENERIC_FAILURE;
00437         }
00438         else
00439         {
00440             *timerID = (palTimerID_t)timer;
00441         }
00442     }
00443     return status;
00444 }
00445 
00446 palStatus_t pal_plat_osTimerStart (palTimerID_t timerID, uint32_t millisec)
00447 {
00448     palStatus_t status = PAL_SUCCESS;
00449     osStatus platStatus = osOK;
00450     palTimer_t* timer = NULL;
00451     
00452     if (NULLPTR == timerID)
00453     {
00454         return PAL_ERR_INVALID_ARGUMENT ;
00455     }
00456 
00457     timer = (palTimer_t*)timerID;
00458     platStatus = osTimerStart((osTimerId)timer->timerID, millisec);
00459     if (osOK == (osStatus)platStatus)
00460     {
00461         status = PAL_SUCCESS;
00462     }
00463     else
00464     {
00465         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00466     }
00467 
00468     return status;
00469 }
00470 
00471 palStatus_t pal_plat_osTimerStop (palTimerID_t timerID)
00472 {
00473     palStatus_t status = PAL_SUCCESS;
00474     osStatus platStatus = osOK;
00475     palTimer_t* timer = NULL;
00476     
00477     if(NULLPTR == timerID)
00478     {
00479         return PAL_ERR_INVALID_ARGUMENT ;
00480     }
00481 
00482     timer = (palTimer_t*)timerID;
00483     platStatus = osTimerStop((osTimerId)timer->timerID);
00484     if (osOK == platStatus)
00485     {
00486         status = PAL_SUCCESS;
00487     }
00488     else
00489     {
00490         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00491     }
00492 
00493     return status;  
00494 }
00495 
00496 palStatus_t pal_plat_osTimerDelete (palTimerID_t* timerID)
00497 {
00498     palStatus_t status = PAL_SUCCESS;
00499     osStatus platStatus = osOK;
00500     palTimer_t* timer = NULL;
00501     
00502     if(NULL == timerID || NULLPTR == *timerID)
00503     {
00504         return PAL_ERR_INVALID_ARGUMENT ;
00505     }
00506 
00507     timer = (palTimer_t*)*timerID;
00508     platStatus = osTimerDelete((osTimerId)timer->timerID);
00509     if (osOK == platStatus)
00510     {
00511         free(timer);
00512         *timerID = NULLPTR;
00513         status = PAL_SUCCESS;
00514     }
00515     else
00516     {
00517         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00518     }
00519 
00520     return status;
00521 }
00522 
00523 
00524 palStatus_t pal_plat_osMutexCreate (palMutexID_t* mutexID)
00525 {
00526     palStatus_t status = PAL_SUCCESS;
00527     palMutex_t* mutex = NULL;
00528     if(NULL == mutexID)
00529     {
00530         return PAL_ERR_INVALID_ARGUMENT ;
00531     }
00532 
00533     mutex = (palMutex_t*)malloc(sizeof(palMutex_t));
00534     if (NULL == mutex)
00535     {
00536         status = PAL_ERR_NO_MEMORY ;
00537     }
00538 
00539     if (PAL_SUCCESS == status)
00540     {
00541         mutex->osMutex.mutex = mutex->internalMutexData;
00542         memset(mutex->osMutex.mutex, 0, sizeof(uint32_t)*PAL_MUTEX_DATA_SIZE);
00543     
00544         mutex->mutexID = (uintptr_t)osMutexCreate(&mutex->osMutex);
00545         if (NULLPTR == mutex->mutexID)
00546         {
00547             free(mutex);
00548             mutex = NULL;
00549             status = PAL_ERR_GENERIC_FAILURE;
00550         }
00551         else
00552         {
00553             *mutexID = (palMutexID_t)mutex;
00554         }
00555     }
00556     return status;
00557 }
00558 
00559 
00560 palStatus_t pal_plat_osMutexWait (palMutexID_t mutexID, uint32_t millisec)
00561 {
00562     palStatus_t status = PAL_SUCCESS;
00563     osStatus platStatus = osOK;
00564     palMutex_t* mutex = NULL;
00565     
00566     if(NULLPTR == mutexID)
00567     {
00568         return PAL_ERR_INVALID_ARGUMENT ;
00569     }
00570 
00571     mutex = (palMutex_t*)mutexID;
00572     platStatus = osMutexWait((osMutexId)mutex->mutexID, millisec);
00573     if (osOK == platStatus)
00574     {
00575         status = PAL_SUCCESS;
00576     }
00577     else
00578     {
00579         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00580     }
00581 
00582     return status;
00583 }
00584 
00585 
00586 palStatus_t pal_plat_osMutexRelease (palMutexID_t mutexID)
00587 {
00588     palStatus_t status = PAL_SUCCESS;
00589     osStatus platStatus = osOK;
00590     palMutex_t* mutex = NULL;
00591     
00592     if(NULLPTR == mutexID)
00593     {
00594         return PAL_ERR_INVALID_ARGUMENT ;
00595     }
00596 
00597     mutex = (palMutex_t*)mutexID;
00598     platStatus = osMutexRelease((osMutexId)mutex->mutexID);
00599     if (osOK == platStatus)
00600     {
00601         status = PAL_SUCCESS;
00602     }
00603     else
00604     {
00605         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00606     }
00607 
00608     return status;
00609 }
00610 
00611 palStatus_t pal_plat_osMutexDelete (palMutexID_t* mutexID)
00612 {
00613     palStatus_t status = PAL_SUCCESS;
00614     osStatus platStatus = osOK;
00615     palMutex_t* mutex = NULL;
00616     
00617     if(NULL == mutexID || NULLPTR == *mutexID)
00618     {
00619         return PAL_ERR_INVALID_ARGUMENT ;
00620     }
00621 
00622     mutex = (palMutex_t*)*mutexID;
00623     platStatus = osMutexDelete((osMutexId)mutex->mutexID);
00624     if (osOK == platStatus)
00625     {
00626         free(mutex);
00627         *mutexID = NULLPTR;
00628         status = PAL_SUCCESS;
00629     }
00630     else
00631     {
00632         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00633     }
00634 
00635     return status;
00636 }
00637 
00638 palStatus_t pal_plat_osSemaphoreCreate (uint32_t count, palSemaphoreID_t* semaphoreID)
00639 {
00640     palStatus_t status = PAL_SUCCESS;
00641     palSemaphore_t* semaphore = NULL;
00642     if(NULL == semaphoreID)
00643     {
00644         return PAL_ERR_INVALID_ARGUMENT ;
00645     }
00646 
00647     semaphore = (palSemaphore_t*)malloc(sizeof(palSemaphore_t));
00648     if (NULL == semaphore)
00649     {
00650         status = PAL_ERR_NO_MEMORY ;
00651     }
00652 
00653     if(PAL_SUCCESS == status)
00654     {
00655         semaphore->osSemaphore.semaphore = semaphore->internalSemaphoreData;
00656         memset(semaphore->osSemaphore.semaphore, 0, sizeof(uint32_t)*PAL_SEMAPHORE_DATA_SIZE);
00657     
00658         semaphore->semaphoreID = (uintptr_t)osSemaphoreCreate(&semaphore->osSemaphore, count);
00659         if (NULLPTR == semaphore->semaphoreID)
00660         {
00661             free(semaphore);
00662             semaphore = NULL;
00663             status = PAL_ERR_GENERIC_FAILURE;
00664         }
00665         else
00666         {
00667             *semaphoreID = (palSemaphoreID_t)semaphore;
00668         }
00669     }
00670     return status;  
00671 }
00672 
00673 palStatus_t pal_plat_osSemaphoreWait (palSemaphoreID_t semaphoreID, uint32_t millisec, int32_t* countersAvailable)
00674 {
00675     palStatus_t status = PAL_SUCCESS;
00676     palSemaphore_t* semaphore = NULL;
00677     int32_t tmpCountersAvailable = 0;
00678     if(NULLPTR == semaphoreID)
00679     {
00680         return PAL_ERR_INVALID_ARGUMENT ;
00681     }   
00682 
00683     semaphore = (palSemaphore_t*)semaphoreID;
00684     tmpCountersAvailable = osSemaphoreWait((osSemaphoreId)semaphore->semaphoreID, millisec);
00685 
00686     if (0 == tmpCountersAvailable)
00687     {
00688         status = PAL_ERR_RTOS_TIMEOUT ;
00689     }
00690     else if (tmpCountersAvailable < 0)
00691     {
00692         tmpCountersAvailable = 0;
00693         status = PAL_ERR_RTOS_PARAMETER;
00694     }
00695 
00696     if (NULL != countersAvailable)
00697     {
00698     //osSemaphoreWait return the number of available counter + "1" 
00699     //The "1" is added because return value "0" is timeout so mbedOS return 1 and this is false
00700         tmpCountersAvailable--;    
00701         *countersAvailable = tmpCountersAvailable;
00702     }
00703     return status;
00704 }
00705 
00706 palStatus_t pal_plat_osSemaphoreRelease (palSemaphoreID_t semaphoreID)
00707 {
00708     palStatus_t status = PAL_SUCCESS;
00709     osStatus platStatus = osOK;
00710     palSemaphore_t* semaphore = NULL;
00711     
00712     if(NULLPTR == semaphoreID)
00713     {
00714         return PAL_ERR_INVALID_ARGUMENT ;
00715     }
00716 
00717     semaphore = (palSemaphore_t*)semaphoreID;
00718     platStatus = osSemaphoreRelease((osSemaphoreId)semaphore->semaphoreID);
00719     if (osOK == platStatus)
00720     {
00721         status = PAL_SUCCESS;
00722     }
00723     else
00724     {
00725         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00726     }
00727 
00728     return status;
00729 }
00730 
00731 palStatus_t pal_plat_osSemaphoreDelete (palSemaphoreID_t* semaphoreID)
00732 {
00733     palStatus_t status = PAL_SUCCESS;
00734     osStatus platStatus = osOK;
00735     palSemaphore_t* semaphore = NULL;
00736     
00737     if(NULL == semaphoreID || NULLPTR == *semaphoreID)
00738     {
00739         return PAL_ERR_INVALID_ARGUMENT ;
00740     }
00741 
00742     semaphore = (palSemaphore_t*)*semaphoreID;
00743     platStatus = osSemaphoreDelete((osSemaphoreId)semaphore->semaphoreID);
00744     if (osOK == platStatus)
00745     {
00746         free(semaphore);
00747         *semaphoreID = NULLPTR;
00748         status = PAL_SUCCESS;
00749     }
00750     else
00751     {
00752         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00753     }
00754 
00755     return status;  
00756 }
00757 
00758 palStatus_t pal_plat_osPoolCreate (uint32_t blockSize, uint32_t blockCount, palMemoryPoolID_t* memoryPoolID)
00759 {
00760     palStatus_t status = PAL_SUCCESS;
00761     palMemoryPool_t* memoryPool = NULL;
00762     if(NULL == memoryPoolID)
00763     {
00764         return PAL_ERR_INVALID_ARGUMENT ;
00765     }
00766 
00767     //! allocate the memory pool structure
00768     memoryPool = (palMemoryPool_t*)malloc(sizeof(palMemoryPool_t));
00769     if (NULL == memoryPool)
00770     {
00771         status = PAL_ERR_NO_MEMORY ;
00772     }
00773 
00774     if(PAL_SUCCESS == status)
00775     {
00776         //! allocate the actual memory allocation for the memory pool blocks, the size of the memory 
00777         //! to allocate was taken from CMSIS header (cmsis_os.h)
00778         memoryPool->osPool.pool = (uint32_t*)malloc(PAL_RTOS_MEMORY_POOL_SIZE(blockSize, blockCount));
00779         if (NULL == memoryPool->osPool.pool)
00780         {
00781             free(memoryPool);
00782             *memoryPoolID = NULLPTR;
00783             status = PAL_ERR_NO_MEMORY ;
00784         }
00785         else
00786         {
00787             memset(memoryPool->osPool.pool, 0, PAL_RTOS_MEMORY_POOL_SIZE(blockSize, blockCount));
00788             memoryPool->osPool.pool_sz = blockCount;    ///< number of items (elements) in the pool
00789             memoryPool->osPool.item_sz = blockSize;     ///< size of an item
00790         
00791             memoryPool->memoryPoolID = (uintptr_t)osPoolCreate(&memoryPool->osPool);
00792             if (NULLPTR == memoryPool->memoryPoolID)
00793             {
00794                 free(memoryPool->osPool.pool);
00795                 free(memoryPool);
00796                 memoryPool = NULL;
00797                 status = PAL_ERR_GENERIC_FAILURE;
00798             }
00799             else
00800             {
00801                 *memoryPoolID = (palMemoryPoolID_t)memoryPool;
00802             }
00803         }
00804     }
00805     return status;      
00806 }
00807 
00808 void* pal_plat_osPoolAlloc (palMemoryPoolID_t memoryPoolID)
00809 {
00810     void* result = NULL;
00811     palMemoryPool_t* memoryPool = NULL;
00812     
00813     if(NULLPTR == memoryPoolID)
00814     {
00815         return NULL;
00816     }
00817 
00818     memoryPool = (palMemoryPool_t*)memoryPoolID;
00819     result = osPoolAlloc((osPoolId)memoryPool->memoryPoolID);
00820 
00821     return result;
00822 }
00823 
00824 void* pal_plat_osPoolCAlloc (palMemoryPoolID_t memoryPoolID)
00825 {
00826     void* result = NULL;
00827     palMemoryPool_t* memoryPool = NULL;
00828     
00829     if(NULLPTR == memoryPoolID)
00830     {
00831         return NULL;
00832     }
00833 
00834     memoryPool = (palMemoryPool_t*)memoryPoolID;
00835     result = osPoolCAlloc((osPoolId)memoryPool->memoryPoolID);
00836 
00837     return result;  
00838 }
00839 
00840 palStatus_t pal_plat_osPoolFree (palMemoryPoolID_t memoryPoolID, void* block)
00841 {
00842     palStatus_t status = PAL_SUCCESS;
00843     osStatus platStatus = osOK;
00844     palMemoryPool_t* memoryPool = NULL;
00845     
00846     if(NULLPTR == memoryPoolID || NULL == block)
00847     {
00848         return PAL_ERR_INVALID_ARGUMENT ;
00849     }
00850 
00851     memoryPool = (palMemoryPool_t*)memoryPoolID;
00852     platStatus = osPoolFree((osPoolId)memoryPool->memoryPoolID, block);
00853     if (osOK == platStatus)
00854     {
00855         status = PAL_SUCCESS;
00856     }
00857     else
00858     {
00859         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00860     }
00861 
00862     return status;  
00863 }
00864 
00865 palStatus_t pal_plat_osPoolDestroy (palMemoryPoolID_t* memoryPoolID)
00866 {
00867     palStatus_t status = PAL_SUCCESS;
00868     palMemoryPool_t* memoryPool = NULL;
00869     
00870     if(NULL == memoryPoolID || NULLPTR == *memoryPoolID)
00871     {
00872         return PAL_ERR_INVALID_ARGUMENT ;
00873     }   
00874 
00875     memoryPool = (palMemoryPool_t*)*memoryPoolID;
00876     free(memoryPool->osPool.pool);
00877     free(memoryPool);
00878     *memoryPoolID = NULLPTR;
00879     return status;
00880 }
00881 
00882 palStatus_t pal_plat_osMessageQueueCreate (uint32_t messageQCount, palMessageQID_t* messageQID)
00883 {
00884     palStatus_t status = PAL_SUCCESS;
00885     palMessageQ_t* messageQ = NULL;
00886     if(NULL == messageQID)
00887     {
00888         return PAL_ERR_INVALID_ARGUMENT ;
00889     }
00890 
00891     //! allocate the message queue structure
00892     messageQ = (palMessageQ_t*)malloc(sizeof(palMessageQ_t));
00893     if (NULL == messageQ)
00894     {
00895         status = PAL_ERR_NO_MEMORY ;
00896     }
00897 
00898     if (PAL_SUCCESS == status)
00899     {
00900         //! allocate the actual memory allocation for the message queue blocks, the size of the memory 
00901         //! to allocate was taken from CMSIS header (cmsis_os.h)
00902         messageQ->osMessageQ.pool = (uint32_t*)malloc(PAL_RTOS_MESSAGE_Q_SIZE(messageQCount));
00903         if (NULL == messageQ->osMessageQ.pool)
00904         {
00905             free(messageQ);
00906             messageQ = NULL;
00907             status = PAL_ERR_NO_MEMORY ;
00908         }
00909         else
00910         {
00911             memset(messageQ->osMessageQ.pool, 0, PAL_RTOS_MESSAGE_Q_SIZE(messageQCount));
00912             messageQ->osMessageQ.queue_sz = messageQCount;   ///< number of items (elements) in the queue
00913         
00914             messageQ->messageQID = (uintptr_t)osMessageCreate(&(messageQ->osMessageQ), NULL);
00915             if (NULLPTR == messageQ->messageQID)
00916             {
00917                 free(messageQ->osMessageQ.pool);
00918                 free(messageQ);
00919                 messageQ = NULL;
00920                 status = PAL_ERR_GENERIC_FAILURE;
00921             }
00922             else
00923             {
00924                 *messageQID = (palMessageQID_t)messageQ;
00925             }
00926         }
00927     }
00928     return status;      
00929 }
00930 
00931 palStatus_t pal_plat_osMessagePut (palMessageQID_t messageQID, uint32_t info, uint32_t timeout)
00932 {
00933     palStatus_t status = PAL_SUCCESS;
00934     osStatus platStatus = osOK;
00935     palMessageQ_t* messageQ = NULL;
00936     
00937     if(NULLPTR == messageQID)
00938     {
00939         return PAL_ERR_INVALID_ARGUMENT ;
00940     }
00941 
00942     messageQ = (palMessageQ_t*)messageQID;
00943     platStatus = osMessagePut((osMessageQId)messageQ->messageQID, info, timeout);
00944     if (osOK == platStatus)
00945     {
00946         status = PAL_SUCCESS;
00947     }
00948     else
00949     {
00950         status = PAL_RTOS_TRANSLATE_CMSIS_ERROR_CODE(platStatus);
00951     }
00952 
00953     return status;  
00954 }
00955 
00956 palStatus_t pal_plat_osMessageGet (palMessageQID_t messageQID, uint32_t timeout, uint32_t* messageValue)
00957 {
00958     palStatus_t status = PAL_SUCCESS;
00959     osEvent event;
00960     palMessageQ_t* messageQ = NULL;
00961 
00962     if (NULLPTR == messageQID)
00963     {
00964         return PAL_ERR_INVALID_ARGUMENT ;
00965     }
00966 
00967     messageQ = (palMessageQ_t*)messageQID;
00968     event = osMessageGet((osMessageQId)messageQ->messageQID, timeout);
00969     
00970     if ((messageValue != NULL) && (osEventMessage == event.status))
00971     {
00972         *messageValue = event.value.v;
00973         status = PAL_SUCCESS;
00974     }
00975     else if ((osEventTimeout == event.status) || (osOK == event.status))
00976     {
00977         status = PAL_ERR_RTOS_TIMEOUT ;
00978     }
00979     else if (osErrorParameter == event.status)
00980     {
00981         status = PAL_ERR_RTOS_PARAMETER;
00982     }
00983 
00984     return status;
00985 }
00986 
00987 
00988 palStatus_t pal_plat_osMessageQueueDestroy (palMessageQID_t* messageQID)
00989 {
00990     palStatus_t status = PAL_SUCCESS;
00991     palMessageQ_t* messageQ = NULL;
00992     
00993     if(NULL == messageQID || NULLPTR == *messageQID)
00994     {
00995         return PAL_ERR_INVALID_ARGUMENT ;
00996     }   
00997 
00998     messageQ = (palMessageQ_t*)*messageQID;
00999     free(messageQ->osMessageQ.pool);
01000     free(messageQ);
01001     *messageQID = NULLPTR;
01002     return status;
01003 }
01004 
01005 
01006 int32_t pal_plat_osAtomicIncrement (int32_t* valuePtr, int32_t increment)
01007 {
01008     if (increment >= 0)
01009     {
01010         return core_util_atomic_incr_u32((uint32_t*)valuePtr, increment);
01011     }
01012     else
01013     {
01014         return core_util_atomic_decr_u32((uint32_t*)valuePtr, 0 - increment);
01015     }
01016 }
01017 
01018 
01019  void *pal_plat_malloc (size_t len)
01020 {
01021     return malloc(len);
01022 }
01023 
01024 
01025  void pal_plat_free (void * buffer)
01026 {
01027     return free(buffer);
01028 }
01029 
01030 palStatus_t pal_plat_osRandomBuffer (uint8_t *randomBuf, size_t bufSizeBytes)
01031 {
01032     palStatus_t status = PAL_SUCCESS;
01033     int32_t platStatus = 0;
01034     size_t actualOutputLen = 0;
01035 
01036     if (g_randInitiated)
01037     {
01038         if (bufSizeBytes < sizeof(g_randomBuffer))
01039         {
01040             memcpy(randomBuf, g_randomBuffer, bufSizeBytes);
01041         }
01042         else
01043         {
01044             memcpy(randomBuf, g_randomBuffer, sizeof(g_randomBuffer));
01045         }
01046     }
01047     else
01048     {
01049         if (bufSizeBytes <= sizeof(g_randomBuffer))
01050         {
01051             platStatus = mbedtls_hardware_poll(NULL /*Not used by the function*/, g_randomBuffer, sizeof(g_randomBuffer), &actualOutputLen);
01052             if (0 != platStatus || actualOutputLen != sizeof(g_randomBuffer))
01053             {
01054                 status = PAL_ERR_RTOS_TRNG_FAILED ;
01055             }
01056             else
01057             {
01058                 memcpy(randomBuf, g_randomBuffer, bufSizeBytes);
01059                 g_randInitiated = true;
01060             }
01061         }
01062         else
01063         {
01064             platStatus = mbedtls_hardware_poll(NULL /*Not used by the function*/, randomBuf, bufSizeBytes, &actualOutputLen);
01065             if (0 != platStatus || actualOutputLen != bufSizeBytes)
01066             {
01067                 status = PAL_ERR_RTOS_TRNG_FAILED ;
01068             }
01069             else
01070             {
01071                 memcpy(g_randomBuffer, randomBuf, sizeof(g_randomBuffer));
01072                 g_randInitiated = true;
01073             }
01074         }     
01075     }
01076     return status;
01077 }
01078 
01079 #endif //mbedOS version