Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers os_port_cmsis_rtos.c Source File

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