os_port_safertos.c
Go to the documentation of this file.
1 /**
2  * @file os_port_safertos.c
3  * @brief RTOS abstraction layer (SafeRTOS)
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 <string.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include "os_port.h"
37 #include "os_port_safertos.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  taskIDLE_PRIORITY + 1, //Task priority
47 };
48 
49 //Declaration of functions
50 extern portBaseType xInitializeScheduler(void);
51 
52 
53 /**
54  * @brief Kernel initialization
55  **/
56 
57 void osInitKernel(void)
58 {
59  //Initialize kernel
61 }
62 
63 
64 /**
65  * @brief Start kernel
66  **/
67 
68 void osStartKernel(void)
69 {
70  //Start the scheduler
71  xTaskStartScheduler(pdTRUE);
72 }
73 
74 
75 /**
76  * @brief Create a task
77  * @param[in] name NULL-terminated string identifying the task
78  * @param[in] taskCode Pointer to the task entry function
79  * @param[in] arg Argument passed to the task function
80  * @param[in] params Task parameters
81  * @return Task identifier referencing the newly created task
82  **/
83 
84 __weak_func OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode,
85  void *arg, const OsTaskParameters *params)
86 {
87  portBaseType status;
88  portTaskHandleType handle;
89  xTaskParameters taskParams;
90 
91  //Check parameters
92  if(params->tcb != NULL && params->stack != NULL)
93  {
94  //Initialize task parameters
95  memset(&taskParams, 0, sizeof(taskParams));
96 
97  //Set task parameters
98  taskParams.pvTaskCode = (pdTASK_CODE) taskCode;
99  taskParams.pcTaskName = name;
100  taskParams.pxTCB = params->tcb;
101  taskParams.pcStackBuffer = params->stack;
102  taskParams.ulStackDepthBytes = params->stackSize;
103  taskParams.pvParameters = arg;
104  taskParams.uxPriority = params->priority;
105  taskParams.xUsingFPU = pdTRUE;
106  taskParams.xMPUParameters.uxPrivilegeLevel = mpuPRIVILEGED_TASK;
107 
108  //Create a new task
109  status = xTaskCreate(&taskParams, &handle);
110 
111  //Failed to create task?
112  if(status != pdPASS)
113  {
114  handle = OS_INVALID_TASK_ID;
115  }
116  }
117  else
118  {
119  //Invalid parameters
120  handle = OS_INVALID_TASK_ID;
121  }
122 
123  //Return the handle referencing the newly created task
124  return (OsTaskId) handle;
125 }
126 
127 
128 /**
129  * @brief Delete a task
130  * @param[in] taskId Task identifier referencing the task to be deleted
131  **/
132 
133 void osDeleteTask(OsTaskId taskId)
134 {
135  //Delete the specified task
136  xTaskDelete((portTaskHandleType) taskId);
137 }
138 
139 
140 /**
141  * @brief Delay routine
142  * @param[in] delay Amount of time for which the calling task should block
143  **/
144 
146 {
147  //Delay the task for the specified duration
148  xTaskDelay(OS_MS_TO_SYSTICKS(delay));
149 }
150 
151 
152 /**
153  * @brief Yield control to the next task
154  **/
155 
156 void osSwitchTask(void)
157 {
158  //Force a context switch
159  taskYIELD();
160 }
161 
162 
163 /**
164  * @brief Suspend scheduler activity
165  **/
166 
168 {
169  //Make sure the operating system is running
170  if(xTaskIsSchedulerStarted() == pdTRUE)
171  {
172  //Suspend all tasks
173  vTaskSuspendScheduler();
174  }
175 }
176 
177 
178 /**
179  * @brief Resume scheduler activity
180  **/
181 
183 {
184  //Make sure the operating system is running
185  if(xTaskIsSchedulerStarted() == pdTRUE)
186  {
187  //Resume all tasks
188  xTaskResumeScheduler();
189  }
190 }
191 
192 
193 /**
194  * @brief Create an event object
195  * @param[in] event Pointer to the event object
196  * @return The function returns TRUE if the event object was successfully
197  * created. Otherwise, FALSE is returned
198  **/
199 
201 {
202  portBaseType status;
203 
204  uint32_t n;
205  uint32_t p = (uint32_t) event->buffer;
206  n = p % portQUEUE_OVERHEAD_BYTES;
207  p += portQUEUE_OVERHEAD_BYTES - n;
208 
209  //Create a binary semaphore
210  status = xSemaphoreCreateBinary((portInt8Type *) p, &event->handle);
211 
212  //Check whether the semaphore was successfully created
213  if(status == pdPASS)
214  {
215  //Force the event to the nonsignaled state
216  xSemaphoreTake(event->handle, 0);
217  //Event successfully created
218  return TRUE;
219  }
220  else
221  {
222  //Failed to create event object
223  return FALSE;
224  }
225 }
226 
227 
228 /**
229  * @brief Delete an event object
230  * @param[in] event Pointer to the event object
231  **/
232 
233 void osDeleteEvent(OsEvent *event)
234 {
235  //Not implemented
236 }
237 
238 
239 /**
240  * @brief Set the specified event object to the signaled state
241  * @param[in] event Pointer to the event object
242  **/
243 
244 void osSetEvent(OsEvent *event)
245 {
246  //Set the specified event to the signaled state
247  xSemaphoreGive(event->handle);
248 }
249 
250 
251 /**
252  * @brief Set the specified event object to the nonsignaled state
253  * @param[in] event Pointer to the event object
254  **/
255 
256 void osResetEvent(OsEvent *event)
257 {
258  //Force the specified event to the nonsignaled state
259  xSemaphoreTake(event->handle, 0);
260 }
261 
262 
263 /**
264  * @brief Wait until the specified event is in the signaled state
265  * @param[in] event Pointer to the event object
266  * @param[in] timeout Timeout interval
267  * @return The function returns TRUE if the state of the specified object is
268  * signaled. FALSE is returned if the timeout interval elapsed
269  **/
270 
272 {
273  portBaseType status;
274 
275  //Wait until the specified event is in the signaled state or the timeout
276  //interval elapses
277  if(timeout == INFINITE_DELAY)
278  {
279  //Infinite timeout period
280  status = xSemaphoreTake(event->handle, portMAX_DELAY);
281  }
282  else
283  {
284  //Wait for the specified time interval
285  status = xSemaphoreTake(event->handle, OS_MS_TO_SYSTICKS(timeout));
286  }
287 
288  //The return value tells whether the event is set
289  if(status == pdPASS)
290  return TRUE;
291  else
292  return FALSE;
293 }
294 
295 
296 /**
297  * @brief Set an event object to the signaled state from an interrupt service routine
298  * @param[in] event Pointer to the event object
299  * @return TRUE if setting the event to signaled state caused a task to unblock
300  * and the unblocked task has a priority higher than the currently running task
301  **/
302 
304 {
305  portBaseType flag = FALSE;
306 
307  //Set the specified event to the signaled state
308  xSemaphoreGiveFromISR(event->handle, &flag);
309 
310  //A higher priority task has been woken?
311  return flag;
312 }
313 
314 
315 /**
316  * @brief Create a semaphore object
317  * @param[in] semaphore Pointer to the semaphore object
318  * @param[in] count The maximum count for the semaphore object. This value
319  * must be greater than zero
320  * @return The function returns TRUE if the semaphore was successfully
321  * created. Otherwise, FALSE is returned
322  **/
323 
325 {
326  portBaseType status;
327 
328  uint32_t n;
329  uint32_t p = (uint32_t) semaphore->buffer;
330  n = p % portQUEUE_OVERHEAD_BYTES;
331  p += portQUEUE_OVERHEAD_BYTES - n;
332 
333  //Create a semaphore
334  status = xSemaphoreCreateCounting(count, count, (portInt8Type *) p,
335  &semaphore->handle);
336 
337  //Check whether the semaphore was successfully created
338  if(status == pdPASS)
339  return TRUE;
340  else
341  return FALSE;
342 }
343 
344 
345 /**
346  * @brief Delete a semaphore object
347  * @param[in] semaphore Pointer to the semaphore object
348  **/
349 
351 {
352  //Not implemented
353 }
354 
355 
356 /**
357  * @brief Wait for the specified semaphore to be available
358  * @param[in] semaphore Pointer to the semaphore object
359  * @param[in] timeout Timeout interval
360  * @return The function returns TRUE if the semaphore is available. FALSE is
361  * returned if the timeout interval elapsed
362  **/
363 
365 {
366  portBaseType status;
367 
368  //Wait until the specified semaphore becomes available
369  if(timeout == INFINITE_DELAY)
370  {
371  //Infinite timeout period
372  status = xSemaphoreTake(semaphore->handle, portMAX_DELAY);
373  }
374  else
375  {
376  //Wait for the specified time interval
377  status = xSemaphoreTake(semaphore->handle, OS_MS_TO_SYSTICKS(timeout));
378  }
379 
380  //The return value tells whether the semaphore is available
381  if(status == pdPASS)
382  return TRUE;
383  else
384  return FALSE;
385 }
386 
387 
388 /**
389  * @brief Release the specified semaphore object
390  * @param[in] semaphore Pointer to the semaphore object
391  **/
392 
394 {
395  //Release the semaphore
396  xSemaphoreGive(semaphore->handle);
397 }
398 
399 
400 /**
401  * @brief Create a mutex object
402  * @param[in] mutex Pointer to the mutex object
403  * @return The function returns TRUE if the mutex was successfully
404  * created. Otherwise, FALSE is returned
405  **/
406 
408 {
409  portBaseType status;
410 
411  uint32_t n;
412  uint32_t p = (uint32_t) mutex->buffer;
413  n = p % portQUEUE_OVERHEAD_BYTES;
414  p += portQUEUE_OVERHEAD_BYTES - n;
415 
416  //Create a binary semaphore
417  status = xSemaphoreCreateBinary((portInt8Type *) p, &mutex->handle);
418 
419  //Check whether the semaphore was successfully created
420  if(status == pdPASS)
421  {
422  //Force the binary semaphore to the signaled state
423  xSemaphoreGive(mutex->handle);
424 
425  //Semaphore successfully created
426  return TRUE;
427  }
428  else
429  {
430  //Failed to create semaphore
431  return FALSE;
432  }
433 }
434 
435 
436 /**
437  * @brief Delete a mutex object
438  * @param[in] mutex Pointer to the mutex object
439  **/
440 
441 void osDeleteMutex(OsMutex *mutex)
442 {
443  //Not implemented
444 }
445 
446 
447 /**
448  * @brief Acquire ownership of the specified mutex object
449  * @param[in] mutex Pointer to the mutex object
450  **/
451 
453 {
454  //Obtain ownership of the mutex object
455  xSemaphoreTake(mutex->handle, portMAX_DELAY);
456 }
457 
458 
459 /**
460  * @brief Release ownership of the specified mutex object
461  * @param[in] mutex Pointer to the mutex object
462  **/
463 
465 {
466  //Release ownership of the mutex object
467  xSemaphoreGive(mutex->handle);
468 }
469 
470 
471 /**
472  * @brief Retrieve system time
473  * @return Number of milliseconds elapsed since the system was last started
474  **/
475 
477 {
478  systime_t time;
479 
480  //Get current tick count
481  time = xTaskGetTickCount();
482 
483  //Convert system ticks to milliseconds
484  return OS_SYSTICKS_TO_MS(time);
485 }
486 
487 
488 /**
489  * @brief Allocate a memory block
490  * @param[in] size Bytes to allocate
491  * @return A pointer to the allocated memory block or NULL if
492  * there is insufficient memory available
493  **/
494 
495 __weak_func void *osAllocMem(size_t size)
496 {
497  //Not implemented
498  return NULL;
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  //Not implemented
510 }
unsigned int uint_t
Definition: compiler_port.h:50
char char_t
Definition: compiler_port.h:48
int bool_t
Definition: compiler_port.h:53
Debugging facilities.
uint8_t n
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
__weak_func void * osAllocMem(size_t size)
Allocate a memory block.
portBaseType xInitializeScheduler(void)
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.
__weak_func OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode, void *arg, const OsTaskParameters *params)
Create a task.
bool_t osWaitForSemaphore(OsSemaphore *semaphore, systime_t timeout)
Wait for the specified semaphore to be available.
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 (SafeRTOS)
char_t name[]
Event object.
portInt8Type buffer[portQUEUE_OVERHEAD_BYTES *2]
SemaphoreHandle_t handle
Mutex object.
portInt8Type buffer[portQUEUE_OVERHEAD_BYTES *2]
SemaphoreHandle_t handle
Semaphore object.
portInt8Type buffer[portQUEUE_OVERHEAD_BYTES *2]
SemaphoreHandle_t handle
Task parameters.