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-2021 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.1.2
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
45void osInitKernel(void)
46{
47 //Kernel initialization
48 chSysInit();
49}
50
51
52/**
53 * @brief Start kernel
54 **/
55
56void 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,
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
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
149void 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
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
211void 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
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
243 //state or the timeout 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
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{
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 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", size, (uintptr_t) p);
453
454 //Return a pointer to the newly allocated memory block
455 return p;
456}
457
458
459/**
460 * @brief Release a previously allocated memory block
461 * @param[in] p Previously allocated memory block to be freed
462 **/
463
464__weak void osFreeMem(void *p)
465{
466 //Make sure the pointer is valid
467 if(p != NULL)
468 {
469 //Debug message
470 TRACE_DEBUG("Freeing memory at 0x%08" PRIXPTR "\r\n", (uintptr_t) p);
471
472 //Free memory block
473 chHeapFree(p);
474 }
475}
476
477
478/**
479 * @brief Idle loop hook
480 **/
481
483{
484 //Not implemented
485}
signed int int_t
Definition: compiler_port.h:44
unsigned int uint_t
Definition: compiler_port.h:45
#define PRIuSIZE
Definition: compiler_port.h:78
char char_t
Definition: compiler_port.h:43
int bool_t
Definition: compiler_port.h:49
uint32_t systime_t
Definition: compiler_port.h:46
Debugging facilities.
#define TRACE_DEBUG(...)
Definition: debug.h:107
uint32_t time
uint8_t p
Definition: ndp.h:298
RTOS abstraction layer.
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
#define INFINITE_DELAY
Definition: os_port.h:74
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.
void osIdleLoopHook(void)
Idle loop hook.
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.
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.
__weak void osFreeMem(void *p)
Release a previously allocated memory block.
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.
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.
void osStartKernel(void)
Start kernel.
OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode, void *param, size_t stackSize, int_t priority)
Create a task.
void osInitKernel(void)
Kernel initialization.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
__weak void * osAllocMem(size_t size)
Allocate a memory block.
RTOS abstraction layer (ChibiOS/RT)
#define chMtxObjectInit
#define THD_WORKING_AREA_SIZE
#define OS_SYSTICKS_TO_MS(n)
#define MSG_OK
void(* OsTaskCode)(void *param)
Task routine.
#define thread_t
#define chSemObjectInit
#define chBSemObjectInit
#define chVTGetSystemTime
#define OS_MS_TO_SYSTICKS(n)
#define OS_SELF_TASK_ID
uint32_t OsStackType
Stack data type.
thread_t * OsTaskId
Task identifier.
char_t name[]
uint16_t priority
Definition: stp_common.h:144
Event object.
Mutex object.
Semaphore object.
Task control block.