os_port_zephyr.c
Go to the documentation of this file.
1 /**
2  * @file os_port_zephyr.c
3  * @brief RTOS abstraction layer (Zephyr)
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 "os_port.h"
36 #include "os_port_zephyr.h"
37 #include "debug.h"
38 
39 //Default task parameters
41 {
42  NULL, //Task control block
43  NULL, //Stack
44  0, //Size of the stack
45  CONFIG_NUM_PREEMPT_PRIORITIES - 1 //Task priority
46 };
47 
48 
49 /**
50  * @brief Kernel initialization
51  **/
52 
53 void osInitKernel(void)
54 {
55  //Not implemented
56 }
57 
58 
59 /**
60  * @brief Start kernel
61  **/
62 
63 void osStartKernel(void)
64 {
65  //Not implemented
66 }
67 
68 
69 /**
70  * @brief Create a task
71  * @param[in] name NULL-terminated string identifying the task
72  * @param[in] taskCode Pointer to the task entry function
73  * @param[in] arg Argument passed to the task function
74  * @param[in] params Task parameters
75  * @return Task identifier referencing the newly created task
76  **/
77 
78 OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode, void *arg,
79  const OsTaskParameters *params)
80 {
81  k_tid_t tid;
82 
83  //Check parameters
84  if(params->tcb != NULL && params->stack != NULL)
85  {
86  //Create a new thread
87  tid = k_thread_create(params->tcb, params->stack, params->stackSize,
88  (k_thread_entry_t) taskCode, arg, NULL, NULL, params->priority, 0,
89  K_NO_WAIT);
90 
91  //Check whether the thread was successfully created
92  if(tid != OS_INVALID_TASK_ID)
93  {
94  //Set current thread name
95  k_thread_name_set(tid, name);
96  }
97  }
98  else
99  {
100  //Invalid parameters
101  tid = OS_INVALID_TASK_ID;
102  }
103 
104  //Return the handle referencing the newly created thread
105  return (OsTaskId) tid;
106 }
107 
108 
109 /**
110  * @brief Delete a task
111  * @param[in] taskId Task identifier referencing the task to be deleted
112  **/
113 
114 void osDeleteTask(OsTaskId taskId)
115 {
116  k_tid_t tid;
117 
118  //Delete the currently running thread?
119  if(taskId == OS_SELF_TASK_ID)
120  {
121  tid = k_current_get();
122  }
123  else
124  {
125  tid = (k_tid_t) taskId;
126  }
127 
128  //Abort the thread
129  k_thread_abort(tid);
130 }
131 
132 
133 /**
134  * @brief Delay routine
135  * @param[in] delay Amount of time for which the calling task should block
136  **/
137 
139 {
140  //Put the current thread to sleep
141  k_sleep(K_MSEC(delay));
142 }
143 
144 
145 /**
146  * @brief Yield control to the next task
147  **/
148 
149 void osSwitchTask(void)
150 {
151  //Wake up a sleeping thread
152  k_yield();
153 }
154 
155 
156 /**
157  * @brief Suspend scheduler activity
158  **/
159 
161 {
162  //Lock the scheduler
163  k_sched_lock();
164 }
165 
166 
167 /**
168  * @brief Resume scheduler activity
169  **/
170 
172 {
173  //Unlock the scheduler
174  k_sched_unlock();
175 }
176 
177 
178 /**
179  * @brief Create an event object
180  * @param[in] event Pointer to the event object
181  * @return The function returns TRUE if the event object was successfully
182  * created. Otherwise, FALSE is returned
183  **/
184 
186 {
187  int err;
188 
189  //Create a binary semaphore
190  err = k_sem_init(event, 0, 1);
191 
192  //Check whether the semaphore was successfully created
193  if(err)
194  {
195  return FALSE;
196  }
197  else
198  {
199  return TRUE;
200  }
201 }
202 
203 
204 /**
205  * @brief Delete an event object
206  * @param[in] event Pointer to the event object
207  **/
208 
209 void osDeleteEvent(OsEvent *event)
210 {
211  //No resource to release
212 }
213 
214 
215 /**
216  * @brief Set the specified event object to the signaled state
217  * @param[in] event Pointer to the event object
218  **/
219 
220 void osSetEvent(OsEvent *event)
221 {
222  //Set the specified event to the signaled state
223  k_sem_give(event);
224 }
225 
226 
227 /**
228  * @brief Set the specified event object to the nonsignaled state
229  * @param[in] event Pointer to the event object
230  **/
231 
232 void osResetEvent(OsEvent *event)
233 {
234  //Force the specified event to the nonsignaled state
235  k_sem_reset(event);
236 }
237 
238 
239 /**
240  * @brief Wait until the specified event is in the signaled state
241  * @param[in] event Pointer to the event object
242  * @param[in] timeout Timeout interval
243  * @return The function returns TRUE if the state of the specified object is
244  * signaled. FALSE is returned if the timeout interval elapsed
245  **/
246 
248 {
249  int err;
250 
251  //Wait until the specified event is in the signaled state or the timeout
252  //interval elapses
253  if(timeout == 0)
254  {
255  //Non-blocking call
256  err = k_sem_take(event, K_NO_WAIT);
257  }
258  else if(timeout == INFINITE_DELAY)
259  {
260  //Infinite timeout period
261  err = k_sem_take(event, K_FOREVER);
262  }
263  else
264  {
265  //Wait until the specified event becomes set
266  err = k_sem_take(event, K_MSEC(timeout));
267  }
268 
269  //Check whether the specified event is set
270  if(err)
271  {
272  return FALSE;
273  }
274  else
275  {
276  return TRUE;
277  }
278 }
279 
280 
281 /**
282  * @brief Set an event object to the signaled state from an interrupt service routine
283  * @param[in] event Pointer to the event object
284  * @return TRUE if setting the event to signaled state caused a task to unblock
285  * and the unblocked task has a priority higher than the currently running task
286  **/
287 
289 {
290  //Set the specified event to the signaled state
291  k_sem_give(event);
292 
293  //The return value is not relevant
294  return FALSE;
295 }
296 
297 
298 /**
299  * @brief Create a semaphore object
300  * @param[in] semaphore Pointer to the semaphore object
301  * @param[in] count The maximum count for the semaphore object. This value
302  * must be greater than zero
303  * @return The function returns TRUE if the semaphore was successfully
304  * created. Otherwise, FALSE is returned
305  **/
306 
308 {
309  int err;
310 
311  //Initialize the semaphore object
312  err = k_sem_init(semaphore, count, count);
313 
314  //Check whether the semaphore was successfully created
315  if(err)
316  {
317  return FALSE;
318  }
319  else
320  {
321  return TRUE;
322  }
323 }
324 
325 
326 /**
327  * @brief Delete a semaphore object
328  * @param[in] semaphore Pointer to the semaphore object
329  **/
330 
332 {
333  //No resource to release
334 }
335 
336 
337 /**
338  * @brief Wait for the specified semaphore to be available
339  * @param[in] semaphore Pointer to the semaphore object
340  * @param[in] timeout Timeout interval
341  * @return The function returns TRUE if the semaphore is available. FALSE is
342  * returned if the timeout interval elapsed
343  **/
344 
346 {
347  int err;
348 
349  //Wait until the semaphore is available or the timeout interval elapses
350  if(timeout == 0)
351  {
352  //Non-blocking call
353  err = k_sem_take(semaphore, K_NO_WAIT);
354  }
355  else if(timeout == INFINITE_DELAY)
356  {
357  //Infinite timeout period
358  err = k_sem_take(semaphore, K_FOREVER);
359  }
360  else
361  {
362  //Wait until the specified semaphore becomes available
363  err = k_sem_take(semaphore, K_MSEC(timeout));
364  }
365 
366  //Check whether the specified semaphore is available
367  if(err)
368  {
369  return FALSE;
370  }
371  else
372  {
373  return TRUE;
374  }
375 }
376 
377 
378 /**
379  * @brief Release the specified semaphore object
380  * @param[in] semaphore Pointer to the semaphore object
381  **/
382 
384 {
385  //Give the semaphore
386  k_sem_give(semaphore);
387 }
388 
389 
390 /**
391  * @brief Create a mutex object
392  * @param[in] mutex Pointer to the mutex object
393  * @return The function returns TRUE if the mutex was successfully
394  * created. Otherwise, FALSE is returned
395  **/
396 
398 {
399  int err;
400 
401  //Initialize the mutex object
402  err = k_mutex_init(mutex);
403 
404  //Check whether the mutex was successfully created
405  if(err)
406  {
407  return FALSE;
408  }
409  else
410  {
411  return TRUE;
412  }
413 }
414 
415 
416 /**
417  * @brief Delete a mutex object
418  * @param[in] mutex Pointer to the mutex object
419  **/
420 
421 void osDeleteMutex(OsMutex *mutex)
422 {
423  //No resource to release
424 }
425 
426 
427 /**
428  * @brief Acquire ownership of the specified mutex object
429  * @param[in] mutex Pointer to the mutex object
430  **/
431 
433 {
434  //Lock the mutex
435  k_mutex_lock(mutex, K_FOREVER);
436 }
437 
438 
439 /**
440  * @brief Release ownership of the specified mutex object
441  * @param[in] mutex Pointer to the mutex object
442  **/
443 
445 {
446  //Unlock the mutex
447  k_mutex_unlock(mutex);
448 }
449 
450 
451 /**
452  * @brief Retrieve system time
453  * @return Number of milliseconds elapsed since the system was last started
454  **/
455 
457 {
458  //Get the elapsed time since the system booted, in milliseconds
459  return (systime_t) k_uptime_get();
460 }
461 
462 
463 /**
464  * @brief Retrieve 64-bit system time
465  * @return Number of milliseconds elapsed since the system was last started
466  **/
467 
468 uint64_t osGetSystemTime64(void)
469 {
470  //Get the elapsed time since the system booted, in milliseconds
471  return (uint64_t) k_uptime_get();
472 }
473 
474 
475 /**
476  * @brief Allocate a memory block
477  * @param[in] size Bytes to allocate
478  * @return A pointer to the allocated memory block or NULL if
479  * there is insufficient memory available
480  **/
481 
482 __weak_func void *osAllocMem(size_t size)
483 {
484  void *p;
485 
486  //Enter critical section
488  //Allocate a memory block
489  p = k_malloc(size);
490  //Leave critical section
492 
493  //Debug message
494  TRACE_DEBUG("Allocating %" PRIuSIZE " bytes at 0x%08" PRIXPTR "\r\n",
495  size, (uintptr_t) p);
496 
497  //Return a pointer to the newly allocated memory block
498  return p;
499 }
500 
501 
502 /**
503  * @brief Release a previously allocated memory block
504  * @param[in] p Previously allocated memory block to be freed
505  **/
506 
507 __weak_func void osFreeMem(void *p)
508 {
509  //Make sure the pointer is valid
510  if(p != NULL)
511  {
512  //Debug message
513  TRACE_DEBUG("Freeing memory at 0x%08" PRIXPTR "\r\n", (uintptr_t) p);
514 
515  //Enter critical section
517  //Free memory block
518  k_free(p);
519  //Leave critical section
521  }
522 }
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
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_SELF_TASK_ID
#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
uint64_t osGetSystemTime64(void)
Retrieve 64-bit system time.
__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.
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.
void osInitKernel(void)
Kernel initialization.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
RTOS abstraction layer (Zephyr)
char_t name[]
Event object.
Mutex object.
Semaphore object.
Task parameters.