Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 }
Generated on Tue Jul 12 2022 21:20:28 by
1.7.2