Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers os_port_cmsis_rtos2.c Source File

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