Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
os_port_cmsis_rtos2.c
Go to the documentation of this file.
00001 /** 00002 * @file os_port_cmsis_rtos2.c 00003 * @brief RTOS abstraction layer (CMSIS-RTOS 2 / RTX v5) 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_rtos2.h" 00035 #include "debug.h" 00036 00037 00038 /** 00039 * @brief Kernel initialization 00040 **/ 00041 00042 void osInitKernel(void) 00043 { 00044 //Initialize the kernel 00045 osKernelInitialize(); 00046 } 00047 00048 00049 /** 00050 * @brief Start kernel 00051 **/ 00052 00053 void osStartKernel(void) 00054 { 00055 //Start the kernel 00056 osKernelStart(); 00057 } 00058 00059 00060 /** 00061 * @brief Create a new task 00062 * @param[in] name A name identifying the task 00063 * @param[in] taskCode Pointer to the task entry function 00064 * @param[in] params A pointer to a variable to be passed to the task 00065 * @param[in] stackSize The initial size of the stack, in words 00066 * @param[in] priority The priority at which the task should run 00067 * @return If the function succeeds, the return value is a pointer to the 00068 * new task. If the function fails, the return value is NULL 00069 **/ 00070 00071 OsTask *osCreateTask(const char_t *name, OsTaskCode taskCode, 00072 void *params, size_t stackSize, int_t priority) 00073 { 00074 osThreadId_t threadId; 00075 osThreadAttr_t threadAttr; 00076 00077 //Set thread attributes 00078 threadAttr.name = name; 00079 threadAttr.attr_bits = 0; 00080 threadAttr.cb_mem = NULL; 00081 threadAttr.cb_size = 0; 00082 threadAttr.stack_mem = NULL; 00083 threadAttr.stack_size = stackSize * sizeof(uint_t); 00084 threadAttr.priority = (osPriority_t) priority; 00085 threadAttr.tz_module = 0; 00086 threadAttr.reserved = 0; 00087 00088 //Create a new thread 00089 threadId = osThreadNew((os_thread_func_t ) taskCode, params, &threadAttr); 00090 //Return a handle to the newly created thread 00091 return (OsTask *) threadId; 00092 } 00093 00094 00095 /** 00096 * @brief Delete a task 00097 * @param[in] task Pointer to the task to be deleted 00098 **/ 00099 00100 void osDeleteTask(OsTask *task) 00101 { 00102 //Delete the specified thread 00103 if(task == NULL) 00104 osThreadExit(); 00105 else 00106 osThreadTerminate((osThreadId_t) task); 00107 } 00108 00109 00110 /** 00111 * @brief Delay routine 00112 * @param[in] delay Amount of time for which the calling task should block 00113 **/ 00114 00115 void osDelayTask(systime_t delay) 00116 { 00117 //Delay the thread for the specified duration 00118 osDelay(OS_MS_TO_SYSTICKS(delay)); 00119 } 00120 00121 00122 /** 00123 * @brief Yield control to the next task 00124 **/ 00125 00126 void osSwitchTask(void) 00127 { 00128 //Force a context switch 00129 osThreadYield(); 00130 } 00131 00132 00133 /** 00134 * @brief Suspend scheduler activity 00135 **/ 00136 00137 void osSuspendAllTasks(void) 00138 { 00139 //Make sure the operating system is running 00140 if(osKernelGetState() != osKernelInactive) 00141 { 00142 //Suspend all task switches 00143 osKernelLock(); 00144 } 00145 } 00146 00147 00148 /** 00149 * @brief Resume scheduler activity 00150 **/ 00151 00152 void osResumeAllTasks(void) 00153 { 00154 //Make sure the operating system is running 00155 if(osKernelGetState() != osKernelInactive) 00156 { 00157 //Resume lock all task switches 00158 osKernelUnlock(); 00159 } 00160 } 00161 00162 00163 /** 00164 * @brief Create an event object 00165 * @param[in] event Pointer to the event object 00166 * @return The function returns TRUE if the event object was successfully 00167 * created. Otherwise, FALSE is returned 00168 **/ 00169 00170 bool_t osCreateEvent(OsEvent *event) 00171 { 00172 osSemaphoreAttr_t semaphoreAttr; 00173 00174 //Set semaphore attributes 00175 semaphoreAttr.name = NULL; 00176 semaphoreAttr.attr_bits = 0; 00177 00178 #if defined(os_CMSIS_RTX) 00179 semaphoreAttr.cb_mem = &event->cb; 00180 semaphoreAttr.cb_size = sizeof(os_semaphore_t); 00181 #else 00182 semaphoreAttr.cb_mem = NULL; 00183 semaphoreAttr.cb_size = 0; 00184 #endif 00185 00186 //Create a binary semaphore object 00187 event->id = osSemaphoreNew(1, 0, &semaphoreAttr); 00188 00189 //Check whether the returned semaphore ID is valid 00190 if(event->id != NULL) 00191 return TRUE; 00192 else 00193 return FALSE; 00194 } 00195 00196 00197 /** 00198 * @brief Delete an event object 00199 * @param[in] event Pointer to the event object 00200 **/ 00201 00202 void osDeleteEvent(OsEvent *event) 00203 { 00204 //Make sure the semaphore ID is valid 00205 if(event->id != NULL) 00206 { 00207 //Properly dispose the event object 00208 osSemaphoreDelete(event->id); 00209 } 00210 } 00211 00212 00213 /** 00214 * @brief Set the specified event object to the signaled state 00215 * @param[in] event Pointer to the event object 00216 **/ 00217 00218 void osSetEvent(OsEvent *event) 00219 { 00220 //Set the specified event to the signaled state 00221 osSemaphoreRelease(event->id); 00222 } 00223 00224 00225 /** 00226 * @brief Set the specified event object to the nonsignaled state 00227 * @param[in] event Pointer to the event object 00228 **/ 00229 00230 void osResetEvent(OsEvent *event) 00231 { 00232 //Force the specified event to the nonsignaled state 00233 osSemaphoreAcquire(event->id, 0); 00234 } 00235 00236 00237 /** 00238 * @brief Wait until the specified event is in the signaled state 00239 * @param[in] event Pointer to the event object 00240 * @param[in] timeout Timeout interval 00241 * @return The function returns TRUE if the state of the specified object is 00242 * signaled. FALSE is returned if the timeout interval elapsed 00243 **/ 00244 00245 bool_t osWaitForEvent(OsEvent *event, systime_t timeout) 00246 { 00247 osStatus_t status; 00248 00249 //Wait until the specified event is in the signaled 00250 //state or the timeout interval elapses 00251 if(timeout == INFINITE_DELAY) 00252 { 00253 //Infinite timeout period 00254 status = osSemaphoreAcquire(event->id, osWaitForever); 00255 } 00256 else 00257 { 00258 //Wait for the specified time interval 00259 status = osSemaphoreAcquire(event->id, OS_MS_TO_SYSTICKS(timeout)); 00260 } 00261 00262 //Check return value 00263 if(status == osOK) 00264 return TRUE; 00265 else 00266 return FALSE; 00267 } 00268 00269 00270 /** 00271 * @brief Set an event object to the signaled state from an interrupt service routine 00272 * @param[in] event Pointer to the event object 00273 * @return TRUE if setting the event to signaled state caused a task to unblock 00274 * and the unblocked task has a priority higher than the currently running task 00275 **/ 00276 00277 bool_t osSetEventFromIsr(OsEvent *event) 00278 { 00279 //Set the specified event to the signaled state 00280 osSemaphoreRelease(event->id); 00281 00282 //The return value is not relevant 00283 return FALSE; 00284 } 00285 00286 00287 /** 00288 * @brief Create a semaphore object 00289 * @param[in] semaphore Pointer to the semaphore object 00290 * @param[in] count The maximum count for the semaphore object. This value 00291 * must be greater than zero 00292 * @return The function returns TRUE if the semaphore was successfully 00293 * created. Otherwise, FALSE is returned 00294 **/ 00295 00296 bool_t osCreateSemaphore(OsSemaphore *semaphore, uint_t count) 00297 { 00298 osSemaphoreAttr_t semaphoreAttr; 00299 00300 //Set semaphore attributes 00301 semaphoreAttr.name = NULL; 00302 semaphoreAttr.attr_bits = 0; 00303 00304 #if defined(os_CMSIS_RTX) 00305 semaphoreAttr.cb_mem = &semaphore->cb; 00306 semaphoreAttr.cb_size = sizeof(os_semaphore_t); 00307 #else 00308 semaphoreAttr.cb_mem = NULL; 00309 semaphoreAttr.cb_size = 0; 00310 #endif 00311 00312 //Create a semaphore object 00313 semaphore->id = osSemaphoreNew(count, count, &semaphoreAttr); 00314 00315 //Check whether the returned semaphore ID is valid 00316 if(semaphore->id != NULL) 00317 return TRUE; 00318 else 00319 return FALSE; 00320 } 00321 00322 00323 /** 00324 * @brief Delete a semaphore object 00325 * @param[in] semaphore Pointer to the semaphore object 00326 **/ 00327 00328 void osDeleteSemaphore(OsSemaphore *semaphore) 00329 { 00330 //Make sure the semaphore ID is valid 00331 if(semaphore->id != NULL) 00332 { 00333 //Properly dispose the specified semaphore 00334 osSemaphoreDelete(semaphore->id); 00335 } 00336 } 00337 00338 00339 /** 00340 * @brief Wait for the specified semaphore to be available 00341 * @param[in] semaphore Pointer to the semaphore object 00342 * @param[in] timeout Timeout interval 00343 * @return The function returns TRUE if the semaphore is available. FALSE is 00344 * returned if the timeout interval elapsed 00345 **/ 00346 00347 bool_t osWaitForSemaphore(OsSemaphore *semaphore, systime_t timeout) 00348 { 00349 osStatus_t status; 00350 00351 //Wait until the semaphore is available or the timeout interval elapses 00352 if(timeout == INFINITE_DELAY) 00353 { 00354 //Infinite timeout period 00355 status = osSemaphoreAcquire(semaphore->id, osWaitForever); 00356 } 00357 else 00358 { 00359 //Wait for the specified time interval 00360 status = osSemaphoreAcquire(semaphore->id, OS_MS_TO_SYSTICKS(timeout)); 00361 } 00362 00363 //Check return value 00364 if(status == osOK) 00365 return TRUE; 00366 else 00367 return FALSE; 00368 } 00369 00370 00371 /** 00372 * @brief Release the specified semaphore object 00373 * @param[in] semaphore Pointer to the semaphore object 00374 **/ 00375 00376 void osReleaseSemaphore(OsSemaphore *semaphore) 00377 { 00378 //Release the semaphore 00379 osSemaphoreRelease(semaphore->id); 00380 } 00381 00382 00383 /** 00384 * @brief Create a mutex object 00385 * @param[in] mutex Pointer to the mutex object 00386 * @return The function returns TRUE if the mutex was successfully 00387 * created. Otherwise, FALSE is returned 00388 **/ 00389 00390 bool_t osCreateMutex(OsMutex *mutex) 00391 { 00392 osMutexAttr_t mutexAttr; 00393 00394 //Set mutex attributes 00395 mutexAttr.name = NULL; 00396 mutexAttr.attr_bits = 0; 00397 00398 #if defined(os_CMSIS_RTX) 00399 mutexAttr.cb_mem = &mutex->cb; 00400 mutexAttr.cb_size = sizeof(os_mutex_t); 00401 #else 00402 mutexAttr.cb_mem = NULL; 00403 mutexAttr.cb_size = 0; 00404 #endif 00405 00406 //Create a mutex object 00407 mutex->id = osMutexNew(&mutexAttr); 00408 00409 //Check whether the returned mutex ID is valid 00410 if(mutex->id != NULL) 00411 return TRUE; 00412 else 00413 return FALSE; 00414 } 00415 00416 00417 /** 00418 * @brief Delete a mutex object 00419 * @param[in] mutex Pointer to the mutex object 00420 **/ 00421 00422 void osDeleteMutex(OsMutex *mutex) 00423 { 00424 //Make sure the mutex ID is valid 00425 if(mutex->id != NULL) 00426 { 00427 //Properly dispose the specified mutex 00428 osMutexDelete(mutex->id); 00429 } 00430 } 00431 00432 00433 /** 00434 * @brief Acquire ownership of the specified mutex object 00435 * @param[in] mutex Pointer to the mutex object 00436 **/ 00437 00438 void osAcquireMutex(OsMutex *mutex) 00439 { 00440 //Obtain ownership of the mutex object 00441 osMutexAcquire(mutex->id, osWaitForever); 00442 } 00443 00444 00445 /** 00446 * @brief Release ownership of the specified mutex object 00447 * @param[in] mutex Pointer to the mutex object 00448 **/ 00449 00450 void osReleaseMutex(OsMutex *mutex) 00451 { 00452 //Release ownership of the mutex object 00453 osMutexRelease(mutex->id); 00454 } 00455 00456 00457 /** 00458 * @brief Retrieve system time 00459 * @return Number of milliseconds elapsed since the system was last started 00460 **/ 00461 00462 systime_t osGetSystemTime(void) 00463 { 00464 systime_t time; 00465 00466 //Get current tick count 00467 time = osKernelGetTickCount(); 00468 00469 //Convert system ticks to milliseconds 00470 return OS_SYSTICKS_TO_MS(time); 00471 } 00472 00473 00474 /** 00475 * @brief Allocate a memory block 00476 * @param[in] size Bytes to allocate 00477 * @return A pointer to the allocated memory block or NULL if 00478 * there is insufficient memory available 00479 **/ 00480 00481 void *osAllocMem(size_t size) 00482 { 00483 void *p; 00484 00485 //Enter critical section 00486 osSuspendAllTasks(); 00487 //Allocate a memory block 00488 p = malloc(size); 00489 //Leave critical section 00490 osResumeAllTasks(); 00491 00492 //Debug message 00493 TRACE_DEBUG("Allocating %u bytes at 0x%08X\r\n", size, (uint_t) p); 00494 00495 //Return a pointer to the newly allocated memory block 00496 return p; 00497 } 00498 00499 00500 /** 00501 * @brief Release a previously allocated memory block 00502 * @param[in] p Previously allocated memory block to be freed 00503 **/ 00504 00505 void osFreeMem(void *p) 00506 { 00507 //Make sure the pointer is valid 00508 if(p != NULL) 00509 { 00510 //Debug message 00511 TRACE_DEBUG("Freeing memory at 0x%08X\r\n", (uint_t) p); 00512 00513 //Enter critical section 00514 osSuspendAllTasks(); 00515 //Free memory block 00516 free(p); 00517 //Leave critical section 00518 osResumeAllTasks(); 00519 } 00520 } 00521
Generated on Tue Jul 12 2022 17:10:15 by
