Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers os_port_embos.c Source File

os_port_embos.c

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