os_port_embos.c
Go to the documentation of this file.
1 /**
2  * @file os_port_embos.c
3  * @brief RTOS abstraction layer (Segger embOS)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 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 2.4.0
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 <string.h>
36 #include "os_port.h"
37 #include "os_port_embos.h"
38 #include "debug.h"
39 
40 //Default task parameters
42 {
43  NULL, //Task control block
44  NULL, //Stack
45  0, //Size of the stack
46  1 //Task priority
47 };
48 
49 
50 /**
51  * @brief Kernel initialization
52  **/
53 
54 void osInitKernel(void)
55 {
56  //Disable interrupts
57  OS_IncDI();
58  //Kernel initialization
59  OS_InitKern();
60  //Hardware initialization
61  OS_InitHW();
62 }
63 
64 
65 /**
66  * @brief Start kernel
67  **/
68 
69 void osStartKernel(void)
70 {
71  //Start the scheduler
72  OS_Start();
73 }
74 
75 
76 /**
77  * @brief Create a task
78  * @param[in] name NULL-terminated string identifying the task
79  * @param[in] taskCode Pointer to the task entry function
80  * @param[in] arg Argument passed to the task function
81  * @param[in] params Task parameters
82  * @return Task identifier referencing the newly created task
83  **/
84 
85 OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode, void *arg,
86  const OsTaskParameters *params)
87 {
88  OsTaskId taskId;
89 
90  //Check parameters
91  if(params->tcb != NULL && params->stack != NULL)
92  {
93  //Create a new task
94  OS_CreateTaskEx(params->tcb, name, params->priority, taskCode,
95  params->stack, params->stackSize * sizeof(uint32_t), 1, arg);
96 
97  //The task was successfully created
98  taskId = (OsTaskId) params->tcb;
99  }
100  else
101  {
102  //Invalid parameters
103  taskId = OS_INVALID_TASK_ID;
104  }
105 
106  //Return the handle referencing the newly created task
107  return taskId;
108 }
109 
110 
111 /**
112  * @brief Delete a task
113  * @param[in] taskId Task identifier referencing the task to be deleted
114  **/
115 
116 void osDeleteTask(OsTaskId taskId)
117 {
118  //Delete the specified task
119  OS_TerminateTask((OS_TASK *) taskId);
120 }
121 
122 
123 /**
124  * @brief Delay routine
125  * @param[in] delay Amount of time for which the calling task should block
126  **/
127 
129 {
130  //Delay the task for the specified duration
131  OS_Delay(OS_MS_TO_SYSTICKS(delay));
132 }
133 
134 
135 /**
136  * @brief Yield control to the next task
137  **/
138 
139 void osSwitchTask(void)
140 {
141  //Not implemented
142 }
143 
144 
145 /**
146  * @brief Suspend scheduler activity
147  **/
148 
150 {
151  //Make sure the operating system is running
152  if(OS_IsRunning())
153  {
154  //Suspend scheduler activity
155  OS_SuspendAllTasks();
156  }
157 }
158 
159 
160 /**
161  * @brief Resume scheduler activity
162  **/
163 
165 {
166  //Make sure the operating system is running
167  if(OS_IsRunning())
168  {
169  //Resume scheduler activity
170  OS_ResumeAllSuspendedTasks();
171  }
172 }
173 
174 
175 /**
176  * @brief Create an event object
177  * @param[in] event Pointer to the event object
178  * @return The function returns TRUE if the event object was successfully
179  * created. Otherwise, FALSE is returned
180  **/
181 
183 {
184  //Create an event object
185  OS_EVENT_Create(event);
186 
187  //The event object was successfully created
188  return TRUE;
189 }
190 
191 
192 /**
193  * @brief Delete an event object
194  * @param[in] event Pointer to the event object
195  **/
196 
197 void osDeleteEvent(OsEvent *event)
198 {
199  //Make sure the operating system is running
200  if(OS_IsRunning())
201  {
202  //Properly dispose the event object
203  OS_EVENT_Delete(event);
204  }
205 }
206 
207 
208 /**
209  * @brief Set the specified event object to the signaled state
210  * @param[in] event Pointer to the event object
211  **/
212 
213 void osSetEvent(OsEvent *event)
214 {
215  //Set the specified event to the signaled state
216  OS_EVENT_Set(event);
217 }
218 
219 
220 /**
221  * @brief Set the specified event object to the nonsignaled state
222  * @param[in] event Pointer to the event object
223  **/
224 
225 void osResetEvent(OsEvent *event)
226 {
227  //Force the specified event to the nonsignaled state
228  OS_EVENT_Reset(event);
229 }
230 
231 
232 /**
233  * @brief Wait until the specified event is in the signaled state
234  * @param[in] event Pointer to the event object
235  * @param[in] timeout Timeout interval
236  * @return The function returns TRUE if the state of the specified object is
237  * signaled. FALSE is returned if the timeout interval elapsed
238  **/
239 
241 {
242  bool_t ret;
243 
244  //Wait until the specified event is in the signaled state or the timeout
245  //interval elapses
246  if(timeout == 0)
247  {
248  //Non-blocking call
249  ret = OS_EVENT_Get(event);
250  }
251  else if(timeout == INFINITE_DELAY)
252  {
253  //Infinite timeout period
254  OS_EVENT_Wait(event);
255  ret = TRUE;
256  }
257  else
258  {
259  //Wait until the specified event becomes set
260  ret = !OS_EVENT_WaitTimed(event, OS_MS_TO_SYSTICKS(timeout));
261  }
262 
263  //The return value specifies whether the event is set
264  return ret;
265 }
266 
267 
268 /**
269  * @brief Set an event object to the signaled state from an interrupt service routine
270  * @param[in] event Pointer to the event object
271  * @return TRUE if setting the event to signaled state caused a task to unblock
272  * and the unblocked task has a priority higher than the currently running task
273  **/
274 
276 {
277  //Set the specified event to the signaled state
278  OS_EVENT_Set(event);
279 
280  //The return value is not relevant
281  return FALSE;
282 }
283 
284 
285 /**
286  * @brief Create a semaphore object
287  * @param[in] semaphore Pointer to the semaphore object
288  * @param[in] count The maximum count for the semaphore object. This value
289  * must be greater than zero
290  * @return The function returns TRUE if the semaphore was successfully
291  * created. Otherwise, FALSE is returned
292  **/
293 
295 {
296  //Create a semaphore
297  OS_CreateCSema(semaphore, count);
298 
299  //The event object was successfully created
300  return TRUE;
301 }
302 
303 
304 /**
305  * @brief Delete a semaphore object
306  * @param[in] semaphore Pointer to the semaphore object
307  **/
308 
310 {
311  //Make sure the operating system is running
312  if(OS_IsRunning())
313  {
314  //Properly dispose the specified semaphore
315  OS_DeleteCSema(semaphore);
316  }
317 }
318 
319 
320 /**
321  * @brief Wait for the specified semaphore to be available
322  * @param[in] semaphore Pointer to the semaphore object
323  * @param[in] timeout Timeout interval
324  * @return The function returns TRUE if the semaphore is available. FALSE is
325  * returned if the timeout interval elapsed
326  **/
327 
329 {
330  bool_t ret;
331 
332  //Wait until the semaphore is available or the timeout interval elapses
333  if(timeout == 0)
334  {
335  //Non-blocking call
336  ret = OS_CSemaRequest(semaphore);
337  }
338  else if(timeout == INFINITE_DELAY)
339  {
340  //Infinite timeout period
341  OS_WaitCSema(semaphore);
342  ret = TRUE;
343  }
344  else
345  {
346  //Wait until the specified semaphore becomes available
347  ret = OS_WaitCSemaTimed(semaphore, OS_MS_TO_SYSTICKS(timeout));
348  }
349 
350  //The return value specifies whether the semaphore is available
351  return ret;
352 }
353 
354 
355 /**
356  * @brief Release the specified semaphore object
357  * @param[in] semaphore Pointer to the semaphore object
358  **/
359 
361 {
362  //Release the semaphore
363  OS_SignalCSema(semaphore);
364 }
365 
366 
367 /**
368  * @brief Create a mutex object
369  * @param[in] mutex Pointer to the mutex object
370  * @return The function returns TRUE if the mutex was successfully
371  * created. Otherwise, FALSE is returned
372  **/
373 
375 {
376  //Create a mutex
377  OS_CreateRSema(mutex);
378 
379  //The mutex was successfully created
380  return TRUE;
381 }
382 
383 
384 /**
385  * @brief Delete a mutex object
386  * @param[in] mutex Pointer to the mutex object
387  **/
388 
389 void osDeleteMutex(OsMutex *mutex)
390 {
391  //Make sure the operating system is running
392  if(OS_IsRunning())
393  {
394  //Properly dispose the specified mutex
395  OS_DeleteRSema(mutex);
396  }
397 }
398 
399 
400 /**
401  * @brief Acquire ownership of the specified mutex object
402  * @param[in] mutex Pointer to the mutex object
403  **/
404 
406 {
407  //Obtain ownership of the mutex object
408  OS_Use(mutex);
409 }
410 
411 
412 /**
413  * @brief Release ownership of the specified mutex object
414  * @param[in] mutex Pointer to the mutex object
415  **/
416 
418 {
419  //Release ownership of the mutex object
420  OS_Unuse(mutex);
421 }
422 
423 
424 /**
425  * @brief Retrieve system time
426  * @return Number of milliseconds elapsed since the system was last started
427  **/
428 
430 {
431  systime_t time;
432 
433  //Get current tick count
434  time = OS_GetTime32();
435 
436  //Convert system ticks to milliseconds
437  return OS_SYSTICKS_TO_MS(time);
438 }
439 
440 
441 /**
442  * @brief Allocate a memory block
443  * @param[in] size Bytes to allocate
444  * @return A pointer to the allocated memory block or NULL if
445  * there is insufficient memory available
446  **/
447 
448 __weak_func void *osAllocMem(size_t size)
449 {
450  void *p;
451 
452  //Allocate a memory block
453  p = OS_malloc(size);
454 
455  //Debug message
456  TRACE_DEBUG("Allocating %" PRIuSIZE " bytes at 0x%08" PRIXPTR "\r\n",
457  size, (uintptr_t) p);
458 
459  //Return a pointer to the newly allocated memory block
460  return p;
461 }
462 
463 
464 /**
465  * @brief Release a previously allocated memory block
466  * @param[in] p Previously allocated memory block to be freed
467  **/
468 
469 __weak_func void osFreeMem(void *p)
470 {
471  //Make sure the pointer is valid
472  if(p != NULL)
473  {
474  //Debug message
475  TRACE_DEBUG("Freeing memory at 0x%08" PRIXPTR "\r\n", (uintptr_t) p);
476 
477  //Free memory block
478  OS_free(p);
479  }
480 }
unsigned int uint_t
Definition: compiler_port.h:50
#define PRIuSIZE
char char_t
Definition: compiler_port.h:48
int bool_t
Definition: compiler_port.h:53
Debugging facilities.
#define TRACE_DEBUG(...)
Definition: debug.h:107
uint32_t time
uint8_t p
Definition: ndp.h:300
RTOS abstraction layer.
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
#define INFINITE_DELAY
Definition: os_port.h:75
void(* OsTaskCode)(void *arg)
Task routine.
#define OS_SYSTICKS_TO_MS(n)
#define OS_MS_TO_SYSTICKS(n)
#define OS_INVALID_TASK_ID
uint32_t systime_t
System time.
thread_t * OsTaskId
Task identifier.
void osSwitchTask(void)
Yield control to the next task.
void osResumeAllTasks(void)
Resume scheduler activity.
bool_t osCreateMutex(OsMutex *mutex)
Create a mutex object.
bool_t osWaitForEvent(OsEvent *event, systime_t timeout)
Wait until the specified event is in the signaled state.
void osDeleteEvent(OsEvent *event)
Delete an event object.
void osDeleteMutex(OsMutex *mutex)
Delete a mutex object.
void osReleaseSemaphore(OsSemaphore *semaphore)
Release the specified semaphore object.
const OsTaskParameters OS_TASK_DEFAULT_PARAMS
Definition: os_port_embos.c:41
__weak_func void * osAllocMem(size_t size)
Allocate a memory block.
void osDeleteSemaphore(OsSemaphore *semaphore)
Delete a semaphore object.
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osDelayTask(systime_t delay)
Delay routine.
__weak_func void osFreeMem(void *p)
Release a previously allocated memory block.
bool_t osWaitForSemaphore(OsSemaphore *semaphore, systime_t timeout)
Wait for the specified semaphore to be available.
OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode, void *arg, const OsTaskParameters *params)
Create a task.
Definition: os_port_embos.c:85
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
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 osDeleteTask(OsTaskId taskId)
Delete a task.
bool_t osCreateSemaphore(OsSemaphore *semaphore, uint_t count)
Create a semaphore object.
systime_t osGetSystemTime(void)
Retrieve system time.
void osSuspendAllTasks(void)
Suspend scheduler activity.
bool_t osCreateEvent(OsEvent *event)
Create an event object.
void osStartKernel(void)
Start kernel.
Definition: os_port_embos.c:69
void osInitKernel(void)
Kernel initialization.
Definition: os_port_embos.c:54
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
RTOS abstraction layer (Segger embOS)
char_t name[]
Event object.
Mutex object.
Semaphore object.
Task parameters.