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