aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios/os/common/abstractions/cmsis_os
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios/os/common/abstractions/cmsis_os')
-rw-r--r--lib/chibios/os/common/abstractions/cmsis_os/cmsis_os.c558
-rw-r--r--lib/chibios/os/common/abstractions/cmsis_os/cmsis_os.h522
-rw-r--r--lib/chibios/os/common/abstractions/cmsis_os/cmsis_os.mk8
3 files changed, 1088 insertions, 0 deletions
diff --git a/lib/chibios/os/common/abstractions/cmsis_os/cmsis_os.c b/lib/chibios/os/common/abstractions/cmsis_os/cmsis_os.c
new file mode 100644
index 000000000..9bd63da8f
--- /dev/null
+++ b/lib/chibios/os/common/abstractions/cmsis_os/cmsis_os.c
@@ -0,0 +1,558 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19/*
20 Concepts and parts of this file have been contributed by Andre R.
21 */
22
23/**
24 * @file cmsis_os.c
25 * @brief CMSIS RTOS module code.
26 *
27 * @addtogroup CMSIS_OS
28 * @{
29 */
30
31#include "cmsis_os.h"
32#include <string.h>
33
34/*===========================================================================*/
35/* Module local definitions. */
36/*===========================================================================*/
37
38/*===========================================================================*/
39/* Module exported variables. */
40/*===========================================================================*/
41
42int32_t cmsis_os_started;
43
44/*===========================================================================*/
45/* Module local types. */
46/*===========================================================================*/
47
48/*===========================================================================*/
49/* Module local variables. */
50/*===========================================================================*/
51
52static memory_pool_t sempool;
53static semaphore_t semaphores[CMSIS_CFG_NUM_SEMAPHORES];
54
55static memory_pool_t timpool;
56static struct os_timer_cb timers[CMSIS_CFG_NUM_TIMERS];
57
58/*===========================================================================*/
59/* Module local functions. */
60/*===========================================================================*/
61
62/**
63 * @brief Virtual timers common callback.
64 */
65static void timer_cb(void const *arg) {
66
67 osTimerId timer_id = (osTimerId)arg;
68 timer_id->ptimer(timer_id->argument);
69 if (timer_id->type == osTimerPeriodic) {
70 chSysLockFromISR();
71 chVTDoSetI(&timer_id->vt, TIME_MS2I(timer_id->millisec),
72 (vtfunc_t)timer_cb, timer_id);
73 chSysUnlockFromISR();
74 }
75}
76
77/*===========================================================================*/
78/* Module exported functions. */
79/*===========================================================================*/
80
81/**
82 * @brief Kernel initialization.
83 */
84osStatus osKernelInitialize(void) {
85
86 cmsis_os_started = 0;
87
88 chSysInit();
89 chThdSetPriority(HIGHPRIO);
90
91 chPoolObjectInit(&sempool, sizeof(semaphore_t), chCoreAllocAlignedI);
92 chPoolLoadArray(&sempool, semaphores, CMSIS_CFG_NUM_SEMAPHORES);
93
94 chPoolObjectInit(&timpool, sizeof(struct os_timer_cb), chCoreAllocAlignedI);
95 chPoolLoadArray(&timpool, timers, CMSIS_CFG_NUM_TIMERS);
96
97 return osOK;
98}
99
100/**
101 * @brief Kernel start.
102 */
103osStatus osKernelStart(void) {
104
105 cmsis_os_started = 1;
106
107 chThdSetPriority(NORMALPRIO);
108
109 return osOK;
110}
111
112/**
113 * @brief Creates a thread.
114 */
115osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument) {
116 size_t size;
117
118 size = thread_def->stacksize == 0 ? CMSIS_CFG_DEFAULT_STACK :
119 thread_def->stacksize;
120 return (osThreadId)chThdCreateFromHeap(0,
121 THD_WORKING_AREA_SIZE(size),
122 thread_def->name,
123 NORMALPRIO+thread_def->tpriority,
124 (tfunc_t)thread_def->pthread,
125 argument);
126}
127
128/**
129 * @brief Thread termination.
130 * @note The thread is not really terminated but asked to terminate which
131 * is not compliant.
132 */
133osStatus osThreadTerminate(osThreadId thread_id) {
134
135 if (thread_id == osThreadGetId()) {
136 /* Note, no memory will be recovered unless a cleaner thread is
137 implemented using the registry.*/
138 chThdExit(0);
139 }
140 chThdTerminate(thread_id);
141 chThdWait((thread_t *)thread_id);
142
143 return osOK;
144}
145
146/**
147 * @brief Change thread priority.
148 * @note This can interfere with the priority inheritance mechanism.
149 */
150osStatus osThreadSetPriority(osThreadId thread_id, osPriority newprio) {
151 thread_t * tp = (thread_t *)thread_id;
152
153 chSysLock();
154
155 /* Changing priority.*/
156#if CH_CFG_USE_MUTEXES
157 if ((tp->hdr.pqueue.prio == tp->realprio) ||
158 ((tprio_t)newprio > tp->hdr.pqueue.prio))
159 tp->hdr.pqueue.prio = (tprio_t)newprio;
160 tp->realprio = (tprio_t)newprio;
161#else
162 tp->hdr.pqueue.prio = (tprio_t)newprio;
163#endif
164
165 /* The following states need priority queues reordering.*/
166 switch (tp->state) {
167#if CH_CFG_USE_MUTEXES | \
168 CH_CFG_USE_CONDVARS | \
169 (CH_CFG_USE_SEMAPHORES && CH_CFG_USE_SEMAPHORES_PRIORITY) | \
170 (CH_CFG_USE_MESSAGES && CH_CFG_USE_MESSAGES_PRIORITY)
171#if CH_CFG_USE_MUTEXES
172 case CH_STATE_WTMTX:
173#endif
174#if CH_CFG_USE_CONDVARS
175 case CH_STATE_WTCOND:
176#endif
177#if CH_CFG_USE_SEMAPHORES && CH_CFG_USE_SEMAPHORES_PRIORITY
178 case CH_STATE_WTSEM:
179#endif
180#if CH_CFG_USE_MESSAGES && CH_CFG_USE_MESSAGES_PRIORITY
181 case CH_STATE_SNDMSGQ:
182#endif
183 /* Re-enqueues tp with its new priority on the queue.*/
184 ch_sch_prio_insert(ch_queue_dequeue(&tp->hdr.queue),
185 (ch_queue_t *)tp->u.wtobjp);
186 break;
187#endif
188 case CH_STATE_READY:
189#if CH_DBG_ENABLE_ASSERTS
190 /* Prevents an assertion in chSchReadyI().*/
191 tp->state = CH_STATE_CURRENT;
192#endif
193 /* Re-enqueues tp with its new priority on the ready list.*/
194 chSchReadyI((thread_t *)ch_queue_dequeue(&tp->hdr.queue));
195 break;
196 }
197
198 /* Rescheduling.*/
199 chSchRescheduleS();
200
201 chSysUnlock();
202
203 return osOK;
204}
205
206/**
207 * @brief Create a timer.
208 */
209osTimerId osTimerCreate(const osTimerDef_t *timer_def,
210 os_timer_type type,
211 void *argument) {
212
213 osTimerId timer = chPoolAlloc(&timpool);
214 chVTObjectInit(&timer->vt);
215 timer->ptimer = timer_def->ptimer;
216 timer->type = type;
217 timer->argument = argument;
218 return timer;
219}
220
221/**
222 * @brief Start a timer.
223 */
224osStatus osTimerStart(osTimerId timer_id, uint32_t millisec) {
225
226 if ((millisec == 0) || (millisec == osWaitForever))
227 return osErrorValue;
228
229 timer_id->millisec = millisec;
230 chVTSet(&timer_id->vt, TIME_MS2I(millisec), (vtfunc_t)timer_cb, timer_id);
231
232 return osOK;
233}
234
235/**
236 * @brief Stop a timer.
237 */
238osStatus osTimerStop(osTimerId timer_id) {
239
240 chVTReset(&timer_id->vt);
241
242 return osOK;
243}
244
245/**
246 * @brief Delete a timer.
247 */
248osStatus osTimerDelete(osTimerId timer_id) {
249
250 chVTReset(&timer_id->vt);
251 chPoolFree(&timpool, (void *)timer_id);
252
253 return osOK;
254}
255
256/**
257 * @brief Send signals.
258 */
259int32_t osSignalSet(osThreadId thread_id, int32_t signals) {
260 int32_t oldsignals;
261
262 syssts_t sts = chSysGetStatusAndLockX();
263 oldsignals = (int32_t)thread_id->epending;
264 chEvtSignalI((thread_t *)thread_id, (eventmask_t)signals);
265 chSysRestoreStatusX(sts);
266
267 return oldsignals;
268}
269
270/**
271 * @brief Clear signals.
272 */
273int32_t osSignalClear(osThreadId thread_id, int32_t signals) {
274 eventmask_t m;
275
276 chSysLock();
277
278 m = thread_id->epending & (eventmask_t)signals;
279 thread_id->epending &= ~(eventmask_t)signals;
280
281 chSysUnlock();
282
283 return (int32_t)m;
284}
285
286/**
287 * @brief Wait for signals.
288 */
289osEvent osSignalWait(int32_t signals, uint32_t millisec) {
290 osEvent event;
291 sysinterval_t timeout = (millisec == osWaitForever ?
292 TIME_INFINITE : (millisec == 0 ? TIME_IMMEDIATE :
293 TIME_MS2I(millisec)));
294
295 if (signals == 0)
296 event.value.signals = (uint32_t)chEvtWaitAnyTimeout(ALL_EVENTS, timeout);
297 else
298 event.value.signals = (uint32_t)chEvtWaitAllTimeout((eventmask_t)signals,
299 timeout);
300
301 /* Type of event.*/
302 if (event.value.signals == 0)
303 event.status = osEventTimeout;
304 else
305 event.status = osEventSignal;
306
307 return event;
308}
309
310/**
311 * @brief Create a semaphore.
312 * @note @p semaphore_def is not used.
313 * @note Can involve memory allocation.
314 */
315osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def,
316 int32_t count) {
317
318 (void)semaphore_def;
319
320 semaphore_t *sem = chPoolAlloc(&sempool);
321 chSemObjectInit(sem, (cnt_t)count);
322 return sem;
323}
324
325/**
326 * @brief Wait on a semaphore.
327 */
328int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec) {
329 sysinterval_t timeout = (millisec == osWaitForever ?
330 TIME_INFINITE : (millisec == 0 ? TIME_IMMEDIATE :
331 TIME_MS2I(millisec)));
332
333 msg_t msg = chSemWaitTimeout((semaphore_t *)semaphore_id, timeout);
334 switch (msg) {
335 case MSG_OK:
336 return osOK;
337 case MSG_TIMEOUT:
338 return osErrorTimeoutResource;
339 }
340 return osErrorResource;
341}
342
343/**
344 * @brief Release a semaphore.
345 */
346osStatus osSemaphoreRelease(osSemaphoreId semaphore_id) {
347
348 syssts_t sts = chSysGetStatusAndLockX();
349 chSemSignalI((semaphore_t *)semaphore_id);
350 chSysRestoreStatusX(sts);
351
352 return osOK;
353}
354
355/**
356 * @brief Deletes a semaphore.
357 * @note After deletion there could be references in the system to a
358 * non-existent semaphore.
359 */
360osStatus osSemaphoreDelete(osSemaphoreId semaphore_id) {
361
362 chSemReset((semaphore_t *)semaphore_id, 0);
363 chPoolFree(&sempool, (void *)semaphore_id);
364
365 return osOK;
366}
367
368/**
369 * @brief Create a mutex.
370 * @note @p mutex_def is not used.
371 * @note Can involve memory allocation.
372 */
373osMutexId osMutexCreate(const osMutexDef_t *mutex_def) {
374
375 (void)mutex_def;
376
377 binary_semaphore_t *mtx = chPoolAlloc(&sempool);
378 chBSemObjectInit(mtx, false);
379 return mtx;
380}
381
382/**
383 * @brief Wait on a mutex.
384 */
385osStatus osMutexWait(osMutexId mutex_id, uint32_t millisec) {
386 sysinterval_t timeout = (millisec == osWaitForever ?
387 TIME_INFINITE : (millisec == 0 ? TIME_IMMEDIATE :
388 TIME_MS2I(millisec)));
389
390 msg_t msg = chBSemWaitTimeout((binary_semaphore_t *)mutex_id, timeout);
391 switch (msg) {
392 case MSG_OK:
393 return osOK;
394 case MSG_TIMEOUT:
395 return osErrorTimeoutResource;
396 }
397 return osErrorResource;
398}
399
400/**
401 * @brief Release a mutex.
402 */
403osStatus osMutexRelease(osMutexId mutex_id) {
404
405 syssts_t sts = chSysGetStatusAndLockX();
406 chBSemSignalI((binary_semaphore_t *)mutex_id);
407 chSysRestoreStatusX(sts);
408
409 return osOK;
410}
411
412/**
413 * @brief Deletes a mutex.
414 * @note After deletion there could be references in the system to a
415 * non-existent semaphore.
416 */
417osStatus osMutexDelete(osMutexId mutex_id) {
418
419 chSemReset((semaphore_t *)mutex_id, 0);
420 chPoolFree(&sempool, (void *)mutex_id);
421
422 return osOK;
423}
424
425/**
426 * @brief Create a memory pool.
427 * @note The pool is not really created because it is allocated statically,
428 * this function just re-initializes it.
429 */
430osPoolId osPoolCreate(const osPoolDef_t *pool_def) {
431
432 chPoolObjectInit(pool_def->pool, (size_t)pool_def->item_sz, NULL);
433 chPoolLoadArray(pool_def->pool, pool_def->items, (size_t)pool_def->pool_sz);
434
435 return (osPoolId)pool_def->pool;
436}
437
438/**
439 * @brief Allocate an object.
440 */
441void *osPoolAlloc(osPoolId pool_id) {
442 void *object;
443
444 syssts_t sts = chSysGetStatusAndLockX();
445 object = chPoolAllocI((memory_pool_t *)pool_id);
446 chSysRestoreStatusX(sts);
447
448 return object;
449}
450
451/**
452 * @brief Allocate an object clearing it.
453 */
454void *osPoolCAlloc(osPoolId pool_id) {
455 void *object;
456
457 object = chPoolAllocI((memory_pool_t *)pool_id);
458 memset(object, 0, pool_id->object_size);
459 return object;
460}
461
462/**
463 * @brief Free an object.
464 */
465osStatus osPoolFree(osPoolId pool_id, void *block) {
466
467 syssts_t sts = chSysGetStatusAndLockX();
468 chPoolFreeI((memory_pool_t *)pool_id, block);
469 chSysRestoreStatusX(sts);
470
471 return osOK;
472}
473
474/**
475 * @brief Create a message queue.
476 * @note The queue is not really created because it is allocated statically,
477 * this function just re-initializes it.
478 */
479osMessageQId osMessageCreate(const osMessageQDef_t *queue_def,
480 osThreadId thread_id) {
481
482 /* Ignoring this parameter for now.*/
483 (void)thread_id;
484
485 if (queue_def->item_sz > sizeof (msg_t))
486 return NULL;
487
488 chMBObjectInit(queue_def->mailbox,
489 queue_def->items,
490 (size_t)queue_def->queue_sz);
491
492 return (osMessageQId) queue_def->mailbox;
493}
494
495/**
496 * @brief Put a message in the queue.
497 */
498osStatus osMessagePut(osMessageQId queue_id,
499 uint32_t info,
500 uint32_t millisec) {
501 msg_t msg;
502 sysinterval_t timeout = (millisec == osWaitForever ?
503 TIME_INFINITE : (millisec == 0 ? TIME_IMMEDIATE :
504 TIME_MS2I(millisec)));
505
506 if (port_is_isr_context()) {
507
508 /* Waiting makes no sense in ISRs so any value except "immediate"
509 makes no sense.*/
510 if (millisec != 0)
511 return osErrorValue;
512
513 chSysLockFromISR();
514 msg = chMBPostI((mailbox_t *)queue_id, (msg_t)info);
515 chSysUnlockFromISR();
516 }
517 else
518 msg = chMBPostTimeout((mailbox_t *)queue_id, (msg_t)info, timeout);
519
520 return msg == MSG_OK ? osOK : osEventTimeout;
521}
522
523/**
524 * @brief Get a message from the queue.
525 */
526osEvent osMessageGet(osMessageQId queue_id,
527 uint32_t millisec) {
528 msg_t msg;
529 osEvent event;
530 sysinterval_t timeout = (millisec == osWaitForever ?
531 TIME_INFINITE : (millisec == 0 ? TIME_IMMEDIATE :
532 TIME_MS2I(millisec)));
533
534 event.def.message_id = queue_id;
535
536 if (port_is_isr_context()) {
537
538 /* Waiting makes no sense in ISRs so any value except "immediate"
539 makes no sense.*/
540 if (millisec != 0) {
541 event.status = osErrorValue;
542 return event;
543 }
544
545 chSysLockFromISR();
546 msg = chMBFetchI((mailbox_t *)queue_id, (msg_t*)&event.value.v);
547 chSysUnlockFromISR();
548 }
549 else {
550 msg = chMBFetchTimeout((mailbox_t *)queue_id, (msg_t*)&event.value.v, timeout);
551 }
552
553 /* Returned event type.*/
554 event.status = msg == MSG_OK ? osEventMessage : osEventTimeout;
555 return event;
556}
557
558/** @} */
diff --git a/lib/chibios/os/common/abstractions/cmsis_os/cmsis_os.h b/lib/chibios/os/common/abstractions/cmsis_os/cmsis_os.h
new file mode 100644
index 000000000..dafe3e398
--- /dev/null
+++ b/lib/chibios/os/common/abstractions/cmsis_os/cmsis_os.h
@@ -0,0 +1,522 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19/*
20 Concepts and parts of this file have been contributed by Andre R.
21 */
22
23/**
24 * @file cmsis_os.h
25 * @brief CMSIS RTOS module macros and structures.
26 *
27 * @addtogroup CMSIS_OS
28 * @{
29 */
30
31#ifndef CMSIS_OS_H
32#define CMSIS_OS_H
33
34#include "ch.h"
35
36/*===========================================================================*/
37/* Module constants. */
38/*===========================================================================*/
39
40/**
41 * @brief API version.
42 */
43#define osCMSIS 0x10002
44
45/**
46 * @brief Kernel version.
47 */
48#define osKernelSystemId "KERNEL V1.00"
49
50/**
51 * @brief ChibiOS/RT version encoded for CMSIS.
52 */
53#define osCMSIS_KERNEL ((CH_KERNEL_MAJOR << 16) | \
54 (CH_KERNEL_MINOR << 8) | \
55 (CH_KERNEL_PATCH))
56
57/**
58 * @name CMSIS Capabilities
59 * @{
60 */
61#define osFeature_MainThread 1
62#define osFeature_Pool 1
63#define osFeature_MailQ 0
64#define osFeature_MessageQ 1
65#define osFeature_Signals 24
66#define osFeature_Semaphore ((1U << 31) - 1U)
67#define osFeature_Wait 0
68#define osFeature_SysTick 1
69/**< @} */
70
71/**
72 * @brief Wait forever specification for timeouts.
73 */
74#define osWaitForever ((uint32_t)-1)
75
76/**
77 * @brief System tick frequency.
78 */
79#define osKernelSysTickFrequency CH_CFG_ST_FREQUENCY
80
81/*===========================================================================*/
82/* Module pre-compile time settings. */
83/*===========================================================================*/
84
85/**
86 * @brief Number of pre-allocated static semaphores/mutexes.
87 */
88#if !defined(CMSIS_CFG_DEFAULT_STACK)
89#define CMSIS_CFG_DEFAULT_STACK 256
90#endif
91
92/**
93 * @brief Number of pre-allocated static semaphores/mutexes.
94 */
95#if !defined(CMSIS_CFG_NUM_SEMAPHORES)
96#define CMSIS_CFG_NUM_SEMAPHORES 4
97#endif
98
99/**
100 * @brief Number of pre-allocated static timers.
101 */
102#if !defined(CMSIS_CFG_NUM_TIMERS)
103#define CMSIS_CFG_NUM_TIMERS 4
104#endif
105
106/*===========================================================================*/
107/* Derived constants and error checks. */
108/*===========================================================================*/
109
110#if !CH_CFG_USE_MEMPOOLS
111#error "CMSIS RTOS requires CH_CFG_USE_MEMPOOLS"
112#endif
113
114#if !CH_CFG_USE_EVENTS
115#error "CMSIS RTOS requires CH_CFG_USE_EVENTS"
116#endif
117
118#if !CH_CFG_USE_EVENTS_TIMEOUT
119#error "CMSIS RTOS requires CH_CFG_USE_EVENTS_TIMEOUT"
120#endif
121
122#if !CH_CFG_USE_SEMAPHORES
123#error "CMSIS RTOS requires CH_CFG_USE_SEMAPHORES"
124#endif
125
126#if !CH_CFG_USE_DYNAMIC
127#error "CMSIS RTOS requires CH_CFG_USE_DYNAMIC"
128#endif
129
130/*===========================================================================*/
131/* Module data structures and types. */
132/*===========================================================================*/
133
134/**
135 * @brief Type of priority levels.
136 */
137typedef enum {
138 osPriorityIdle = -3,
139 osPriorityLow = -2,
140 osPriorityBelowNormal = -1,
141 osPriorityNormal = 0,
142 osPriorityAboveNormal = +1,
143 osPriorityHigh = +2,
144 osPriorityRealtime = +3,
145 osPriorityError = 0x84
146} osPriority;
147
148/**
149 * @brief Type of error codes.
150 */
151typedef enum {
152 osOK = 0,
153 osEventSignal = 0x08,
154 osEventMessage = 0x10,
155 osEventMail = 0x20,
156 osEventTimeout = 0x40,
157 osErrorParameter = 0x80,
158 osErrorResource = 0x81,
159 osErrorTimeoutResource = 0xC1,
160 osErrorISR = 0x82,
161 osErrorISRRecursive = 0x83,
162 osErrorPriority = 0x84,
163 osErrorNoMemory = 0x85,
164 osErrorValue = 0x86,
165 osErrorOS = 0xFF,
166 os_status_reserved = 0x7FFFFFFF
167} osStatus;
168
169/**
170 * @brief Type of a timer mode.
171 */
172typedef enum {
173 osTimerOnce = 0,
174 osTimerPeriodic = 1
175} os_timer_type;
176
177/**
178 * @brief Type of thread functions.
179 */
180typedef void (*os_pthread) (void const *argument);
181
182/**
183 * @brief Type of timer callback.
184 */
185typedef void (*os_ptimer) (void const *argument);
186
187/**
188 * @brief Type of pointer to thread control block.
189 */
190typedef thread_t *osThreadId;
191
192/**
193 * @brief Type of pointer to timer control block.
194 */
195typedef struct os_timer_cb {
196 virtual_timer_t vt;
197 os_timer_type type;
198 os_ptimer ptimer;
199 void *argument;
200 uint32_t millisec;
201} *osTimerId;
202
203/**
204 * @brief Type of pointer to mutex control block.
205 */
206typedef binary_semaphore_t *osMutexId;
207
208/**
209 * @brief Type of pointer to semaphore control block.
210 */
211typedef semaphore_t *osSemaphoreId;
212
213/**
214 * @brief Type of pointer to memory pool control block.
215 */
216typedef memory_pool_t *osPoolId;
217
218/**
219 * @brief Type of pointer to message queue control block.
220 */
221typedef struct mailbox *osMessageQId;
222
223/**
224 * @brief Type of an event.
225 */
226typedef struct {
227 osStatus status;
228 union {
229 uint32_t v;
230 void *p;
231 int32_t signals;
232 } value;
233 union {
234/* osMailQId mail_id;*/
235 osMessageQId message_id;
236 } def;
237} osEvent;
238
239/**
240 * @brief Type of a thread definition block.
241 */
242typedef struct os_thread_def {
243 os_pthread pthread;
244 osPriority tpriority;
245 uint32_t stacksize;
246 const char *name;
247} osThreadDef_t;
248
249/**
250 * @brief Type of a timer definition block.
251 */
252typedef struct os_timer_def {
253 os_ptimer ptimer;
254} osTimerDef_t;
255
256/**
257 * @brief Type of a mutex definition block.
258 */
259typedef struct os_mutex_def {
260 uint32_t dummy;
261} osMutexDef_t;
262
263/**
264 * @brief Type of a semaphore definition block.
265 */
266typedef struct os_semaphore_def {
267 uint32_t dummy;
268} osSemaphoreDef_t;
269
270/**
271 * @brief Type of a memory pool definition block.
272 */
273typedef struct os_pool_def {
274 uint32_t pool_sz;
275 uint32_t item_sz;
276 memory_pool_t *pool;
277 void *items;
278} osPoolDef_t;
279
280/**
281 * @brief Type of a message queue definition block.
282 */
283typedef struct os_messageQ_def {
284 uint32_t queue_sz;
285 uint32_t item_sz;
286 mailbox_t *mailbox;
287 void *items;
288} osMessageQDef_t;
289
290/*===========================================================================*/
291/* Module macros. */
292/*===========================================================================*/
293
294/**
295 * @brief Convert a microseconds value to a RTOS kernel system timer value.
296 */
297#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * \
298 (osKernelSysTickFrequency)) / \
299 1000000)
300
301/**
302 * @brief Create a Thread definition.
303 */
304#if defined(osObjectsExternal)
305#define osThreadDef(thd, priority, stacksz, name) \
306 extern const osThreadDef_t os_thread_def_##thd
307#else
308#define osThreadDef(thd, priority, stacksz, name) \
309const osThreadDef_t os_thread_def_##thd = { \
310 (thd), \
311 (priority), \
312 (stacksz), \
313 (name) \
314}
315#endif
316
317/**
318 * @brief Access a Thread definition.
319 */
320#define osThread(name) &os_thread_def_##name
321
322/**
323 * @brief Define a Timer object.
324 */
325#if defined(osObjectsExternal)
326#define osTimerDef(name, function) \
327 extern const osTimerDef_t os_timer_def_##name
328#else
329#define osTimerDef(name, function) \
330const osTimerDef_t os_timer_def_##name = { \
331 (function) \
332}
333#endif
334
335/**
336 * @brief Access a Timer definition.
337 */
338#define osTimer(name) &os_timer_def_##name
339
340/**
341 * @brief Define a Mutex.
342 */
343#if defined(osObjectsExternal)
344#define osMutexDef(name) extern const osMutexDef_t os_mutex_def_##name
345#else
346#define osMutexDef(name) const osMutexDef_t os_mutex_def_##name = {0}
347#endif
348
349/**
350 * @brief Access a Mutex definition.
351 */
352#define osMutex(name) &os_mutex_def_##name
353
354/**
355 * @brief Define a Semaphore.
356 */
357#if defined(osObjectsExternal)
358#define osSemaphoreDef(name) \
359 extern const osSemaphoreDef_t os_semaphore_def_##name
360#else // define the object
361#define osSemaphoreDef(name) \
362 const osSemaphoreDef_t os_semaphore_def_##name = {0}
363#endif
364
365/**
366 * @brief Access a Semaphore definition.
367 */
368#define osSemaphore(name) &os_semaphore_def_##name
369
370/**
371 * @brief Define a Memory Pool.
372 */
373#if defined(osObjectsExternal)
374#define osPoolDef(name, no, type) \
375 extern const osPoolDef_t os_pool_def_##name
376#else
377#define osPoolDef(name, no, type) \
378static const type os_pool_buf_##name[no]; \
379static memory_pool_t os_pool_obj_##name; \
380const osPoolDef_t os_pool_def_##name = { \
381 (no), \
382 sizeof (type), \
383 (void *)&os_pool_obj_##name, \
384 (void *)&os_pool_buf_##name[0] \
385}
386#endif
387
388/**
389 * @brief Access a Memory Pool definition.
390 */
391#define osPool(name) &os_pool_def_##name
392
393/**
394 * @brief Define a Message Queue.
395 */
396#if defined(osObjectsExternal)
397#define osMessageQDef(name, queue_sz, type) \
398 extern const osMessageQDef_t os_messageQ_def_##name
399#else
400#define osMessageQDef(name, queue_sz, type) \
401static const msg_t os_messageQ_buf_##name[queue_sz]; \
402static mailbox_t os_messageQ_obj_##name; \
403const osMessageQDef_t os_messageQ_def_##name = { \
404 (queue_sz), \
405 sizeof (type), \
406 (void *)&os_messageQ_obj_##name, \
407 (void *)&os_messageQ_buf_##name[0] \
408}
409#endif
410
411/**
412 * @brief Access a Message Queue definition.
413 */
414#define osMessageQ(name) &os_messageQ_def_##name
415
416/*===========================================================================*/
417/* External declarations. */
418/*===========================================================================*/
419
420extern int32_t cmsis_os_started;
421
422#ifdef __cplusplus
423extern "C" {
424#endif
425 osStatus osKernelInitialize(void);
426 osStatus osKernelStart(void);
427 osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument);
428 osStatus osThreadTerminate(osThreadId thread_id);
429 osStatus osThreadSetPriority(osThreadId thread_id, osPriority newprio);
430 /*osEvent osWait(uint32_t millisec);*/
431 osTimerId osTimerCreate(const osTimerDef_t *timer_def,
432 os_timer_type type,
433 void *argument);
434 osStatus osTimerStart(osTimerId timer_id, uint32_t millisec);
435 osStatus osTimerStop(osTimerId timer_id);
436 osStatus osTimerDelete(osTimerId timer_id);
437 int32_t osSignalSet(osThreadId thread_id, int32_t signals);
438 int32_t osSignalClear(osThreadId thread_id, int32_t signals);
439 osEvent osSignalWait(int32_t signals, uint32_t millisec);
440 osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def,
441 int32_t count);
442 int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec);
443 osStatus osSemaphoreRelease(osSemaphoreId semaphore_id);
444 osStatus osSemaphoreDelete(osSemaphoreId semaphore_id);
445 osMutexId osMutexCreate(const osMutexDef_t *mutex_def);
446 osStatus osMutexWait(osMutexId mutex_id, uint32_t millisec);
447 osStatus osMutexRelease(osMutexId mutex_id);
448 osStatus osMutexDelete(osMutexId mutex_id);
449 osPoolId osPoolCreate(const osPoolDef_t *pool_def);
450 void *osPoolAlloc(osPoolId pool_id);
451 void *osPoolCAlloc(osPoolId pool_id);
452 osStatus osPoolFree(osPoolId pool_id, void *block);
453 osMessageQId osMessageCreate(const osMessageQDef_t *queue_def,
454 osThreadId thread_id);
455 osStatus osMessagePut(osMessageQId queue_id,
456 uint32_t info,
457 uint32_t millisec);
458 osEvent osMessageGet(osMessageQId queue_id,
459 uint32_t millisec);
460#ifdef __cplusplus
461}
462#endif
463
464/*===========================================================================*/
465/* Module inline functions. */
466/*===========================================================================*/
467
468/**
469 * @brief To be or not to be.
470 */
471static inline int32_t osKernelRunning(void) {
472
473 return cmsis_os_started;
474}
475
476/**
477 * @brief System ticks since start.
478 */
479static inline uint32_t osKernelSysTick(void) {
480
481 return (uint32_t)chVTGetSystemTimeX();
482}
483
484/**
485 * @brief Returns the current thread.
486 */
487static inline osThreadId osThreadGetId(void) {
488
489 return (osThreadId)chThdGetSelfX();
490}
491
492/**
493 * @brief Thread time slice yield.
494 */
495static inline osStatus osThreadYield(void) {
496
497 chThdYield();
498
499 return osOK;
500}
501
502/**
503 * @brief Returns priority of a thread.
504 */
505static inline osPriority osThreadGetPriority(osThreadId thread_id) {
506
507 return (osPriority)(NORMALPRIO - thread_id->hdr.pqueue.prio);
508}
509
510/**
511 * @brief Thread delay in milliseconds.
512 */
513static inline osStatus osDelay(uint32_t millisec) {
514
515 chThdSleepMilliseconds(millisec);
516
517 return osOK;
518}
519
520#endif /* CMSIS_OS_H */
521
522/** @} */
diff --git a/lib/chibios/os/common/abstractions/cmsis_os/cmsis_os.mk b/lib/chibios/os/common/abstractions/cmsis_os/cmsis_os.mk
new file mode 100644
index 000000000..343f6df40
--- /dev/null
+++ b/lib/chibios/os/common/abstractions/cmsis_os/cmsis_os.mk
@@ -0,0 +1,8 @@
1# List of the ChibiOS/RT CMSIS RTOS wrapper.
2CMSISRTOSSRC = ${CHIBIOS}/os/common/abstractions/cmsis_os/cmsis_os.c
3
4CMSISRTOSINC = ${CHIBIOS}/os/common/abstractions/cmsis_os
5
6# Shared variables
7ALLCSRC += $(CMSISRTOSSRC)
8ALLINC += $(CMSISRTOSINC)