Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Tue Jul 12 2022 17:10:15 by
