os_port_chibios.c
Go to the documentation of this file.
1 /**
2  * @file os_port_chibios.c
3  * @brief RTOS abstraction layer (ChibiOS/RT)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2023 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.2.4
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_chibios.h"
38 #include "debug.h"
39 
40 
41 /**
42  * @brief Kernel initialization
43  **/
44 
45 void osInitKernel(void)
46 {
47  //Kernel initialization
48  chSysInit();
49 }
50 
51 
52 /**
53  * @brief Start kernel
54  **/
55 
56 void osStartKernel(void)
57 {
58  //Terminate the main thread
59  chThdExit(MSG_OK);
60 }
61 
62 
63 /**
64  * @brief Create a task
65  * @param[in] name A name identifying the task
66  * @param[in] taskCode Pointer to the task entry function
67  * @param[in] param A pointer to a variable to be passed to the task
68  * @param[in] stackSize The initial size of the stack, in words
69  * @param[in] priority The priority at which the task should run
70  * @return Task identifier referencing the newly created task
71  **/
72 
74  void *param, size_t stackSize, int_t priority)
75 {
76  thread_t *handle;
77 
78  //Create a new task
79  handle = chThdCreateFromHeap(0, THD_WORKING_AREA_SIZE(stackSize),
80  priority, taskCode, param);
81 
82  //Return a handle to the newly created thread
83  return (OsTaskId) handle;
84 }
85 
86 
87 /**
88  * @brief Create a task with statically allocated memory
89  * @param[in] name A name identifying the task
90  * @param[in] taskCode Pointer to the task entry function
91  * @param[in] param A pointer to a variable to be passed to the task
92  * @param[in] tcb Pointer to the task control block
93  * @param[in] stack Pointer to the stack
94  * @param[in] stackSize The initial size of the stack, in words
95  * @param[in] priority The priority at which the task should run
96  * @return Task identifier referencing the newly created task
97  **/
98 
100  void *param, OsTaskTcb *tcb, OsStackType *stack, size_t stackSize,
101  int_t priority)
102 {
103  thread_t *handle;
104 
105  //Create a new task
106  handle = chThdCreateStatic(stack, stackSize * sizeof(uint32_t), priority,
107  (tfunc_t) taskCode, param);
108 
109  //Return a handle to the newly created thread
110  return (OsTaskId) handle;
111 }
112 
113 
114 /**
115  * @brief Delete a task
116  * @param[in] taskId Task identifier referencing the task to be deleted
117  **/
118 
119 void osDeleteTask(OsTaskId taskId)
120 {
121  //Delete the specified task
122  if(taskId == OS_SELF_TASK_ID)
123  {
124  chThdExit(MSG_OK);
125  }
126  else
127  {
128  chThdTerminate((thread_t *) taskId);
129  }
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  //Delay the task for the specified duration
141  chThdSleep(OS_MS_TO_SYSTICKS(delay));
142 }
143 
144 
145 /**
146  * @brief Yield control to the next task
147  **/
148 
149 void osSwitchTask(void)
150 {
151  //Force a context switch
152  chThdYield();
153 }
154 
155 
156 /**
157  * @brief Suspend scheduler activity
158  **/
159 
161 {
162  //Suspend scheduler activity
163  chSysLock();
164 }
165 
166 
167 /**
168  * @brief Resume scheduler activity
169  **/
170 
172 {
173  //Resume scheduler activity
174  chSysUnlock();
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  //Initialize the binary semaphore object
188  chBSemObjectInit(event, TRUE);
189 
190  //Event successfully created
191  return TRUE;
192 }
193 
194 
195 /**
196  * @brief Delete an event object
197  * @param[in] event Pointer to the event object
198  **/
199 
200 void osDeleteEvent(OsEvent *event)
201 {
202  //No resource to release
203 }
204 
205 
206 /**
207  * @brief Set the specified event object to the signaled state
208  * @param[in] event Pointer to the event object
209  **/
210 
211 void osSetEvent(OsEvent *event)
212 {
213  //Set the specified event to the signaled state
214  chBSemSignal(event);
215 }
216 
217 
218 /**
219  * @brief Set the specified event object to the nonsignaled state
220  * @param[in] event Pointer to the event object
221  **/
222 
223 void osResetEvent(OsEvent *event)
224 {
225  //Force the specified event to the nonsignaled state
226  chBSemReset(event, TRUE);
227 }
228 
229 
230 /**
231  * @brief Wait until the specified event is in the signaled state
232  * @param[in] event Pointer to the event object
233  * @param[in] timeout Timeout interval
234  * @return The function returns TRUE if the state of the specified object is
235  * signaled. FALSE is returned if the timeout interval elapsed
236  **/
237 
239 {
240  msg_t msg;
241 
242  //Wait until the specified event is in the signaled state or the timeout
243  //interval elapses
244  if(timeout == 0)
245  {
246  //Non-blocking call
247  msg = chBSemWaitTimeout(event, TIME_IMMEDIATE);
248  }
249  else if(timeout == INFINITE_DELAY)
250  {
251  //Infinite timeout period
252  msg = chBSemWaitTimeout(event, TIME_INFINITE);
253  }
254  else
255  {
256  //Wait until the specified event becomes set
257  msg = chBSemWaitTimeout(event, OS_MS_TO_SYSTICKS(timeout));
258  }
259 
260  //Check whether the specified event is set
261  if(msg == MSG_OK)
262  return TRUE;
263  else
264  return FALSE;
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  chBSemSignalI(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  //Initialize the semaphore object
297  chSemObjectInit(semaphore, count);
298 
299  //Semaphore 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  //No resource to release
312 }
313 
314 
315 /**
316  * @brief Wait for the specified semaphore to be available
317  * @param[in] semaphore Pointer to the semaphore object
318  * @param[in] timeout Timeout interval
319  * @return The function returns TRUE if the semaphore is available. FALSE is
320  * returned if the timeout interval elapsed
321  **/
322 
324 {
325  msg_t msg;
326 
327  //Wait until the semaphore is available or the timeout interval elapses
328  if(timeout == 0)
329  {
330  //Non-blocking call
331  msg = chSemWaitTimeout(semaphore, TIME_IMMEDIATE);
332  }
333  else if(timeout == INFINITE_DELAY)
334  {
335  //Infinite timeout period
336  msg = chSemWaitTimeout(semaphore, TIME_INFINITE);
337  }
338  else
339  {
340  //Wait until the specified semaphore becomes available
341  msg = chSemWaitTimeout(semaphore, OS_MS_TO_SYSTICKS(timeout));
342  }
343 
344  //Check whether the specified semaphore is available
345  if(msg == MSG_OK)
346  return TRUE;
347  else
348  return FALSE;
349 }
350 
351 
352 /**
353  * @brief Release the specified semaphore object
354  * @param[in] semaphore Pointer to the semaphore object
355  **/
356 
358 {
359  //Release the semaphore
360  chSemSignal(semaphore);
361 }
362 
363 
364 /**
365  * @brief Create a mutex object
366  * @param[in] mutex Pointer to the mutex object
367  * @return The function returns TRUE if the mutex was successfully
368  * created. Otherwise, FALSE is returned
369  **/
370 
372 {
373  //Initialize the mutex object
374  chMtxObjectInit(mutex);
375 
376  //Mutex successfully created
377  return TRUE;
378 }
379 
380 
381 /**
382  * @brief Delete a mutex object
383  * @param[in] mutex Pointer to the mutex object
384  **/
385 
386 void osDeleteMutex(OsMutex *mutex)
387 {
388  //No resource to release
389 }
390 
391 
392 /**
393  * @brief Acquire ownership of the specified mutex object
394  * @param[in] mutex Pointer to the mutex object
395  **/
396 
398 {
399  //Obtain ownership of the mutex object
400  chMtxLock(mutex);
401 }
402 
403 
404 /**
405  * @brief Release ownership of the specified mutex object
406  * @param[in] mutex Pointer to the mutex object
407  **/
408 
410 {
411  //Release ownership of the mutex object
412 #if (CH_KERNEL_MAJOR < 3)
413  chMtxUnlock();
414 #else
415  chMtxUnlock(mutex);
416 #endif
417 }
418 
419 
420 /**
421  * @brief Retrieve system time
422  * @return Number of milliseconds elapsed since the system was last started
423  **/
424 
426 {
427  systime_t time;
428 
429  //Get current tick count
431 
432  //Convert system ticks to milliseconds
433  return OS_SYSTICKS_TO_MS(time);
434 }
435 
436 
437 /**
438  * @brief Allocate a memory block
439  * @param[in] size Bytes to allocate
440  * @return A pointer to the allocated memory block or NULL if
441  * there is insufficient memory available
442  **/
443 
444 __weak_func void *osAllocMem(size_t size)
445 {
446  void *p;
447 
448  //Allocate a memory block
449  p = chHeapAlloc(NULL, size);
450 
451  //Debug message
452  TRACE_DEBUG("Allocating %" PRIuSIZE " bytes at 0x%08" PRIXPTR "\r\n",
453  size, (uintptr_t) p);
454 
455  //Return a pointer to the newly allocated memory block
456  return p;
457 }
458 
459 
460 /**
461  * @brief Release a previously allocated memory block
462  * @param[in] p Previously allocated memory block to be freed
463  **/
464 
465 __weak_func void osFreeMem(void *p)
466 {
467  //Make sure the pointer is valid
468  if(p != NULL)
469  {
470  //Debug message
471  TRACE_DEBUG("Freeing memory at 0x%08" PRIXPTR "\r\n", (uintptr_t) p);
472 
473  //Free memory block
474  chHeapFree(p);
475  }
476 }
477 
478 
479 /**
480  * @brief Idle loop hook
481  **/
482 
483 void osIdleLoopHook(void)
484 {
485  //Not implemented
486 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode, void *param, size_t stackSize, int_t priority)
Create a task.
RTOS abstraction layer (ChibiOS/RT)
int bool_t
Definition: compiler_port.h:53
bool_t osCreateMutex(OsMutex *mutex)
Create a mutex object.
signed int int_t
Definition: compiler_port.h:49
void osReleaseSemaphore(OsSemaphore *semaphore)
Release the specified semaphore object.
uint8_t p
Definition: ndp.h:298
void osStartKernel(void)
Start kernel.
#define TRUE
Definition: os_port.h:52
Event object.
char_t name[]
#define OS_SELF_TASK_ID
bool_t osWaitForSemaphore(OsSemaphore *semaphore, systime_t timeout)
Wait for the specified semaphore to be available.
void osDeleteSemaphore(OsSemaphore *semaphore)
Delete a semaphore object.
Semaphore object.
bool_t osCreateSemaphore(OsSemaphore *semaphore, uint_t count)
Create a semaphore object.
__weak_func void * osAllocMem(size_t size)
Allocate a memory block.
void osDeleteTask(OsTaskId taskId)
Delete a task.
#define FALSE
Definition: os_port.h:48
void osResetEvent(OsEvent *event)
Set the specified event object to the nonsignaled state.
#define chSemObjectInit
OsTaskId osCreateStaticTask(const char_t *name, OsTaskCode taskCode, void *param, OsTaskTcb *tcb, OsStackType *stack, size_t stackSize, int_t priority)
Create a task with statically allocated memory.
__weak_func void osFreeMem(void *p)
Release a previously allocated memory block.
void osIdleLoopHook(void)
Idle loop hook.
Task control block.
void osDeleteEvent(OsEvent *event)
Delete an event object.
void osInitKernel(void)
Kernel initialization.
#define OS_SYSTICKS_TO_MS(n)
uint32_t OsStackType
Stack data type.
#define OS_MS_TO_SYSTICKS(n)
void osResumeAllTasks(void)
Resume scheduler activity.
#define thread_t
void osSwitchTask(void)
Yield control to the next task.
Mutex object.
uint32_t systime_t
System time.
#define THD_WORKING_AREA_SIZE
#define TRACE_DEBUG(...)
Definition: debug.h:107
char char_t
Definition: compiler_port.h:48
uint32_t time
void osDeleteMutex(OsMutex *mutex)
Delete a mutex object.
#define chBSemObjectInit
void osSuspendAllTasks(void)
Suspend scheduler activity.
void(* OsTaskCode)(void *param)
Task routine.
bool_t osWaitForEvent(OsEvent *event, systime_t timeout)
Wait until the specified event is in the signaled state.
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
bool_t osCreateEvent(OsEvent *event)
Create an event object.
#define MSG_OK
void osDelayTask(systime_t delay)
Delay routine.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
thread_t * OsTaskId
Task identifier.
#define chVTGetSystemTime
#define PRIuSIZE
unsigned int uint_t
Definition: compiler_port.h:50
uint16_t priority
Definition: dns_common.h:249
RTOS abstraction layer.
Debugging facilities.
#define chMtxObjectInit
#define INFINITE_DELAY
Definition: os_port.h:77
systime_t osGetSystemTime(void)
Retrieve system time.