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