Sergey Pastor / 1

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers os_port_sys_bios.c Source File

os_port_sys_bios.c

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