Ram Gandikota / Mbed OS ABCD
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_plat_rtos.c Source File

pal_plat_rtos.c

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