os_port_sys_bios.c
Go to the documentation of this file.
1 /**
2  * @file os_port_sys_bios.c
3  * @brief RTOS abstraction layer (SYS/BIOS)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.6
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL TRACE_LEVEL_OFF
31 
32 //Dependencies
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include "os_port.h"
36 #include "os_port_sys_bios.h"
37 #include "debug.h"
38 
39 //Variables
40 static bool_t running = FALSE;
41 
42 
43 /**
44  * @brief Kernel initialization
45  **/
46 
47 void osInitKernel(void)
48 {
49  //The scheduler is not running
50  running = FALSE;
51 }
52 
53 
54 /**
55  * @brief Start kernel
56  **/
57 
58 void osStartKernel(void)
59 {
60  //The scheduler is now running
61  running = TRUE;
62  //Start the scheduler
63  BIOS_start();
64 }
65 
66 
67 /**
68  * @brief Create a new task
69  * @param[in] name A name identifying the task
70  * @param[in] taskCode Pointer to the task entry function
71  * @param[in] param A pointer to a variable to be passed to the task
72  * @param[in] stackSize The initial size of the stack, in words
73  * @param[in] priority The priority at which the task should run
74  * @return If the function succeeds, the return value is a pointer to the
75  * new task. If the function fails, the return value is NULL
76  **/
77 
79  void *param, size_t stackSize, int_t priority)
80 {
81  Error_Block eb;
82  Task_Params taskParams;
83  Task_Handle task;
84 
85  //Initialize error block
86  Error_init(&eb);
87 
88  //Set parameters
89  Task_Params_init(&taskParams);
90  taskParams.arg0 = (UArg) param;
91  taskParams.stackSize = stackSize * sizeof(uint_t);
92  taskParams.priority = priority;
93 
94  //Create a new task
95  task = Task_create((Task_FuncPtr) taskCode, &taskParams, &eb);
96 
97  //Return a pointer to the newly created task
98  return task;
99 }
100 
101 
102 /**
103  * @brief Delete a task
104  * @param[in] task Pointer to the task to be deleted
105  **/
106 
107 void osDeleteTask(OsTask *task)
108 {
109  //Delete the specified task
110  Task_delete(&task);
111 }
112 
113 
114 /**
115  * @brief Delay routine
116  * @param[in] delay Amount of time for which the calling task should block
117  **/
118 
120 {
121  //Delay the task for the specified duration
122  Task_sleep(OS_MS_TO_SYSTICKS(delay));
123 }
124 
125 
126 /**
127  * @brief Yield control to the next task
128  **/
129 
130 void osSwitchTask(void)
131 {
132  //Force a context switch
133  Task_yield();
134 }
135 
136 
137 /**
138  * @brief Suspend scheduler activity
139  **/
140 
142 {
143  //Make sure the operating system is running
144  if(running)
145  {
146  //Disable the task scheduler
147  Task_disable();
148  }
149 }
150 
151 
152 /**
153  * @brief Resume scheduler activity
154  **/
155 
157 {
158  //Make sure the operating system is running
159  if(running)
160  {
161  //Enable the task scheduler
162  Task_enable();
163  }
164 }
165 
166 
167 /**
168  * @brief Create an event object
169  * @param[in] event Pointer to the event object
170  * @return The function returns TRUE if the event object was successfully
171  * created. Otherwise, FALSE is returned
172  **/
173 
175 {
176  //Create an event object
177  event->handle = Event_create(NULL, NULL);
178 
179  //Check whether the returned handle is valid
180  if(event->handle != NULL)
181  return TRUE;
182  else
183  return FALSE;
184 }
185 
186 
187 /**
188  * @brief Delete an event object
189  * @param[in] event Pointer to the event object
190  **/
191 
192 void osDeleteEvent(OsEvent *event)
193 {
194  //Make sure the handle is valid
195  if(event->handle != NULL)
196  {
197  //Properly dispose the event object
198  Event_delete(&event->handle);
199  }
200 }
201 
202 
203 /**
204  * @brief Set the specified event object to the signaled state
205  * @param[in] event Pointer to the event object
206  **/
207 
208 void osSetEvent(OsEvent *event)
209 {
210  //Set the specified event to the signaled state
211  Event_post(event->handle, Event_Id_00);
212 }
213 
214 
215 /**
216  * @brief Set the specified event object to the nonsignaled state
217  * @param[in] event Pointer to the event object
218  **/
219 
220 void osResetEvent(OsEvent *event)
221 {
222  //Force the specified event to the nonsignaled state
223  Event_pend(event->handle, Event_Id_00, Event_Id_NONE, BIOS_NO_WAIT);
224 }
225 
226 
227 /**
228  * @brief Wait until the specified event is in the signaled state
229  * @param[in] event Pointer to the event object
230  * @param[in] timeout Timeout interval
231  * @return The function returns TRUE if the state of the specified object is
232  * signaled. FALSE is returned if the timeout interval elapsed
233  **/
234 
236 {
237  Bool ret;
238 
239  //Wait until the specified event is in the signaled state
240  if(timeout == 0)
241  {
242  //Non-blocking call
243  ret = Event_pend(event->handle, Event_Id_00,
244  Event_Id_NONE, BIOS_NO_WAIT);
245  }
246  else if(timeout == INFINITE_DELAY)
247  {
248  //Infinite timeout period
249  ret = Event_pend(event->handle, Event_Id_00,
250  Event_Id_NONE, BIOS_WAIT_FOREVER);
251  }
252  else
253  {
254  //Wait for the specified time interval
255  ret = Event_pend(event->handle, Event_Id_00,
256  Event_Id_NONE, OS_MS_TO_SYSTICKS(timeout));
257  }
258 
259  //The return value tells whether the event is set
260  return ret;
261 }
262 
263 
264 /**
265  * @brief Set an event object to the signaled state from an interrupt service routine
266  * @param[in] event Pointer to the event object
267  * @return TRUE if setting the event to signaled state caused a task to unblock
268  * and the unblocked task has a priority higher than the currently running task
269  **/
270 
272 {
273  //Set the specified event to the signaled state
274  Event_post(event->handle, Event_Id_00);
275 
276  //The return value is not relevant
277  return FALSE;
278 }
279 
280 
281 /**
282  * @brief Create a semaphore object
283  * @param[in] semaphore Pointer to the semaphore object
284  * @param[in] count The maximum count for the semaphore object. This value
285  * must be greater than zero
286  * @return The function returns TRUE if the semaphore was successfully
287  * created. Otherwise, FALSE is returned
288  **/
289 
291 {
292  Semaphore_Params semaphoreParams;
293 
294  //Set parameters
295  Semaphore_Params_init(&semaphoreParams);
296  semaphoreParams.mode = Semaphore_Mode_COUNTING;
297 
298  //Create a semaphore
299  semaphore->handle = Semaphore_create(count, &semaphoreParams, NULL);
300 
301  //Check whether the returned handle is valid
302  if(semaphore->handle != NULL)
303  return TRUE;
304  else
305  return FALSE;
306 }
307 
308 
309 /**
310  * @brief Delete a semaphore object
311  * @param[in] semaphore Pointer to the semaphore object
312  **/
313 
315 {
316  //Make sure the handle is valid
317  if(semaphore->handle != NULL)
318  {
319  //Properly dispose the specified semaphore
320  Semaphore_delete(&semaphore->handle);
321  }
322 }
323 
324 
325 /**
326  * @brief Wait for the specified semaphore to be available
327  * @param[in] semaphore Pointer to the semaphore object
328  * @param[in] timeout Timeout interval
329  * @return The function returns TRUE if the semaphore is available. FALSE is
330  * returned if the timeout interval elapsed
331  **/
332 
334 {
335  Bool ret;
336 
337  //Wait until the specified semaphore becomes available
338  if(timeout == 0)
339  {
340  //Non-blocking call
341  ret = Semaphore_pend(semaphore->handle, BIOS_NO_WAIT);
342  }
343  else if(timeout == INFINITE_DELAY)
344  {
345  //Infinite timeout period
346  ret = Semaphore_pend(semaphore->handle, BIOS_WAIT_FOREVER);
347  }
348  else
349  {
350  //Wait for the specified time interval
351  ret = Semaphore_pend(semaphore->handle, OS_MS_TO_SYSTICKS(timeout));
352  }
353 
354  //The return value tells whether the semaphore is available
355  return ret;
356 }
357 
358 
359 /**
360  * @brief Release the specified semaphore object
361  * @param[in] semaphore Pointer to the semaphore object
362  **/
363 
365 {
366  //Release the semaphore
367  Semaphore_post(semaphore->handle);
368 }
369 
370 
371 /**
372  * @brief Create a mutex object
373  * @param[in] mutex Pointer to the mutex object
374  * @return The function returns TRUE if the mutex was successfully
375  * created. Otherwise, FALSE is returned
376  **/
377 
379 {
380  Semaphore_Params semaphoreParams;
381 
382  //Set parameters
383  Semaphore_Params_init(&semaphoreParams);
384  semaphoreParams.mode = Semaphore_Mode_BINARY_PRIORITY;
385 
386  //Create a mutex
387  mutex->handle = Semaphore_create(1, &semaphoreParams, NULL);
388 
389  //Check whether the returned handle is valid
390  if(mutex->handle != NULL)
391  return TRUE;
392  else
393  return FALSE;
394 }
395 
396 
397 /**
398  * @brief Delete a mutex object
399  * @param[in] mutex Pointer to the mutex object
400  **/
401 
402 void osDeleteMutex(OsMutex *mutex)
403 {
404  //Make sure the handle is valid
405  if(mutex->handle != NULL)
406  {
407  //Properly dispose the specified mutex
408  Semaphore_delete(&mutex->handle);
409  }
410 }
411 
412 
413 /**
414  * @brief Acquire ownership of the specified mutex object
415  * @param[in] mutex Pointer to the mutex object
416  **/
417 
419 {
420  //Obtain ownership of the mutex object
421  Semaphore_pend(mutex->handle, BIOS_WAIT_FOREVER);
422 }
423 
424 
425 /**
426  * @brief Release ownership of the specified mutex object
427  * @param[in] mutex Pointer to the mutex object
428  **/
429 
431 {
432  //Release ownership of the mutex object
433  Semaphore_post(mutex->handle);
434 }
435 
436 
437 /**
438  * @brief Retrieve system time
439  * @return Number of milliseconds elapsed since the system was last started
440  **/
441 
443 {
444  systime_t time;
445 
446  //Get current tick count
447  time = Clock_getTicks();
448 
449  //Convert system ticks to milliseconds
450  return OS_SYSTICKS_TO_MS(time);
451 }
452 
453 
454 /**
455  * @brief Allocate a memory block
456  * @param[in] size Bytes to allocate
457  * @return A pointer to the allocated memory block or NULL if
458  * there is insufficient memory available
459  **/
460 
461 void *osAllocMem(size_t size)
462 {
463  void *p;
464 
465  //Enter critical section
467  //Allocate a memory block
468  p = malloc(size);
469  //Leave critical section
471 
472  //Debug message
473  TRACE_DEBUG("Allocating %" PRIuSIZE " bytes at 0x%08" PRIXPTR "\r\n", size, (uintptr_t) p);
474 
475  //Return a pointer to the newly allocated memory block
476  return p;
477 }
478 
479 
480 /**
481  * @brief Release a previously allocated memory block
482  * @param[in] p Previously allocated memory block to be freed
483  **/
484 
485 void osFreeMem(void *p)
486 {
487  //Make sure the pointer is valid
488  if(p != NULL)
489  {
490  //Debug message
491  TRACE_DEBUG("Freeing memory at 0x%08" PRIXPTR "\r\n", (uintptr_t) p);
492 
493  //Enter critical section
495  //Free memory block
496  free(p);
497  //Leave critical section
499  }
500 }
int bool_t
Definition: compiler_port.h:49
signed int int_t
Definition: compiler_port.h:44
bool_t osCreateSemaphore(OsSemaphore *semaphore, uint_t count)
Create a semaphore object.
SemaphoreHandle_t handle
uint8_t p
Definition: ndp.h:298
void osSwitchTask(void)
Yield control to the next task.
#define TRUE
Definition: os_port.h:50
Event object.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
char_t name[]
Semaphore object.
#define FALSE
Definition: os_port.h:46
bool_t osWaitForEvent(OsEvent *event, systime_t timeout)
Wait until the specified event is in the signaled state.
RTOS abstraction layer (SYS/BIOS)
bool_t osCreateMutex(OsMutex *mutex)
Create a mutex object.
Task object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
#define OS_SYSTICKS_TO_MS(n)
void osResetEvent(OsEvent *event)
Set the specified event object to the nonsignaled state.
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
void osInitKernel(void)
Kernel initialization.
#define OS_MS_TO_SYSTICKS(n)
void osDeleteSemaphore(OsSemaphore *semaphore)
Delete a semaphore object.
void osReleaseSemaphore(OsSemaphore *semaphore)
Release the specified semaphore object.
systime_t osGetSystemTime(void)
Retrieve system time.
void osDeleteEvent(OsEvent *event)
Delete an event object.
Mutex object.
#define TRACE_DEBUG(...)
Definition: debug.h:106
char char_t
Definition: compiler_port.h:43
uint32_t time
void osDelayTask(systime_t delay)
Delay routine.
SemaphoreHandle_t handle
void(* OsTaskCode)(void *param)
Task routine.
bool_t osWaitForSemaphore(OsSemaphore *semaphore, systime_t timeout)
Wait for the specified semaphore to be available.
void osSuspendAllTasks(void)
Suspend scheduler activity.
void osFreeMem(void *p)
Release a previously allocated memory block.
bool_t osCreateEvent(OsEvent *event)
Create an event object.
OsTask * osCreateTask(const char_t *name, OsTaskCode taskCode, void *param, size_t stackSize, int_t priority)
Create a new task.
void osDeleteMutex(OsMutex *mutex)
Delete a mutex object.
#define PRIuSIZE
Definition: compiler_port.h:78
unsigned int uint_t
Definition: compiler_port.h:45
void osDeleteTask(OsTask *task)
Delete a task.
uint16_t priority
Definition: dns_common.h:221
RTOS abstraction layer.
void osResumeAllTasks(void)
Resume scheduler activity.
uint32_t systime_t
Definition: compiler_port.h:46
void * osAllocMem(size_t size)
Allocate a memory block.
Debugging facilities.
#define INFINITE_DELAY
Definition: os_port.h:74
void osStartKernel(void)
Start kernel.
SemaphoreHandle_t handle