Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
os_port_cmsis_rtos.c
Go to the documentation of this file.
00001 /** 00002 * @file os_port_cmsis_rtos.c 00003 * @brief RTOS abstraction layer (CMSIS-RTOS) 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU General Public License 00011 * as published by the Free Software Foundation; either version 2 00012 * of the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software Foundation, 00021 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00022 * 00023 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00024 * @version 1.7.6 00025 **/ 00026 00027 //Switch to the appropriate trace level 00028 #define TRACE_LEVEL TRACE_LEVEL_OFF 00029 00030 //Dependencies 00031 #include <stdio.h> 00032 #include <stdlib.h> 00033 #include "os_port.h" 00034 #include "os_port_cmsis_rtos.h" 00035 #include "debug.h" 00036 00037 00038 /** 00039 * @brief Kernel initialization 00040 **/ 00041 00042 void osInitKernel(void) 00043 { 00044 //Check CMSIS-RTOS API version 00045 #if (osCMSIS >= 0x10001) 00046 //Initialize the kernel 00047 osKernelInitialize(); 00048 #endif 00049 } 00050 00051 00052 /** 00053 * @brief Start kernel 00054 **/ 00055 00056 void osStartKernel(void) 00057 { 00058 //Check CMSIS-RTOS API version 00059 #if (osCMSIS >= 0x10001) 00060 //Start the kernel 00061 osKernelStart(); 00062 #else 00063 //Start the kernel 00064 osKernelStart(NULL, NULL); 00065 #endif 00066 } 00067 00068 00069 /** 00070 * @brief Create a new task 00071 * @param[in] name A name identifying the task 00072 * @param[in] taskCode Pointer to the task entry function 00073 * @param[in] params A pointer to a variable to be passed to the task 00074 * @param[in] stackSize The initial size of the stack, in words 00075 * @param[in] priority The priority at which the task should run 00076 * @return If the function succeeds, the return value is a pointer to the 00077 * new task. If the function fails, the return value is NULL 00078 **/ 00079 00080 OsTask *osCreateTask(const char_t *name, OsTaskCode taskCode, 00081 void *params, size_t stackSize, int_t priority) 00082 { 00083 osThreadId threadId; 00084 osThreadDef_t threadDef; 00085 00086 #if defined(osCMSIS_RTX) 00087 threadDef.pthread = (os_pthread) taskCode; 00088 threadDef.tpriority = (osPriority) priority; 00089 threadDef.instances = 1; 00090 threadDef.stacksize = stackSize * sizeof(uint_t); 00091 #else 00092 threadDef.name = (char_t *) name; 00093 threadDef.pthread = (os_pthread) taskCode; 00094 threadDef.tpriority = (osPriority) priority; 00095 threadDef.instances = 1; 00096 threadDef.stacksize = stackSize; 00097 #endif 00098 00099 //Create a new thread 00100 threadId = osThreadCreate(&threadDef, params); 00101 //Return a handle to the newly created thread 00102 return (OsTask *) threadId; 00103 } 00104 00105 00106 /** 00107 * @brief Delete a task 00108 * @param[in] task Pointer to the task to be deleted 00109 **/ 00110 00111 void osDeleteTask(OsTask *task) 00112 { 00113 //Delete the specified thread 00114 osThreadTerminate((osThreadId) task); 00115 } 00116 00117 00118 /** 00119 * @brief Delay routine 00120 * @param[in] delay Amount of time for which the calling task should block 00121 **/ 00122 00123 void osDelayTask(systime_t delay) 00124 { 00125 //Delay the thread for the specified duration 00126 osDelay(delay); 00127 } 00128 00129 00130 /** 00131 * @brief Yield control to the next task 00132 **/ 00133 00134 void osSwitchTask(void) 00135 { 00136 //Force a context switch 00137 osThreadYield(); 00138 } 00139 00140 00141 /** 00142 * @brief Suspend scheduler activity 00143 **/ 00144 00145 void osSuspendAllTasks(void) 00146 { 00147 #if !defined(osCMSIS_RTX) 00148 //Make sure the operating system is running 00149 if(osKernelRunning()) 00150 { 00151 //Suspend all threads 00152 osThreadSuspendAll(); 00153 } 00154 #endif 00155 } 00156 00157 00158 /** 00159 * @brief Resume scheduler activity 00160 **/ 00161 00162 void osResumeAllTasks(void) 00163 { 00164 #if !defined(osCMSIS_RTX) 00165 //Make sure the operating system is running 00166 if(osKernelRunning()) 00167 { 00168 //Resume all threads 00169 osThreadResumeAll(); 00170 } 00171 #endif 00172 } 00173 00174 00175 /** 00176 * @brief Create an event object 00177 * @param[in] event Pointer to the event object 00178 * @return The function returns TRUE if the event object was successfully 00179 * created. Otherwise, FALSE is returned 00180 **/ 00181 00182 bool_t osCreateEvent(OsEvent *event) 00183 { 00184 osSemaphoreDef_t semaphoreDef; 00185 00186 #if defined(osCMSIS_RTX) 00187 semaphoreDef.semaphore = event->cb; 00188 #else 00189 semaphoreDef.dummy = 0; 00190 #endif 00191 00192 //Create a binary semaphore object 00193 event->id = osSemaphoreCreate(&semaphoreDef, 1); 00194 00195 //Check whether the returned semaphore ID is valid 00196 if(event->id != NULL) 00197 { 00198 //Force the specified event to the nonsignaled state 00199 osSemaphoreWait(event->id, 0); 00200 //Event successfully created 00201 return TRUE; 00202 } 00203 else 00204 { 00205 //Failed to create event object 00206 return FALSE; 00207 } 00208 } 00209 00210 00211 /** 00212 * @brief Delete an event object 00213 * @param[in] event Pointer to the event object 00214 **/ 00215 00216 void osDeleteEvent(OsEvent *event) 00217 { 00218 //Make sure the semaphore ID is valid 00219 if(event->id != NULL) 00220 { 00221 //Properly dispose the event object 00222 osSemaphoreDelete(event->id); 00223 } 00224 } 00225 00226 00227 /** 00228 * @brief Set the specified event object to the signaled state 00229 * @param[in] event Pointer to the event object 00230 **/ 00231 00232 void osSetEvent(OsEvent *event) 00233 { 00234 //Set the specified event to the signaled state 00235 osSemaphoreRelease(event->id); 00236 } 00237 00238 00239 /** 00240 * @brief Set the specified event object to the nonsignaled state 00241 * @param[in] event Pointer to the event object 00242 **/ 00243 00244 void osResetEvent(OsEvent *event) 00245 { 00246 #if defined(osCMSIS_RTX) 00247 //Force the specified event to the nonsignaled state 00248 while(osSemaphoreWait(event->id, 0) > 0); 00249 #else 00250 //Force the specified event to the nonsignaled state 00251 osSemaphoreWait(event->id, 0); 00252 #endif 00253 } 00254 00255 00256 /** 00257 * @brief Wait until the specified event is in the signaled state 00258 * @param[in] event Pointer to the event object 00259 * @param[in] timeout Timeout interval 00260 * @return The function returns TRUE if the state of the specified object is 00261 * signaled. FALSE is returned if the timeout interval elapsed 00262 **/ 00263 00264 bool_t osWaitForEvent(OsEvent *event, systime_t timeout) 00265 { 00266 int32_t ret; 00267 00268 //Wait until the specified event is in the signaled 00269 //state or the timeout interval elapses 00270 if(timeout == INFINITE_DELAY) 00271 { 00272 //Infinite timeout period 00273 ret = osSemaphoreWait(event->id, osWaitForever); 00274 } 00275 else 00276 { 00277 #if defined(osCMSIS_RTX) 00278 systime_t n; 00279 00280 //Loop until the assigned time period has elapsed 00281 do 00282 { 00283 //Limit the timeout value 00284 n = MIN(timeout, 10000); 00285 //Wait for the specified time interval 00286 ret = osSemaphoreWait(event->id, n); 00287 //Decrement timeout value 00288 timeout -= n; 00289 00290 //Check timeout value 00291 } while(ret == 0 && timeout > 0); 00292 #else 00293 //Wait for the specified time interval 00294 ret = osSemaphoreWait(event->id, timeout); 00295 #endif 00296 } 00297 00298 #if defined(osCMSIS_RTX) 00299 //Check return value 00300 if(ret > 0) 00301 { 00302 //Force the event back to the nonsignaled state 00303 while(osSemaphoreWait(event->id, 0) > 0); 00304 00305 //The specified event is in the signaled state 00306 return TRUE; 00307 } 00308 else 00309 { 00310 //The timeout interval elapsed 00311 return FALSE; 00312 } 00313 #else 00314 //Check return value 00315 if(ret == osOK) 00316 return TRUE; 00317 else 00318 return FALSE; 00319 #endif 00320 } 00321 00322 00323 /** 00324 * @brief Set an event object to the signaled state from an interrupt service routine 00325 * @param[in] event Pointer to the event object 00326 * @return TRUE if setting the event to signaled state caused a task to unblock 00327 * and the unblocked task has a priority higher than the currently running task 00328 **/ 00329 00330 bool_t osSetEventFromIsr(OsEvent *event) 00331 { 00332 //Set the specified event to the signaled state 00333 osSemaphoreRelease(event->id); 00334 00335 //The return value is not relevant 00336 return FALSE; 00337 } 00338 00339 00340 /** 00341 * @brief Create a semaphore object 00342 * @param[in] semaphore Pointer to the semaphore object 00343 * @param[in] count The maximum count for the semaphore object. This value 00344 * must be greater than zero 00345 * @return The function returns TRUE if the semaphore was successfully 00346 * created. Otherwise, FALSE is returned 00347 **/ 00348 00349 bool_t osCreateSemaphore(OsSemaphore *semaphore, uint_t count) 00350 { 00351 osSemaphoreDef_t semaphoreDef; 00352 00353 #if defined(osCMSIS_RTX) 00354 semaphoreDef.semaphore = semaphore->cb; 00355 #else 00356 semaphoreDef.dummy = 0; 00357 #endif 00358 00359 //Create a semaphore object 00360 semaphore->id = osSemaphoreCreate(&semaphoreDef, count); 00361 00362 //Check whether the returned semaphore ID is valid 00363 if(semaphore->id != NULL) 00364 return TRUE; 00365 else 00366 return FALSE; 00367 } 00368 00369 00370 /** 00371 * @brief Delete a semaphore object 00372 * @param[in] semaphore Pointer to the semaphore object 00373 **/ 00374 00375 void osDeleteSemaphore(OsSemaphore *semaphore) 00376 { 00377 //Make sure the semaphore ID is valid 00378 if(semaphore->id != NULL) 00379 { 00380 //Properly dispose the specified semaphore 00381 osSemaphoreDelete(semaphore->id); 00382 } 00383 } 00384 00385 00386 /** 00387 * @brief Wait for the specified semaphore to be available 00388 * @param[in] semaphore Pointer to the semaphore object 00389 * @param[in] timeout Timeout interval 00390 * @return The function returns TRUE if the semaphore is available. FALSE is 00391 * returned if the timeout interval elapsed 00392 **/ 00393 00394 bool_t osWaitForSemaphore(OsSemaphore *semaphore, systime_t timeout) 00395 { 00396 int32_t ret; 00397 00398 //Wait until the semaphore is available or the timeout interval elapses 00399 if(timeout == INFINITE_DELAY) 00400 { 00401 //Infinite timeout period 00402 ret = osSemaphoreWait(semaphore->id, osWaitForever); 00403 } 00404 else 00405 { 00406 #if defined(osCMSIS_RTX) 00407 systime_t n; 00408 00409 //Loop until the assigned time period has elapsed 00410 do 00411 { 00412 //Limit the timeout value 00413 n = MIN(timeout, 10000); 00414 //Wait for the specified time interval 00415 ret = osSemaphoreWait(semaphore->id, n); 00416 //Decrement timeout value 00417 timeout -= n; 00418 00419 //Check timeout value 00420 } while(ret == 0 && timeout > 0); 00421 #else 00422 //Wait for the specified time interval 00423 ret = osSemaphoreWait(semaphore->id, timeout); 00424 #endif 00425 } 00426 00427 #if defined(osCMSIS_RTX) 00428 //Check return value 00429 if(ret > 0) 00430 return TRUE; 00431 else 00432 return FALSE; 00433 #else 00434 //Check return value 00435 if(ret == osOK) 00436 return TRUE; 00437 else 00438 return FALSE; 00439 #endif 00440 } 00441 00442 00443 /** 00444 * @brief Release the specified semaphore object 00445 * @param[in] semaphore Pointer to the semaphore object 00446 **/ 00447 00448 void osReleaseSemaphore(OsSemaphore *semaphore) 00449 { 00450 //Release the semaphore 00451 osSemaphoreRelease(semaphore->id); 00452 } 00453 00454 00455 /** 00456 * @brief Create a mutex object 00457 * @param[in] mutex Pointer to the mutex object 00458 * @return The function returns TRUE if the mutex was successfully 00459 * created. Otherwise, FALSE is returned 00460 **/ 00461 00462 bool_t osCreateMutex(OsMutex *mutex) 00463 { 00464 osMutexDef_t mutexDef; 00465 00466 #if defined(osCMSIS_RTX) 00467 mutexDef.mutex = mutex->cb; 00468 #else 00469 mutexDef.dummy = 0; 00470 #endif 00471 00472 //Create a mutex object 00473 mutex->id = osMutexCreate(&mutexDef); 00474 00475 //Check whether the returned mutex ID is valid 00476 if(mutex->id != NULL) 00477 return TRUE; 00478 else 00479 return FALSE; 00480 } 00481 00482 00483 /** 00484 * @brief Delete a mutex object 00485 * @param[in] mutex Pointer to the mutex object 00486 **/ 00487 00488 void osDeleteMutex(OsMutex *mutex) 00489 { 00490 //Make sure the mutex ID is valid 00491 if(mutex->id != NULL) 00492 { 00493 //Properly dispose the specified mutex 00494 osMutexDelete(mutex->id); 00495 } 00496 } 00497 00498 00499 /** 00500 * @brief Acquire ownership of the specified mutex object 00501 * @param[in] mutex Pointer to the mutex object 00502 **/ 00503 00504 void osAcquireMutex(OsMutex *mutex) 00505 { 00506 //Obtain ownership of the mutex object 00507 osMutexWait(mutex->id, osWaitForever); 00508 } 00509 00510 00511 /** 00512 * @brief Release ownership of the specified mutex object 00513 * @param[in] mutex Pointer to the mutex object 00514 **/ 00515 00516 void osReleaseMutex(OsMutex *mutex) 00517 { 00518 //Release ownership of the mutex object 00519 osMutexRelease(mutex->id); 00520 } 00521 00522 00523 /** 00524 * @brief Retrieve system time 00525 * @return Number of milliseconds elapsed since the system was last started 00526 **/ 00527 00528 systime_t osGetSystemTime(void) 00529 { 00530 systime_t time; 00531 00532 #if defined(osCMSIS_RTX) 00533 //Forward function declaration 00534 extern uint32_t rt_time_get(void); 00535 00536 //Get current tick count 00537 time = rt_time_get(); 00538 #else 00539 //Get current tick count 00540 time = osKernelSysTick(); 00541 #endif 00542 00543 //Convert system ticks to milliseconds 00544 return OS_SYSTICKS_TO_MS(time); 00545 } 00546 00547 00548 /** 00549 * @brief Allocate a memory block 00550 * @param[in] size Bytes to allocate 00551 * @return A pointer to the allocated memory block or NULL if 00552 * there is insufficient memory available 00553 **/ 00554 00555 void *osAllocMem(size_t size) 00556 { 00557 void *p; 00558 00559 //Enter critical section 00560 osSuspendAllTasks(); 00561 //Allocate a memory block 00562 p = malloc(size); 00563 //Leave critical section 00564 osResumeAllTasks(); 00565 00566 //Debug message 00567 TRACE_DEBUG("Allocating %u bytes at 0x%08X\r\n", size, (uint_t) p); 00568 00569 //Return a pointer to the newly allocated memory block 00570 return p; 00571 } 00572 00573 00574 /** 00575 * @brief Release a previously allocated memory block 00576 * @param[in] p Previously allocated memory block to be freed 00577 **/ 00578 00579 void osFreeMem(void *p) 00580 { 00581 //Make sure the pointer is valid 00582 if(p != NULL) 00583 { 00584 //Debug message 00585 TRACE_DEBUG("Freeing memory at 0x%08X\r\n", (uint_t) p); 00586 00587 //Enter critical section 00588 osSuspendAllTasks(); 00589 //Free memory block 00590 free(p); 00591 //Leave critical section 00592 osResumeAllTasks(); 00593 } 00594 } 00595
Generated on Tue Jul 12 2022 17:10:15 by
