Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
os_port_rtx.c
00001 /** 00002 * @file os_port_rtx.c 00003 * @brief RTOS abstraction layer (Keil RTX) 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_rtx.h" 00036 #include "debug.h" 00037 00038 //Variables 00039 static bool_t running = FALSE; 00040 static OsTask taskTable[OS_PORT_MAX_TASKS]; 00041 00042 00043 /** 00044 * @brief Kernel initialization 00045 **/ 00046 00047 void osInitKernel(void) 00048 { 00049 //The scheduler is not running 00050 running = FALSE; 00051 //Initialize task table 00052 memset(taskTable, 0, sizeof(taskTable)); 00053 } 00054 00055 00056 /** 00057 * @brief Start kernel 00058 * @param[in] task Pointer to the task function to start after the kernel is initialized 00059 **/ 00060 00061 void osStartKernel(OsInitTaskCode task) 00062 { 00063 //The scheduler is now running 00064 running = TRUE; 00065 //Start the scheduler 00066 os_sys_init(task); 00067 } 00068 00069 00070 /** 00071 * @brief Create a static task 00072 * @param[out] task Pointer to the task structure 00073 * @param[in] name A name identifying the task 00074 * @param[in] taskCode Pointer to the task entry function 00075 * @param[in] params A pointer to a variable to be passed to the task 00076 * @param[in] stack Pointer to the stack 00077 * @param[in] stackSize The initial size of the stack, in words 00078 * @param[in] priority The priority at which the task should run 00079 * @return The function returns TRUE if the task was successfully 00080 * created. Otherwise, FALSE is returned 00081 **/ 00082 00083 bool_t osCreateStaticTask(OsTask *task, const char_t *name, OsTaskCode taskCode, 00084 void *params, void *stack, size_t stackSize, int_t priority) 00085 { 00086 //Create a new task 00087 task->tid = os_tsk_create_user_ex(taskCode, priority, 00088 stack, stackSize * sizeof(uint_t), params); 00089 00090 //Check task identifier 00091 if(task->tid != 0) 00092 return TRUE; 00093 else 00094 return FALSE; 00095 } 00096 00097 00098 /** 00099 * @brief Create a new task 00100 * @param[in] name A name identifying the task 00101 * @param[in] taskCode Pointer to the task entry function 00102 * @param[in] params A pointer to a variable to be passed to the task 00103 * @param[in] stackSize The initial size of the stack, in words 00104 * @param[in] priority The priority at which the task should run 00105 * @return If the function succeeds, the return value is a pointer to the 00106 * new task. If the function fails, the return value is NULL 00107 **/ 00108 00109 OsTask *osCreateTask(const char_t *name, OsTaskCode taskCode, 00110 void *params, size_t stackSize, int_t priority) 00111 { 00112 uint_t i; 00113 OsTask *task = NULL; 00114 00115 //Enter critical section 00116 osSuspendAllTasks(); 00117 00118 //Loop through table 00119 for(i = 0; i < OS_PORT_MAX_TASKS; i++) 00120 { 00121 //Check whether the current entry is free 00122 if(!taskTable[i].tid) 00123 break; 00124 } 00125 00126 //Any entry available in the table? 00127 if(i < OS_PORT_MAX_TASKS) 00128 { 00129 //Create a new task 00130 taskTable[i].tid = os_tsk_create_ex(taskCode, priority, params); 00131 00132 //Check whether the task was successfully created 00133 if(taskTable[i].tid != 0) 00134 task = &taskTable[i]; 00135 } 00136 00137 //Leave critical section 00138 osResumeAllTasks(); 00139 00140 //Return a pointer to the newly created task 00141 return task; 00142 } 00143 00144 00145 /** 00146 * @brief Delete a task 00147 * @param[in] task Pointer to the task to be deleted 00148 **/ 00149 00150 void osDeleteTask(OsTask *task) 00151 { 00152 uint_t i; 00153 OS_TID tid; 00154 00155 //Retrieve task ID 00156 if(task == NULL) 00157 tid = os_tsk_self(); 00158 else 00159 tid = task->tid; 00160 00161 //Enter critical section 00162 osSuspendAllTasks(); 00163 00164 //Loop through table 00165 for(i = 0; i < OS_PORT_MAX_TASKS; i++) 00166 { 00167 //Check current entry 00168 if(taskTable[i].tid == tid) 00169 { 00170 //Release current entry 00171 taskTable[i].tid = 0; 00172 } 00173 } 00174 00175 //Leave critical section 00176 osResumeAllTasks(); 00177 00178 //Delete the currently running task? 00179 if(task == NULL) 00180 { 00181 //Kill ourselves 00182 os_tsk_delete_self(); 00183 } 00184 else 00185 { 00186 //Delete the specified task 00187 os_tsk_delete(tid); 00188 } 00189 } 00190 00191 00192 /** 00193 * @brief Delay routine 00194 * @param[in] delay Amount of time for which the calling task should block 00195 **/ 00196 00197 void osDelayTask(systime_t delay) 00198 { 00199 uint16_t n; 00200 00201 //Convert milliseconds to system ticks 00202 delay = OS_MS_TO_SYSTICKS(delay); 00203 00204 //Delay the task for the specified duration 00205 while(delay > 0) 00206 { 00207 //The delay value cannot be higher than 0xFFFE... 00208 n = MIN(delay, 0xFFFE); 00209 //Wait for the specified amount of time 00210 os_dly_wait(n); 00211 //Decrement delay value 00212 delay -= n; 00213 } 00214 } 00215 00216 00217 /** 00218 * @brief Yield control to the next task 00219 **/ 00220 00221 void osSwitchTask(void) 00222 { 00223 //Pass control to the next task 00224 os_tsk_pass(); 00225 } 00226 00227 00228 /** 00229 * @brief Suspend scheduler activity 00230 **/ 00231 00232 void osSuspendAllTasks(void) 00233 { 00234 //Make sure the operating system is running 00235 if(running) 00236 { 00237 //Suspend all tasks 00238 tsk_lock(); 00239 } 00240 } 00241 00242 00243 /** 00244 * @brief Resume scheduler activity 00245 **/ 00246 00247 void osResumeAllTasks(void) 00248 { 00249 //Make sure the operating system is running 00250 if(running) 00251 { 00252 //Resume all tasks 00253 tsk_unlock(); 00254 } 00255 } 00256 00257 00258 /** 00259 * @brief Create an event object 00260 * @param[in] event Pointer to the event object 00261 * @return The function returns TRUE if the event object was successfully 00262 * created. Otherwise, FALSE is returned 00263 **/ 00264 00265 bool_t osCreateEvent(OsEvent *event) 00266 { 00267 //Initialize the event object 00268 os_sem_init(event, 0); 00269 00270 //Event successfully created 00271 return TRUE; 00272 } 00273 00274 00275 /** 00276 * @brief Delete an event object 00277 * @param[in] event Pointer to the event object 00278 **/ 00279 00280 void osDeleteEvent(OsEvent *event) 00281 { 00282 //No resource to release 00283 } 00284 00285 00286 /** 00287 * @brief Set the specified event object to the signaled state 00288 * @param[in] event Pointer to the event object 00289 **/ 00290 00291 void osSetEvent(OsEvent *event) 00292 { 00293 //Set the specified event to the signaled state 00294 os_sem_send(event); 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 OS_RESULT res; 00306 00307 //Force the specified event to the nonsignaled state 00308 do 00309 { 00310 //Decrement the semaphore's count by one 00311 res = os_sem_wait(event, 0); 00312 00313 //Check status 00314 } while(res == OS_R_OK); 00315 } 00316 00317 00318 /** 00319 * @brief Wait until the specified event is in the signaled state 00320 * @param[in] event Pointer to the event object 00321 * @param[in] timeout Timeout interval 00322 * @return The function returns TRUE if the state of the specified object is 00323 * signaled. FALSE is returned if the timeout interval elapsed 00324 **/ 00325 00326 bool_t osWaitForEvent(OsEvent *event, systime_t timeout) 00327 { 00328 uint16_t n; 00329 OS_RESULT res; 00330 00331 //Wait until the specified event is in the signaled 00332 //state or the timeout interval elapses 00333 if(timeout == INFINITE_DELAY) 00334 { 00335 //Infinite timeout period 00336 res = os_sem_wait(event, 0xFFFF); 00337 } 00338 else 00339 { 00340 //Convert milliseconds to system ticks 00341 timeout = OS_MS_TO_SYSTICKS(timeout); 00342 00343 //Loop until the assigned time period has elapsed 00344 do 00345 { 00346 //The timeout value cannot be higher than 0xFFFE... 00347 n = MIN(timeout, 0xFFFE); 00348 //Wait for the specified time interval 00349 res = os_sem_wait(event, n); 00350 //Decrement timeout value 00351 timeout -= n; 00352 00353 //Check timeout value 00354 } while(res == OS_R_TMO && timeout > 0); 00355 } 00356 00357 //Check whether the specified event is set 00358 if(res == OS_R_OK || res == OS_R_SEM) 00359 { 00360 //Force the event back to the nonsignaled state 00361 do 00362 { 00363 //Decrement the semaphore's count by one 00364 res = os_sem_wait(event, 0); 00365 00366 //Check status 00367 } while(res == OS_R_OK); 00368 00369 //The specified event is in the signaled state 00370 return TRUE; 00371 } 00372 else 00373 { 00374 //The timeout interval elapsed 00375 return FALSE; 00376 } 00377 } 00378 00379 00380 /** 00381 * @brief Set an event object to the signaled state from an interrupt service routine 00382 * @param[in] event Pointer to the event object 00383 * @return TRUE if setting the event to signaled state caused a task to unblock 00384 * and the unblocked task has a priority higher than the currently running task 00385 **/ 00386 00387 bool_t osSetEventFromIsr(OsEvent *event) 00388 { 00389 //Set the specified event to the signaled state 00390 isr_sem_send(event); 00391 00392 //The return value is not relevant 00393 return FALSE; 00394 } 00395 00396 00397 /** 00398 * @brief Create a semaphore object 00399 * @param[in] semaphore Pointer to the semaphore object 00400 * @param[in] count The maximum count for the semaphore object. This value 00401 * must be greater than zero 00402 * @return The function returns TRUE if the semaphore was successfully 00403 * created. Otherwise, FALSE is returned 00404 **/ 00405 00406 bool_t osCreateSemaphore(OsSemaphore *semaphore, uint_t count) 00407 { 00408 //Initialize the semaphore object 00409 os_sem_init(semaphore, count); 00410 00411 //Semaphore successfully created 00412 return TRUE; 00413 } 00414 00415 00416 /** 00417 * @brief Delete a semaphore object 00418 * @param[in] semaphore Pointer to the semaphore object 00419 **/ 00420 00421 void osDeleteSemaphore(OsSemaphore *semaphore) 00422 { 00423 //No resource to release 00424 } 00425 00426 00427 /** 00428 * @brief Wait for the specified semaphore to be available 00429 * @param[in] semaphore Pointer to the semaphore object 00430 * @param[in] timeout Timeout interval 00431 * @return The function returns TRUE if the semaphore is available. FALSE is 00432 * returned if the timeout interval elapsed 00433 **/ 00434 00435 bool_t osWaitForSemaphore(OsSemaphore *semaphore, systime_t timeout) 00436 { 00437 uint16_t n; 00438 OS_RESULT res; 00439 00440 //Wait until the semaphore is available or the timeout interval elapses 00441 if(timeout == INFINITE_DELAY) 00442 { 00443 //Infinite timeout period 00444 res = os_sem_wait(semaphore, 0xFFFF); 00445 } 00446 else 00447 { 00448 //Convert milliseconds to system ticks 00449 timeout = OS_MS_TO_SYSTICKS(timeout); 00450 00451 //Loop until the assigned time period has elapsed 00452 do 00453 { 00454 //The timeout value cannot be higher than 0xFFFE... 00455 n = MIN(timeout, 0xFFFE); 00456 //Wait for the specified time interval 00457 res = os_sem_wait(semaphore, n); 00458 //Decrement timeout value 00459 timeout -= n; 00460 00461 //Check timeout value 00462 } while(res == OS_R_TMO && timeout > 0); 00463 } 00464 00465 //Check whether the specified semaphore is available 00466 if(res == OS_R_OK || res == OS_R_SEM) 00467 return TRUE; 00468 else 00469 return FALSE; 00470 } 00471 00472 00473 /** 00474 * @brief Release the specified semaphore object 00475 * @param[in] semaphore Pointer to the semaphore object 00476 **/ 00477 00478 void osReleaseSemaphore(OsSemaphore *semaphore) 00479 { 00480 //Release the semaphore 00481 os_sem_send(semaphore); 00482 } 00483 00484 00485 /** 00486 * @brief Create a mutex object 00487 * @param[in] mutex Pointer to the mutex object 00488 * @return The function returns TRUE if the mutex was successfully 00489 * created. Otherwise, FALSE is returned 00490 **/ 00491 00492 bool_t osCreateMutex(OsMutex *mutex) 00493 { 00494 //Initialize the mutex object 00495 os_mut_init(mutex); 00496 00497 //Mutex successfully created 00498 return TRUE; 00499 } 00500 00501 00502 /** 00503 * @brief Delete a mutex object 00504 * @param[in] mutex Pointer to the mutex object 00505 **/ 00506 00507 void osDeleteMutex(OsMutex *mutex) 00508 { 00509 //No resource to release 00510 } 00511 00512 00513 /** 00514 * @brief Acquire ownership of the specified mutex object 00515 * @param[in] mutex A handle to the mutex object 00516 **/ 00517 00518 void osAcquireMutex(OsMutex *mutex) 00519 { 00520 //Obtain ownership of the mutex object 00521 os_mut_wait(mutex, 0xFFFF); 00522 } 00523 00524 00525 /** 00526 * @brief Release ownership of the specified mutex object 00527 * @param[in] mutex A handle to the mutex object 00528 **/ 00529 00530 void osReleaseMutex(OsMutex *mutex) 00531 { 00532 //Release ownership of the mutex object 00533 os_mut_release(mutex); 00534 } 00535 00536 00537 /** 00538 * @brief Retrieve system time 00539 * @return Number of milliseconds elapsed since the system was last started 00540 **/ 00541 00542 systime_t osGetSystemTime(void) 00543 { 00544 systime_t time; 00545 00546 //Get current tick count 00547 time = os_time_get(); 00548 00549 //Convert system ticks to milliseconds 00550 return OS_SYSTICKS_TO_MS(time); 00551 } 00552 00553 00554 /** 00555 * @brief Allocate a memory block 00556 * @param[in] size Bytes to allocate 00557 * @return A pointer to the allocated memory block or NULL if 00558 * there is insufficient memory available 00559 **/ 00560 00561 void *osAllocMem(size_t size) 00562 { 00563 void *p; 00564 00565 //Enter critical section 00566 osSuspendAllTasks(); 00567 //Allocate a memory block 00568 p = malloc(size); 00569 //Leave critical section 00570 osResumeAllTasks(); 00571 00572 //Debug message 00573 TRACE_DEBUG("Allocating %u bytes at 0x%08X\r\n", size, (uint_t) p); 00574 00575 //Return a pointer to the newly allocated memory block 00576 return p; 00577 } 00578 00579 00580 /** 00581 * @brief Release a previously allocated memory block 00582 * @param[in] p Previously allocated memory block to be freed 00583 **/ 00584 00585 void osFreeMem(void *p) 00586 { 00587 //Make sure the pointer is valid 00588 if(p != NULL) 00589 { 00590 //Debug message 00591 TRACE_DEBUG("Freeing memory at 0x%08X\r\n", (uint_t) p); 00592 00593 //Enter critical section 00594 osSuspendAllTasks(); 00595 //Free memory block 00596 free(p); 00597 //Leave critical section 00598 osResumeAllTasks(); 00599 } 00600 } 00601
Generated on Tue Jul 12 2022 17:10:15 by
