Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
os_port_ucos2.c
Go to the documentation of this file.
00001 /** 00002 * @file os_port_ucos2.c 00003 * @brief RTOS abstraction layer (Micrium uC/OS-II) 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_ucos2.h" 00036 #include "debug.h" 00037 00038 //Variables 00039 static OsTask tcbTable[OS_LOWEST_PRIO]; 00040 00041 00042 /** 00043 * @brief Kernel initialization 00044 **/ 00045 00046 void osInitKernel(void) 00047 { 00048 //Initialize table 00049 memset(tcbTable, 0, sizeof(tcbTable)); 00050 00051 //Scheduler initialization 00052 OSInit(); 00053 } 00054 00055 00056 /** 00057 * @brief Start kernel 00058 **/ 00059 00060 void osStartKernel(void) 00061 { 00062 //Start the scheduler 00063 OSStart(); 00064 } 00065 00066 00067 /** 00068 * @brief Create a static task 00069 * @param[out] task Pointer to the task structure 00070 * @param[in] name A name identifying the task 00071 * @param[in] taskCode Pointer to the task entry function 00072 * @param[in] params A pointer to a variable to be passed to the task 00073 * @param[in] stack Pointer to the stack 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 The function returns TRUE if the task was successfully 00077 * created. Otherwise, FALSE is returned 00078 **/ 00079 00080 bool_t osCreateStaticTask(OsTask *task, const char_t *name, OsTaskCode taskCode, 00081 void *params, void *stack, size_t stackSize, int_t priority) 00082 { 00083 INT8U err; 00084 OS_STK *stackTop; 00085 00086 //Check stack size 00087 if(stackSize == 0) 00088 return FALSE; 00089 00090 //Top of the stack 00091 stackTop = (OS_STK *) stack + (stackSize - 1); 00092 00093 //Search for a free TCB 00094 while(priority < (OS_LOWEST_PRIO - 3) && OSTCBPrioTbl[priority] != 0) 00095 priority++; 00096 00097 //No more TCB available? 00098 if(priority >= (OS_LOWEST_PRIO - 3)) 00099 return FALSE; 00100 00101 //Create a new task 00102 err = OSTaskCreateExt(taskCode, params, stackTop, priority, priority, 00103 stack, stackSize, NULL, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); 00104 00105 //Check whether the task was successfully created 00106 if(err == OS_ERR_NONE) 00107 { 00108 //Save task priority 00109 task->prio = priority; 00110 //The task was successfully created 00111 return TRUE; 00112 } 00113 else 00114 { 00115 //Report an error 00116 return FALSE; 00117 } 00118 } 00119 00120 00121 /** 00122 * @brief Create a new task 00123 * @param[in] name A name identifying the task 00124 * @param[in] taskCode Pointer to the task entry function 00125 * @param[in] params A pointer to a variable to be passed to the task 00126 * @param[in] stackSize The initial size of the stack, in words 00127 * @param[in] priority The priority at which the task should run 00128 * @return If the function succeeds, the return value is a pointer to the 00129 * new task. If the function fails, the return value is NULL 00130 **/ 00131 00132 OsTask *osCreateTask(const char_t *name, OsTaskCode taskCode, 00133 void *params, size_t stackSize, int_t priority) 00134 { 00135 //INT8U i; 00136 OS_STK *stack; 00137 00138 //Allocate a memory block to hold the task's stack 00139 stack = osAllocMem(stackSize * sizeof(OS_STK)); 00140 00141 //Successful memory allocation? 00142 if(stack != NULL) 00143 { 00144 //Create task 00145 if(osCreateStaticTask(&tcbTable[priority], name, 00146 taskCode, params, stack, stackSize, priority)) 00147 { 00148 //Return a valid handle 00149 return &tcbTable[priority]; 00150 } 00151 else 00152 { 00153 //Clean up side effects 00154 osFreeMem(stack); 00155 //Report an error 00156 return NULL; 00157 } 00158 } 00159 else 00160 { 00161 //Memory allocation failed 00162 return NULL; 00163 } 00164 } 00165 00166 00167 /** 00168 * @brief Delete a task 00169 * @param[in] task Pointer to the task to be deleted 00170 **/ 00171 00172 void osDeleteTask(OsTask *task) 00173 { 00174 //Delete the specified task 00175 OSTaskDel(task->prio); 00176 } 00177 00178 00179 /** 00180 * @brief Delay routine 00181 * @param[in] delay Amount of time for which the calling task should block 00182 **/ 00183 00184 void osDelayTask(systime_t delay) 00185 { 00186 INT16U n; 00187 00188 //Convert milliseconds to system ticks 00189 delay = OS_MS_TO_SYSTICKS(delay); 00190 00191 //Delay the task for the specified duration 00192 while(delay > 0) 00193 { 00194 //The maximum delay is 65535 clock ticks 00195 n = MIN(delay, 65535); 00196 //Wait for the specified amount of time 00197 OSTimeDly(n); 00198 //Decrement delay value 00199 delay -= n; 00200 } 00201 } 00202 00203 00204 /** 00205 * @brief Yield control to the next task 00206 **/ 00207 00208 void osSwitchTask(void) 00209 { 00210 //Not implemented 00211 } 00212 00213 00214 /** 00215 * @brief Suspend scheduler activity 00216 **/ 00217 00218 void osSuspendAllTasks(void) 00219 { 00220 //Make sure the operating system is running 00221 if(OSRunning == OS_TRUE) 00222 { 00223 //Suspend scheduler activity 00224 OSSchedLock(); 00225 } 00226 } 00227 00228 00229 /** 00230 * @brief Resume scheduler activity 00231 **/ 00232 00233 void osResumeAllTasks(void) 00234 { 00235 //Make sure the operating system is running 00236 if(OSRunning == OS_TRUE) 00237 { 00238 //Resume scheduler activity 00239 OSSchedUnlock(); 00240 } 00241 } 00242 00243 00244 /** 00245 * @brief Create an event object 00246 * @param[in] event Pointer to the event object 00247 * @return The function returns TRUE if the event object was successfully 00248 * created. Otherwise, FALSE is returned 00249 **/ 00250 00251 bool_t osCreateEvent(OsEvent *event) 00252 { 00253 INT8U err; 00254 00255 //Create an event flag group 00256 event->p = OSFlagCreate(0, &err); 00257 00258 //Check whether the event flag group was successfully created 00259 if(event->p != NULL && err == OS_ERR_NONE) 00260 return TRUE; 00261 else 00262 return FALSE; 00263 } 00264 00265 00266 /** 00267 * @brief Delete an event object 00268 * @param[in] event Pointer to the event object 00269 **/ 00270 00271 void osDeleteEvent(OsEvent *event) 00272 { 00273 INT8U err; 00274 00275 //Make sure the operating system is running 00276 if(OSRunning == OS_TRUE) 00277 { 00278 //Properly dispose the event object 00279 OSFlagDel(event->p, OS_DEL_ALWAYS, &err); 00280 } 00281 } 00282 00283 00284 /** 00285 * @brief Set the specified event object to the signaled state 00286 * @param[in] event Pointer to the event object 00287 **/ 00288 00289 void osSetEvent(OsEvent *event) 00290 { 00291 INT8U err; 00292 00293 //Set the specified event to the signaled state 00294 OSFlagPost(event->p, 1, OS_FLAG_SET, &err); 00295 } 00296 00297 00298 /** 00299 * @brief Set the specified event object to the nonsignaled state 00300 * @param[in] event Pointer to the event object 00301 **/ 00302 00303 void osResetEvent(OsEvent *event) 00304 { 00305 INT8U err; 00306 00307 //Force the specified event to the nonsignaled state 00308 OSFlagPost(event->p, 1, OS_FLAG_CLR, &err); 00309 } 00310 00311 00312 /** 00313 * @brief Wait until the specified event is in the signaled state 00314 * @param[in] event Pointer to the event object 00315 * @param[in] timeout Timeout interval 00316 * @return The function returns TRUE if the state of the specified object is 00317 * signaled. FALSE is returned if the timeout interval elapsed 00318 **/ 00319 00320 bool_t osWaitForEvent(OsEvent *event, systime_t timeout) 00321 { 00322 INT8U err; 00323 INT16U n; 00324 00325 //Wait until the specified event is in the signaled 00326 //state or the timeout interval elapses 00327 if(timeout == 0) 00328 { 00329 //Non-blocking call 00330 OSFlagAccept(event->p, 1, OS_FLAG_WAIT_SET_ANY | OS_FLAG_CONSUME, &err); 00331 } 00332 else if(timeout == INFINITE_DELAY) 00333 { 00334 //Infinite timeout period 00335 OSFlagPend(event->p, 1, OS_FLAG_WAIT_SET_ANY | OS_FLAG_CONSUME, 0, &err); 00336 } 00337 else 00338 { 00339 //Convert milliseconds to system ticks 00340 timeout = OS_MS_TO_SYSTICKS(timeout); 00341 00342 //Loop until the assigned time period has elapsed 00343 do 00344 { 00345 //The maximum timeout is 65535 clock ticks 00346 n = MIN(timeout, 65535); 00347 //Wait for the specified time interval 00348 OSFlagPend(event->p, 1, OS_FLAG_WAIT_SET_ANY | OS_FLAG_CONSUME, n, &err); 00349 //Decrement timeout value 00350 timeout -= n; 00351 00352 //Check timeout value 00353 } while(err == OS_ERR_TIMEOUT && timeout > 0); 00354 } 00355 00356 //Check whether the specified event is set 00357 if(err == OS_ERR_NONE) 00358 return TRUE; 00359 else 00360 return FALSE; 00361 } 00362 00363 00364 /** 00365 * @brief Set an event object to the signaled state from an interrupt service routine 00366 * @param[in] event Pointer to the event object 00367 * @return TRUE if setting the event to signaled state caused a task to unblock 00368 * and the unblocked task has a priority higher than the currently running task 00369 **/ 00370 00371 bool_t osSetEventFromIsr(OsEvent *event) 00372 { 00373 INT8U err; 00374 00375 //Set the specified event to the signaled state 00376 OSFlagPost(event->p, 1, OS_FLAG_SET, &err); 00377 00378 //The return value is not relevant 00379 return FALSE; 00380 } 00381 00382 00383 /** 00384 * @brief Create a semaphore object 00385 * @param[in] semaphore Pointer to the semaphore object 00386 * @param[in] count The maximum count for the semaphore object. This value 00387 * must be greater than zero 00388 * @return The function returns TRUE if the semaphore was successfully 00389 * created. Otherwise, FALSE is returned 00390 **/ 00391 00392 bool_t osCreateSemaphore(OsSemaphore *semaphore, uint_t count) 00393 { 00394 //Create a semaphore 00395 semaphore->p = OSSemCreate(count); 00396 00397 //Check whether the semaphore was successfully created 00398 if(semaphore->p != NULL) 00399 return TRUE; 00400 else 00401 return FALSE; 00402 } 00403 00404 00405 /** 00406 * @brief Delete a semaphore object 00407 * @param[in] semaphore Pointer to the semaphore object 00408 **/ 00409 00410 void osDeleteSemaphore(OsSemaphore *semaphore) 00411 { 00412 INT8U err; 00413 00414 //Make sure the operating system is running 00415 if(OSRunning == OS_TRUE) 00416 { 00417 //Properly dispose the specified semaphore 00418 OSSemDel(semaphore->p, OS_DEL_ALWAYS, &err); 00419 } 00420 } 00421 00422 00423 /** 00424 * @brief Wait for the specified semaphore to be available 00425 * @param[in] semaphore Pointer to the semaphore object 00426 * @param[in] timeout Timeout interval 00427 * @return The function returns TRUE if the semaphore is available. FALSE is 00428 * returned if the timeout interval elapsed 00429 **/ 00430 00431 bool_t osWaitForSemaphore(OsSemaphore *semaphore, systime_t timeout) 00432 { 00433 INT8U err; 00434 INT16U n; 00435 00436 //Wait until the semaphore is available or the timeout interval elapses 00437 if(timeout == 0) 00438 { 00439 //Non-blocking call 00440 if(OSSemAccept(semaphore->p) > 0) 00441 err = OS_ERR_NONE; 00442 else 00443 err = OS_ERR_TIMEOUT; 00444 } 00445 else if(timeout == INFINITE_DELAY) 00446 { 00447 //Infinite timeout period 00448 OSSemPend(semaphore->p, 0, &err); 00449 } 00450 else 00451 { 00452 //Convert milliseconds to system ticks 00453 timeout = OS_MS_TO_SYSTICKS(timeout); 00454 00455 //Loop until the assigned time period has elapsed 00456 do 00457 { 00458 //The maximum timeout is 65535 clock ticks 00459 n = MIN(timeout, 65535); 00460 //Wait for the specified time interval 00461 OSSemPend(semaphore->p, n, &err); 00462 //Decrement timeout value 00463 timeout -= n; 00464 00465 //Check timeout value 00466 } while(err == OS_ERR_TIMEOUT && timeout > 0); 00467 } 00468 00469 //Check whether the specified semaphore is available 00470 if(err == OS_ERR_NONE) 00471 return TRUE; 00472 else 00473 return FALSE; 00474 } 00475 00476 00477 /** 00478 * @brief Release the specified semaphore object 00479 * @param[in] semaphore Pointer to the semaphore object 00480 **/ 00481 00482 void osReleaseSemaphore(OsSemaphore *semaphore) 00483 { 00484 //Release the semaphore 00485 OSSemPost(semaphore->p); 00486 } 00487 00488 00489 /** 00490 * @brief Create a mutex object 00491 * @param[in] mutex Pointer to the mutex object 00492 * @return The function returns TRUE if the mutex was successfully 00493 * created. Otherwise, FALSE is returned 00494 **/ 00495 00496 bool_t osCreateMutex(OsMutex *mutex) 00497 { 00498 #if 1 00499 bool_t status; 00500 00501 //Create an event object 00502 status = osCreateEvent((OsEvent *) mutex); 00503 00504 //Check whether the event object was successfully created 00505 if(status) 00506 { 00507 //Set event 00508 osSetEvent((OsEvent *) mutex); 00509 } 00510 00511 //Return status 00512 return status; 00513 #else 00514 INT8U err; 00515 00516 //Create a mutex 00517 mutex->p = OSMutexCreate(10, &err); 00518 00519 //Check whether the mutex was successfully created 00520 if(mutex->p != NULL && err == OS_ERR_NONE) 00521 return TRUE; 00522 else 00523 return FALSE; 00524 #endif 00525 } 00526 00527 00528 /** 00529 * @brief Delete a mutex object 00530 * @param[in] mutex Pointer to the mutex object 00531 **/ 00532 00533 void osDeleteMutex(OsMutex *mutex) 00534 { 00535 #if 1 00536 //Delete event object 00537 osDeleteEvent((OsEvent *) mutex); 00538 #else 00539 INT8U err; 00540 00541 //Make sure the operating system is running 00542 if(OSRunning == OS_TRUE) 00543 { 00544 //Properly dispose the specified mutex 00545 OSMutexDel(mutex->p, OS_DEL_ALWAYS, &err); 00546 } 00547 #endif 00548 } 00549 00550 00551 /** 00552 * @brief Acquire ownership of the specified mutex object 00553 * @param[in] mutex Pointer to the mutex object 00554 **/ 00555 00556 void osAcquireMutex(OsMutex *mutex) 00557 { 00558 #if 1 00559 //Wait for event 00560 osWaitForEvent((OsEvent *) mutex, INFINITE_DELAY); 00561 #else 00562 INT8U err; 00563 00564 //Obtain ownership of the mutex object 00565 OSMutexPend(mutex->p, 0, &err); 00566 #endif 00567 } 00568 00569 00570 /** 00571 * @brief Release ownership of the specified mutex object 00572 * @param[in] mutex Pointer to the mutex object 00573 **/ 00574 00575 void osReleaseMutex(OsMutex *mutex) 00576 { 00577 #if 1 00578 //Set event 00579 osSetEvent((OsEvent *) mutex); 00580 #else 00581 //Release ownership of the mutex object 00582 OSMutexPost(mutex->p); 00583 #endif 00584 } 00585 00586 00587 /** 00588 * @brief Retrieve system time 00589 * @return Number of milliseconds elapsed since the system was last started 00590 **/ 00591 00592 systime_t osGetSystemTime(void) 00593 { 00594 systime_t time; 00595 00596 //Get current tick count 00597 time = OSTimeGet(); 00598 00599 //Convert system ticks to milliseconds 00600 return OS_SYSTICKS_TO_MS(time); 00601 } 00602 00603 00604 /** 00605 * @brief Allocate a memory block 00606 * @param[in] size Bytes to allocate 00607 * @return A pointer to the allocated memory block or NULL if 00608 * there is insufficient memory available 00609 **/ 00610 00611 void *osAllocMem(size_t size) 00612 { 00613 void *p; 00614 00615 //Enter critical section 00616 osSuspendAllTasks(); 00617 //Allocate a memory block 00618 p = malloc(size); 00619 //Leave critical section 00620 osResumeAllTasks(); 00621 00622 //Debug message 00623 TRACE_DEBUG("Allocating %" PRIuSIZE " bytes at 0x%08" PRIXPTR "\r\n", size, (uintptr_t) p); 00624 00625 //Return a pointer to the newly allocated memory block 00626 return p; 00627 } 00628 00629 00630 /** 00631 * @brief Release a previously allocated memory block 00632 * @param[in] p Previously allocated memory block to be freed 00633 **/ 00634 00635 void osFreeMem(void *p) 00636 { 00637 //Make sure the pointer is valid 00638 if(p != NULL) 00639 { 00640 //Debug message 00641 TRACE_DEBUG("Freeing memory at 0x%08" PRIXPTR "\r\n", (uintptr_t) p); 00642 00643 //Enter critical section 00644 osSuspendAllTasks(); 00645 //Free memory block 00646 free(p); 00647 //Leave critical section 00648 osResumeAllTasks(); 00649 } 00650 } 00651
Generated on Tue Jul 12 2022 17:10:15 by
