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