ChibiOS 21.11.5
nil/include/ch.h
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006-2026 Giovanni Di Sirio.
3
4 This file is part of ChibiOS.
5
6 ChibiOS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation version 3 of the License.
9
10 ChibiOS is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/**
20 * @file nil/include/ch.h
21 * @brief Nil RTOS main header file.
22 * @details This header includes all the required kernel headers so it is the
23 * only header you usually need to include in your application.
24 *
25 * @addtogroup NIL_KERNEL
26 * @{
27 */
28
29#ifndef CH_H
30#define CH_H
31
32#include "chtypes.h"
33
34/*===========================================================================*/
35/* Module constants. */
36/*===========================================================================*/
37
38/**
39 * @brief ChibiOS/NIL identification macro.
40 */
41#define __CHIBIOS_NIL__
42
43/**
44 * @brief Stable release flag.
45 */
46#define CH_KERNEL_STABLE 1
47
48/**
49 * @name ChibiOS/NIL version identification
50 * @{
51 */
52/**
53 * @brief Kernel version string.
54 */
55#define CH_KERNEL_VERSION "4.1.4"
56
57/**
58 * @brief Kernel version major number.
59 */
60#define CH_KERNEL_MAJOR 4
61
62/**
63 * @brief Kernel version minor number.
64 */
65#define CH_KERNEL_MINOR 1
66
67/**
68 * @brief Kernel version patch number.
69 */
70#define CH_KERNEL_PATCH 4
71/** @} */
72
73/**
74 * @name Constants for configuration options
75 * @{
76 */
77/**
78 * @brief Generic 'false' preprocessor boolean constant.
79 * @note It is meant to be used in configuration files as switch.
80 */
81#if !defined(FALSE) || defined(__DOXYGEN__)
82#define FALSE 0
83#endif
84
85/**
86 * @brief Generic 'true' preprocessor boolean constant.
87 * @note It is meant to be used in configuration files as switch.
88 */
89#if !defined(TRUE) || defined(__DOXYGEN__)
90#define TRUE 1
91#endif
92/** @} */
93
94/**
95 * @name Wakeup messages
96 * @{
97 */
98#define MSG_OK (msg_t)0 /**< @brief OK wakeup message. */
99#define MSG_TIMEOUT (msg_t)-1 /**< @brief Wake-up caused by
100 a timeout condition. */
101#define MSG_RESET (msg_t)-2 /**< @brief Wake-up caused by
102 a reset condition. */
103/** @} */
104
105/**
106 * @name Special time constants
107 * @{
108 */
109/**
110 * @brief Zero time specification for some functions with a timeout
111 * specification.
112 * @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter,
113 * see the specific function documentation.
114 */
115#define TIME_IMMEDIATE ((sysinterval_t)-1)
116
117/**
118 * @brief Infinite time specification for all functions with a timeout
119 * specification.
120 */
121#define TIME_INFINITE ((sysinterval_t)0)
122
123/**
124 * @brief Maximum interval constant usable as timeout.
125 */
126#define TIME_MAX_INTERVAL ((sysinterval_t)-2)
127
128/**
129 * @brief Maximum system of system time before it wraps.
130 */
131#define TIME_MAX_SYSTIME ((systime_t)-1)
132/** @} */
133
134/**
135 * @name Thread state related macros
136 * @{
137 */
138#define NIL_STATE_WTSTART (tstate_t)0 /**< @brief Thread not yet
139 started or terminated. */
140#define NIL_STATE_READY (tstate_t)1 /**< @brief Thread ready or
141 executing. */
142#define NIL_STATE_SLEEPING (tstate_t)2 /**< @brief Thread sleeping. */
143#define NIL_STATE_SUSPENDED (tstate_t)3 /**< @brief Thread suspended. */
144#define NIL_STATE_WTEXIT (tstate_t)4 /**< @brief Waiting a thread. */
145#define NIL_STATE_WTQUEUE (tstate_t)5 /**< @brief On queue or semaph. */
146#define NIL_STATE_WTOREVT (tstate_t)6 /**< @brief Waiting for events. */
147#define NIL_STATE_WTANDEVT (tstate_t)7 /**< @brief Waiting for events. */
148#define NIL_STATE_SNDMSGQ (tstate_t)8 /**< @brief Sending a message,
149 in queue. */
150#define NIL_STATE_WTMSG (tstate_t)10/**< @brief Waiting for a
151 message. */
152#define NIL_STATE_FINAL (tstate_t)11/**< @brief Thread terminated. */
153
154#define NIL_THD_IS_WTSTART(tp) ((tp)->state == NIL_STATE_WTSTART)
155#define NIL_THD_IS_READY(tp) ((tp)->state == NIL_STATE_READY)
156#define NIL_THD_IS_SLEEPING(tp) ((tp)->state == NIL_STATE_SLEEPING)
157#define NIL_THD_IS_SUSPENDED(tp) ((tp)->state == NIL_STATE_SUSPENDED)
158#define NIL_THD_IS_WTEXIT(tp) ((tp)->state == NIL_STATE_WTEXIT)
159#define NIL_THD_IS_WTQUEUE(tp) ((tp)->state == NIL_STATE_WTQUEUE)
160#define NIL_THD_IS_WTOREVT(tp) ((tp)->state == NIL_STATE_WTOREVT)
161#define NIL_THD_IS_WTANDEVT(tp) ((tp)->state == NIL_STATE_WTANDEVT)
162#define NIL_THD_IS_SNDMSGQ(tp) ((tp)->state == NIL_STATE_SNDMSGQ)
163#define NIL_THD_IS_WTMSG(tp) ((tp)->state == NIL_STATE_WTMSG)
164#define NIL_THD_IS_FINAL(tp) ((tp)->state == NIL_STATE_FINAL)
165
166#define CH_STATE_NAMES \
167 "WTSTART", "READY", "SLEEPING", "SUSPENDED", "WTEXIT", "WTQUEUE", \
168 "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", "WTMSG", "FINAL"
169/** @} */
170
171/**
172 * @name RT options not existing in NIL
173 * @{
174 */
175#define CH_CFG_USE_REGISTRY FALSE
176/** @} */
177
178/*===========================================================================*/
179/* Module pre-compile time settings. */
180/*===========================================================================*/
181
182#include "chconf.h"
183#include "chlicense.h"
184
185/*===========================================================================*/
186/* Derived constants and error checks. */
187/*===========================================================================*/
188
189/* Checks on configuration options.*/
190#if !defined(CH_CFG_MAX_THREADS) || defined(__DOXYGEN__)
191#error "CH_CFG_MAX_THREADS not defined in chconf.h"
192#endif
193
194#if !defined(CH_CFG_AUTOSTART_THREADS) || defined(__DOXYGEN__)
195#error "CH_CFG_AUTOSTART_THREADS not defined in chconf.h"
196#endif
197
198#if !defined(CH_CFG_ST_RESOLUTION) || defined(__DOXYGEN__)
199#error "CH_CFG_ST_RESOLUTION not defined in chconf.h"
200#endif
201
202#if !defined(CH_CFG_ST_FREQUENCY) || defined(__DOXYGEN__)
203#error "CH_CFG_ST_FREQUENCY not defined in chconf.h"
204#endif
205
206#if !defined(CH_CFG_ST_TIMEDELTA) || defined(__DOXYGEN__)
207#error "CH_CFG_ST_TIMEDELTA not defined in chconf.h"
208#endif
209
210#if !defined(CH_CFG_USE_WAITEXIT)
211#error "CH_CFG_USE_WAITEXIT not defined in chconf.h"
212#endif
213
214#if !defined(CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
215#error "CH_CFG_USE_MESSAGES not defined in chconf.h"
216#endif
217
218#if !defined(CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
219#error "CH_CFG_USE_SEMAPHORES not defined in chconf.h"
220#endif
221
222#if !defined(CH_CFG_USE_EVENTS)
223#error "CH_CFG_USE_EVENTS not defined in chconf.h"
224#endif
225
226#if !defined(CH_CFG_USE_MUTEXES) || defined(__DOXYGEN__)
227#error "CH_CFG_USE_MUTEXES not defined in chconf.h"
228#endif
229
230#if !defined(CH_DBG_STATISTICS) || defined(__DOXYGEN__)
231#error "CH_DBG_STATISTICS not defined in chconf.h"
232#endif
233
234#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
235#error "CH_DBG_SYSTEM_STATE_CHECK not defined in chconf.h"
236#endif
237
238#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
239#error "CH_DBG_ENABLE_CHECKS not defined in chconf.h"
240#endif
241
242#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
243#error "CH_DBG_ENABLE_ASSERTS not defined in chconf.h"
244#endif
245
246#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
247#error "CH_DBG_ENABLE_STACK_CHECK not defined in chconf.h"
248#endif
249
250#if !defined(CH_CFG_SYSTEM_INIT_HOOK) || defined(__DOXYGEN__)
251#error "CH_CFG_SYSTEM_INIT_HOOK not defined in chconf.h"
252#endif
253
254#if !defined(CH_CFG_THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
255#error "CH_CFG_THREAD_EXT_FIELDS not defined in chconf.h"
256#endif
257
258#if !defined(CH_CFG_THREAD_EXT_INIT_HOOK) || defined(__DOXYGEN__)
259#error "CH_CFG_THREAD_EXT_INIT_HOOK not defined in chconf.h"
260#endif
261
262#if !defined(CH_CFG_THREAD_EXIT_HOOK) || defined(__DOXYGEN__)
263#error "CH_CFG_THREAD_EXIT_HOOK not defined in chconf.h"
264#endif
265
266#if !defined(CH_CFG_IDLE_ENTER_HOOK) || defined(__DOXYGEN__)
267#error "CH_CFG_IDLE_ENTER_HOOK not defined in chconf.h"
268#endif
269
270#if !defined(CH_CFG_IDLE_LEAVE_HOOK) || defined(__DOXYGEN__)
271#error "CH_CFG_IDLE_LEAVE_HOOK not defined in chconf.h"
272#endif
273
274#if !defined(CH_CFG_SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
275#error "CH_CFG_SYSTEM_HALT_HOOK not defined in chconf.h"
276#endif
277
278/* License checks.*/
279#if !defined(CH_CUSTOMER_LIC_NIL) || !defined(CH_LICENSE_FEATURES)
280#error "malformed chlicense.h"
281#endif
282
283#if CH_CUSTOMER_LIC_NIL == FALSE
284#error "ChibiOS/NIL not licensed"
285#endif
286
287#if (CH_LICENSE_FEATURES != CH_FEATURES_FULL) && \
288 (CH_LICENSE_FEATURES != CH_FEATURES_INTERMEDIATE) && \
289 (CH_LICENSE_FEATURES != CH_FEATURES_BASIC)
290#error "invalid CH_LICENSE_FEATURES setting"
291#endif
292
293/* Restrictions in basic and intermediate modes.*/
294#if (CH_LICENSE_FEATURES == CH_FEATURES_INTERMEDIATE) || \
295 (CH_LICENSE_FEATURES == CH_FEATURES_BASIC)
296
297/* System tick limited to 1000hz.*/
298#if CH_CFG_ST_FREQUENCY > 1000
299#undef CH_CFG_ST_FREQUENCY
300#define CH_CFG_ST_FREQUENCY 1000
301#endif
302
303#endif /* (CH_LICENSE_FEATURES == CH_FEATURES_INTERMEDIATE) ||
304 (CH_LICENSE_FEATURES == CH_FEATURES_BASIC) */
305
306/* Restrictions in basic mode.*/
307#if CH_LICENSE_FEATURES == CH_FEATURES_BASIC
308
309/* Tick-Less mode restricted.*/
310#undef CH_CFG_ST_TIMEDELTA
311#define CH_CFG_ST_TIMEDELTA 0
312
313/* Messages restricted.*/
314#undef CH_CFG_USE_MESSAGES
315#define CH_CFG_USE_MESSAGES FALSE
316
317#endif /* CH_LICENSE_FEATURES == CH_FEATURES_BASIC */
318
319#if !defined(_CHIBIOS_NIL_CONF_)
320#error "missing or wrong configuration file"
321#endif
322
323#if !defined(_CHIBIOS_NIL_CONF_VER_4_0_)
324#error "obsolete or unknown configuration file"
325#endif
326
327#if CH_CFG_MAX_THREADS < 1
328#error "at least one thread must be defined"
329#endif
330
331#if CH_CFG_MAX_THREADS > 16
332#error "ChibiOS/NIL is not recommended for thread-intensive applications," \
333 "consider ChibiOS/RT instead"
334#endif
335
336#if (CH_CFG_ST_RESOLUTION != 16) && (CH_CFG_ST_RESOLUTION != 32)
337#error "invalid CH_CFG_ST_RESOLUTION specified, must be 16 or 32"
338#endif
339
340#if CH_CFG_ST_FREQUENCY <= 0
341#error "invalid CH_CFG_ST_FREQUENCY specified, must be greater than zero"
342#endif
343
344#if (CH_CFG_ST_TIMEDELTA < 0) || (CH_CFG_ST_TIMEDELTA == 1)
345#error "invalid CH_CFG_ST_TIMEDELTA specified, must " \
346 "be zero or greater than one"
347#endif
348
349#if CH_CFG_USE_MUTEXES == TRUE
350#error "mutexes not yet supported"
351#endif
352
353#if CH_DBG_STATISTICS == TRUE
354#error "statistics not yet supported"
355#endif
356
357#if (CH_DBG_SYSTEM_STATE_CHECK == TRUE) || \
358 (CH_DBG_ENABLE_CHECKS == TRUE) || \
359 (CH_DBG_ENABLE_ASSERTS == TRUE) || \
360 (CH_DBG_ENABLE_STACK_CHECK == TRUE)
361#define NIL_DBG_ENABLED TRUE
362#else
363#define NIL_DBG_ENABLED FALSE
364#endif
365
366/** Boundaries of the idle thread boundaries, only required if stack checking
367 is enabled.*/
368#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || defined(__DOXYGEN__)
369#define THD_IDLE_BASE (&__main_thread_stack_base__)
370#define THD_IDLE_END (&__main_thread_stack_end__)
371#else
372#define THD_IDLE_BASE NULL
373#define THD_IDLE_END NULL
374#endif
375
376/*===========================================================================*/
377/* Module data structures and types. */
378/*===========================================================================*/
379
380#if defined(PORT_DOES_NOT_PROVIDE_TYPES) || defined(__DOXYGEN__)
381/**
382 * @name Kernel types
383 * @{
384 */
385typedef port_rtcnt_t rtcnt_t; /**< Realtime counter. */
386typedef port_syssts_t syssts_t; /**< System status word. */
387typedef port_stkalign_t stkalign_t; /**< Stack alignment type. */
388
389#if (PORT_ARCH_REGISTERS_WIDTH == 32) || defined(__DOXYGEN__)
390typedef uint8_t tstate_t; /**< Thread state. */
391typedef uint32_t tprio_t; /**< Thread priority. */
392typedef int32_t msg_t; /**< Inter-thread message. */
393typedef int32_t eventid_t; /**< Numeric event identifier. */
394typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
395typedef uint32_t eventflags_t; /**< Mask of event flags. */
396typedef int32_t cnt_t; /**< Generic signed counter. */
397typedef uint32_t ucnt_t; /**< Generic unsigned counter. */
398#elif PORT_ARCH_REGISTERS_WIDTH == 16
399typedef uint8_t tstate_t; /**< Thread state. */
400typedef uint16_t tprio_t; /**< Thread priority. */
401typedef int16_t msg_t; /**< Inter-thread message. */
402typedef int16_t eventid_t; /**< Numeric event identifier. */
403typedef uint16_t eventmask_t; /**< Mask of event identifiers. */
404typedef uint16_t eventflags_t; /**< Mask of event flags. */
405typedef int16_t cnt_t; /**< Generic signed counter. */
406typedef uint16_t ucnt_t; /**< Generic unsigned counter. */
407#elif PORT_ARCH_REGISTERS_WIDTH == 8
408typedef uint8_t tstate_t; /**< Thread state. */
409typedef uint8_t tprio_t; /**< Thread priority. */
410typedef int16_t msg_t; /**< Inter-thread message. */
411typedef int8_t eventid_t; /**< Numeric event identifier. */
412typedef uint8_t eventmask_t; /**< Mask of event identifiers. */
413typedef uint8_t eventflags_t; /**< Mask of event flags. */
414typedef int8_t cnt_t; /**< Generic signed counter. */
415typedef uint8_t ucnt_t; /**< Generic unsigned counter. */
416#else
417#error "unsupported PORT_ARCH_REGISTERS_WIDTH value"
418#endif
419/** @} */
420#endif
421
422#if (CH_CFG_ST_RESOLUTION == 32) || defined(__DOXYGEN__)
423/**
424 * @brief Type of system time.
425 * @note It is selectable in configuration between 16 or 32 bits.
426 */
427typedef uint32_t systime_t;
428
429/**
430 * @brief Type of time interval.
431 * @note It is selectable in configuration between 16 or 32 bits.
432 */
433typedef uint32_t sysinterval_t;
434
435/**
436 * @brief Type of time conversion variable.
437 * @note This type must have double width than other time types, it is
438 * only used internally for conversions.
439 */
440typedef uint64_t time_conv_t;
441
442#else
443typedef uint16_t systime_t;
444typedef uint16_t sysinterval_t;
445typedef uint32_t time_conv_t;
446#endif
447
448/**
449 * @brief Type of a structure representing the system.
450 */
452
453/**
454 * @brief Thread function.
455 */
456typedef void (*tfunc_t)(void *p);
457
458/**
459 * @brief Type of a thread descriptor.
460 */
462
463/**
464 * @brief Type of a structure representing a thread.
465 * @note It is required as an early definition.
466 */
467typedef struct nil_thread thread_t;
468
469/**
470 * @brief Type of a thread reference.
471 */
473
474/**
475 * @brief Type of a queue of threads.
476 */
478
479#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
480/**
481 * @brief Type of a structure representing a semaphore.
482 * @note Semaphores are implemented on thread queues, the object is the
483 * same, the behavior is slightly different.
484 */
486#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
487
488/* Late inclusion of port core layer.*/
489#include "chcore.h"
490
491/* Recursive locks port capability assessed.*/
492#if defined(port_get_lock_status) && defined(port_is_locked)
493#define CH_PORT_SUPPORTS_RECURSIVE_LOCKS TRUE
494#else
495#define CH_PORT_SUPPORTS_RECURSIVE_LOCKS FALSE
496#endif
497
498/**
499 * @brief Structure representing a queue of threads.
500 */
502 volatile cnt_t cnt; /**< @brief Threads Queue counter. */
503};
504
505/**
506 * @brief Structure representing a thread descriptor.
507 */
509 const char *name; /**< @brief Thread name, for debugging. */
510 stkalign_t *wbase; /**< @brief Thread working area base. */
511 stkalign_t *wend; /**< @brief Thread working area end. */
512 tprio_t prio; /**< @brief Thread priority slot. */
513 tfunc_t funcp; /**< @brief Thread function. */
514 void *arg; /**< @brief Thread function argument. */
515};
516
517/**
518 * @brief Structure representing a thread.
519 */
521 struct port_context ctx; /**< @brief Processor context. */
522 tstate_t state; /**< @brief Thread state. */
523 /* Note, the following union contains a pointer/value while the thread is
524 in a sleeping state or a wake-up message when the thread is made ready.*/
525 union {
526 msg_t msg; /**< @brief Wake-up/exit message. */
527 void *p; /**< @brief Generic pointer. */
528 os_instance_t *nsp; /**< @brief Pointer to nil base struct. */
529 thread_reference_t *trp; /**< @brief Pointer to thread reference.*/
530 threads_queue_t *tqp; /**< @brief Pointer to thread queue. */
531 thread_t *tp; /**< @brief Pointer to thread. */
532#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
533 semaphore_t *semp; /**< @brief Pointer to semaphore. */
534#endif
535#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
536 eventmask_t ewmask; /**< @brief Enabled events mask. */
537#endif
538 } u1;
539 volatile sysinterval_t timeout; /**< @brief Timeout counter, zero
540 if disabled. */
541#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
542 eventmask_t epmask; /**< @brief Pending events mask. */
543#endif
544#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
545 msg_t sntmsg; /**< @brief Sent message. */
546#endif
547#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || defined(__DOXYGEN__)
548 stkalign_t *wabase; /**< @brief Thread stack boundary. */
549#endif
550 /* Optional extra fields.*/
552};
553
554/**
555 * @brief System data structure.
556 * @note This structure contain all the data areas used by the OS except
557 * stacks.
558 */
560 /**
561 * @brief Pointer to the running thread.
562 */
564 /**
565 * @brief Pointer to the next thread to be executed.
566 * @note This pointer must point at the same thread pointed by @p current
567 * or to an higher priority thread if a switch is required.
568 */
570#if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__)
571 /**
572 * @brief System time.
573 */
575#endif
576#if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__)
577 /**
578 * @brief System time of the last tick event.
579 */
581 /**
582 * @brief Time of the next scheduled tick event.
583 */
585#endif
586#if (CH_DBG_SYSTEM_STATE_CHECK == TRUE) || defined(__DOXYGEN__)
587 /**
588 * @brief ISR nesting level.
589 */
591 /**
592 * @brief Lock nesting level.
593 */
595#endif
596#if (NIL_DBG_ENABLED == TRUE) || defined(__DOXYGEN__)
597 /**
598 * @brief Panic message.
599 * @note This field is only present if some debug options have been
600 * activated.
601 * @note Accesses to this pointer must never be optimized out so the
602 * field itself is declared volatile.
603 */
604 const char * volatile dbg_panic_msg;
605#endif
606 /**
607 * @brief Thread structures for all the defined threads.
608 */
610};
611
612/*===========================================================================*/
613/* Module macros. */
614/*===========================================================================*/
615
616#if CH_DBG_SYSTEM_STATE_CHECK == TRUE
617#define __dbg_enter_lock() (nil.lock_cnt = (cnt_t)1)
618#define __dbg_leave_lock() (nil.lock_cnt = (cnt_t)0)
619#endif
620
621/**
622 * @brief Utility to make the parameter a quoted string.
623 */
624#define __CH_STRINGIFY(a) #a
625
626/**
627 * @name Threads tables definition macros
628 * @{
629 */
630/**
631 * @brief Start of user threads table.
632 */
633#define THD_TABLE_BEGIN \
634 const thread_descriptor_t nil_thd_configs[] = {
635
636/**
637 * @brief Entry of user threads table
638 */
639#define THD_TABLE_THREAD(_prio, _name, _wap, _funcp, _arg) \
640 { \
641 .name = (_name), \
642 .wbase = (_wap), \
643 .wend = THD_WORKING_AREA_END(_wap), \
644 .prio = (_prio), \
645 .funcp = (_funcp), \
646 .arg = (_arg) \
647 },
648
649/**
650 * @brief End of user threads table.
651 */
652#define THD_TABLE_END \
653 { \
654 .name = "idle", \
655 .wbase = THD_IDLE_BASE, \
656 .wend = THD_IDLE_END, \
657 .prio = CH_CFG_MAX_THREADS, \
658 .funcp = NULL, \
659 .arg = NULL \
660 } \
661};
662/** @} */
663
664/**
665 * @name Memory alignment support macros
666 * @{
667 */
668/**
669 * @brief Alignment mask constant.
670 *
671 * @param[in] a alignment, must be a power of two
672 */
673#define MEM_ALIGN_MASK(a) ((size_t)(a) - 1U)
674
675/**
676 * @brief Aligns to the previous aligned memory address.
677 *
678 * @param[in] p variable to be aligned
679 * @param[in] a alignment, must be a power of two
680 */
681#define MEM_ALIGN_PREV(p, a) ((size_t)(p) & ~MEM_ALIGN_MASK(a))
682
683/**
684 * @brief Aligns to the new aligned memory address.
685 *
686 * @param[in] p variable to be aligned
687 * @param[in] a alignment, must be a power of two
688 */
689#define MEM_ALIGN_NEXT(p, a) MEM_ALIGN_PREV((size_t)(p) + \
690 MEM_ALIGN_MASK(a), (a))
691
692/**
693 * @brief Returns whatever a pointer or memory size is aligned.
694 *
695 * @param[in] p variable to be aligned
696 * @param[in] a alignment, must be a power of two
697 */
698#define MEM_IS_ALIGNED(p, a) (((size_t)(p) & MEM_ALIGN_MASK(a)) == 0U)
699
700/**
701 * @brief Returns whatever a constant is a valid alignment.
702 * @details Valid alignments are powers of two.
703 *
704 * @param[in] a alignment to be checked, must be a constant
705 */
706#define MEM_IS_VALID_ALIGNMENT(a) \
707 (((size_t)(a) != 0U) && (((size_t)(a) & ((size_t)(a) - 1U)) == 0U))
708/** @} */
709
710/**
711 * @name Working Areas
712 * @{
713 */
714/**
715 * @brief Calculates the total Working Area size.
716 *
717 * @param[in] n the stack size to be assigned to the thread
718 * @return The total used memory in bytes.
719 *
720 * @api
721 */
722#define THD_WORKING_AREA_SIZE(n) MEM_ALIGN_NEXT(PORT_WA_SIZE(n), \
723 PORT_STACK_ALIGN)
724
725/**
726 * @brief Static working area allocation.
727 * @details This macro is used to allocate a static thread working area
728 * aligned as both position and size.
729 *
730 * @param[in] s the name to be assigned to the stack array
731 * @param[in] n the stack size to be assigned to the thread
732 *
733 * @api
734 */
735#define THD_WORKING_AREA(s, n) PORT_WORKING_AREA(s, n)
736/** @} */
737
738/**
739 * @brief Returns the top address of a working area.
740 * @note The parameter is assumed to be an array of @p stkalign_t. The
741 * macros is invalid for anything else.
742 *
743 * @param[in] wa working area array
744 *
745 * @api
746 */
747#define THD_WORKING_AREA_END(wa) \
748 ((wa) + ((sizeof wa) / sizeof (stkalign_t)))
749
750/**
751 * @name Threads abstraction macros
752 * @{
753 */
754/**
755 * @brief Thread declaration macro.
756 * @note Thread declarations should be performed using this macro because
757 * the port layer could define optimizations for thread functions.
758 */
759#define THD_FUNCTION(tname, arg) PORT_THD_FUNCTION(tname, arg)
760/** @} */
761
762/**
763 * @name ISRs abstraction macros
764 * @{
765 */
766/**
767 * @brief Priority level validation macro.
768 * @details This macro determines if the passed value is a valid priority
769 * level for the underlying architecture.
770 *
771 * @param[in] prio the priority level
772 * @return Priority range result.
773 * @retval false if the priority is invalid or if the architecture
774 * does not support priorities.
775 * @retval true if the priority is valid.
776 */
777#if defined(PORT_IRQ_IS_VALID_PRIORITY) || defined(__DOXYGEN__)
778#define CH_IRQ_IS_VALID_PRIORITY(prio) \
779 PORT_IRQ_IS_VALID_PRIORITY(prio)
780#else
781#define CH_IRQ_IS_VALID_PRIORITY(prio) false
782#endif
783
784/**
785 * @brief Priority level validation macro.
786 * @details This macro determines if the passed value is a valid priority
787 * level that cannot preempt the kernel critical zone.
788 *
789 * @param[in] prio the priority level
790 * @return Priority range result.
791 * @retval false if the priority is invalid or if the architecture
792 * does not support priorities.
793 * @retval true if the priority is valid.
794 */
795#if defined(PORT_IRQ_IS_VALID_KERNEL_PRIORITY) || defined(__DOXYGEN__)
796#define CH_IRQ_IS_VALID_KERNEL_PRIORITY(prio) \
797 PORT_IRQ_IS_VALID_KERNEL_PRIORITY(prio)
798#else
799#define CH_IRQ_IS_VALID_KERNEL_PRIORITY(prio) false
800#endif
801
802/**
803 * @brief IRQ handler enter code.
804 * @note Usually IRQ handlers functions are also declared naked.
805 * @note On some architectures this macro can be empty.
806 *
807 * @special
808 */
809#define CH_IRQ_PROLOGUE() \
810 PORT_IRQ_PROLOGUE(); \
811 __dbg_check_enter_isr()
812
813/**
814 * @brief IRQ handler exit code.
815 * @note Usually IRQ handlers function are also declared naked.
816 *
817 * @special
818 */
819#define CH_IRQ_EPILOGUE() \
820 __dbg_check_leave_isr(); \
821 PORT_IRQ_EPILOGUE()
822
823/**
824 * @brief Standard normal IRQ handler declaration.
825 * @note @p id can be a function name or a vector number depending on the
826 * port implementation.
827 *
828 * @special
829 */
830#define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
831/** @} */
832
833/**
834 * @name Fast ISRs abstraction macros
835 * @{
836 */
837/**
838 * @brief Standard fast IRQ handler declaration.
839 * @note @p id can be a function name or a vector number depending on the
840 * port implementation.
841 * @note Not all architectures support fast interrupts.
842 *
843 * @special
844 */
845#define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
846/** @} */
847
848/**
849 * @name Time conversion utilities
850 * @{
851 */
852/**
853 * @brief Seconds to time interval.
854 * @details Converts from seconds to system ticks number.
855 * @note The result is rounded upward to the next tick boundary.
856 * @note Use of this macro for large values is not secure because
857 * integer overflows, make sure your value can be correctly
858 * converted.
859 *
860 * @param[in] secs number of seconds
861 * @return The number of ticks.
862 *
863 * @api
864 */
865#define TIME_S2I(secs) \
866 ((sysinterval_t)((time_conv_t)(secs) * (time_conv_t)CH_CFG_ST_FREQUENCY))
867
868/**
869 * @brief Milliseconds to time interval.
870 * @details Converts from milliseconds to system ticks number.
871 * @note The result is rounded upward to the next tick boundary.
872 * @note Use of this macro for large values is not secure because
873 * integer overflows, make sure your value can be correctly
874 * converted.
875 *
876 * @param[in] msecs number of milliseconds
877 * @return The number of ticks.
878 *
879 * @api
880 */
881#define TIME_MS2I(msecs) \
882 ((sysinterval_t)((((time_conv_t)(msecs) * \
883 (time_conv_t)CH_CFG_ST_FREQUENCY) + \
884 (time_conv_t)999) / (time_conv_t)1000))
885
886/**
887 * @brief Microseconds to time interval.
888 * @details Converts from microseconds to system ticks number.
889 * @note The result is rounded upward to the next tick boundary.
890 * @note Use of this macro for large values is not secure because
891 * integer overflows, make sure your value can be correctly
892 * converted.
893 *
894 * @param[in] usecs number of microseconds
895 * @return The number of ticks.
896 *
897 * @api
898 */
899#define TIME_US2I(usecs) \
900 ((sysinterval_t)((((time_conv_t)(usecs) * \
901 (time_conv_t)CH_CFG_ST_FREQUENCY) + \
902 (time_conv_t)999999) / (time_conv_t)1000000))
903
904/**
905 * @brief Time interval to seconds.
906 * @details Converts from system ticks number to seconds.
907 * @note The result is rounded up to the next second boundary.
908 * @note Use of this macro for large values is not secure because
909 * integer overflows, make sure your value can be correctly
910 * converted.
911 *
912 * @param[in] interval interval in ticks
913 * @return The number of seconds.
914 *
915 * @api
916 */
917#define TIME_I2S(interval) \
918 (time_secs_t)(((time_conv_t)(interval) + \
919 (time_conv_t)CH_CFG_ST_FREQUENCY - \
920 (time_conv_t)1) / (time_conv_t)CH_CFG_ST_FREQUENCY)
921
922/**
923 * @brief Time interval to milliseconds.
924 * @details Converts from system ticks number to milliseconds.
925 * @note The result is rounded up to the next millisecond boundary.
926 * @note Use of this macro for large values is not secure because
927 * integer overflows, make sure your value can be correctly
928 * converted.
929 *
930 * @param[in] interval interval in ticks
931 * @return The number of milliseconds.
932 *
933 * @api
934 */
935#define TIME_I2MS(interval) \
936 (time_msecs_t)((((time_conv_t)(interval) * (time_conv_t)1000) + \
937 (time_conv_t)CH_CFG_ST_FREQUENCY - (time_conv_t)1) / \
938 (time_conv_t)CH_CFG_ST_FREQUENCY)
939
940/**
941 * @brief Time interval to microseconds.
942 * @details Converts from system ticks number to microseconds.
943 * @note The result is rounded up to the next microsecond boundary.
944 * @note Use of this macro for large values is not secure because
945 * integer overflows, make sure your value can be correctly
946 * converted.
947 *
948 * @param[in] interval interval in ticks
949 * @return The number of microseconds.
950 *
951 * @api
952 */
953#define TIME_I2US(interval) \
954 (time_usecs_t)((((time_conv_t)(interval) * (time_conv_t)1000000) + \
955 (time_conv_t)CH_CFG_ST_FREQUENCY - (time_conv_t)1) / \
956 (time_conv_t)CH_CFG_ST_FREQUENCY)
957/** @} */
958
959/**
960 * @name Threads queues
961 * @{
962 */
963/**
964 * @brief Data part of a static threads queue object initializer.
965 * @details This macro should be used when statically initializing a threads
966 * queue that is part of a bigger structure.
967 *
968 * @param[in] name the name of the threads queue variable
969 */
970#define __THREADS_QUEUE_DATA(name) {(cnt_t)0}
971
972/**
973 * @brief Static threads queue object initializer.
974 * @details Statically initialized threads queues require no explicit
975 * initialization using @p queue_init().
976 *
977 * @param[in] name the name of the threads queue variable
978 */
979#define THREADS_QUEUE_DECL(name) \
980 threads_queue_t name = __THREADS_QUEUE_DATA(name)
981/** @} */
982
983/**
984 * @name Macro Functions
985 * @{
986 */
987/**
988 * @brief Returns the current value of the system real time counter.
989 * @note This function is only available if the port layer supports the
990 * option @p PORT_SUPPORTS_RT.
991 *
992 * @return The value of the system realtime counter of
993 * type rtcnt_t.
994 *
995 * @xclass
996 */
997#if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__)
998#define chSysGetRealtimeCounterX() (rtcnt_t)port_rt_get_counter_value()
999#endif
1000
1001/**
1002 * @brief Raises the system interrupt priority mask to the maximum level.
1003 * @details All the maskable interrupt sources are disabled regardless their
1004 * hardware priority.
1005 * @note Do not invoke this API from within a kernel lock.
1006 *
1007 * @special
1008 */
1009#define chSysDisable() { \
1010 port_disable(); \
1011 __dbg_check_disable(); \
1012}
1013
1014/**
1015 * @brief Raises the system interrupt priority mask to system level.
1016 * @details The interrupt sources that should not be able to preempt the kernel
1017 * are disabled, interrupt sources with higher priority are still
1018 * enabled.
1019 * @note Do not invoke this API from within a kernel lock.
1020 * @note This API is no replacement for @p chSysLock(), the @p chSysLock()
1021 * could do more than just disable the interrupts.
1022 *
1023 * @special
1024 */
1025#define chSysSuspend() { \
1026 port_suspend(); \
1027 __dbg_check_suspend(); \
1028}
1029
1030/**
1031 * @brief Lowers the system interrupt priority mask to user level.
1032 * @details All the interrupt sources are enabled.
1033 * @note Do not invoke this API from within a kernel lock.
1034 * @note This API is no replacement for @p chSysUnlock(), the
1035 * @p chSysUnlock() could do more than just enable the interrupts.
1036 *
1037 * @special
1038 */
1039#define chSysEnable() { \
1040 __dbg_check_enable(); \
1041 port_enable(); \
1042}
1043
1044/**
1045 * @brief Enters the kernel lock state.
1046 *
1047 * @special
1048 */
1049#define chSysLock() { \
1050 port_lock(); \
1051 __dbg_check_lock(); \
1052}
1053
1054/**
1055 * @brief Leaves the kernel lock state.
1056 *
1057 * @special
1058 */
1059#define chSysUnlock() { \
1060 __dbg_check_unlock(); \
1061 port_unlock(); \
1062}
1063
1064/**
1065 * @brief Enters the kernel lock state from within an interrupt handler.
1066 * @note This API may do nothing on some architectures, it is required
1067 * because on ports that support preemptable interrupt handlers
1068 * it is required to raise the interrupt mask to the same level of
1069 * the system mutual exclusion zone.<br>
1070 * It is good practice to invoke this API before invoking any I-class
1071 * syscall from an interrupt handler.
1072 * @note This API must be invoked exclusively from interrupt handlers.
1073 *
1074 * @special
1075 */
1076#define chSysLockFromISR() { \
1077 port_lock_from_isr(); \
1078 __dbg_check_lock_from_isr(); \
1079}
1080
1081/**
1082 * @brief Leaves the kernel lock state from within an interrupt handler.
1083 *
1084 * @note This API may do nothing on some architectures, it is required
1085 * because on ports that support preemptable interrupt handlers
1086 * it is required to raise the interrupt mask to the same level of
1087 * the system mutual exclusion zone.<br>
1088 * It is good practice to invoke this API after invoking any I-class
1089 * syscall from an interrupt handler.
1090 * @note This API must be invoked exclusively from interrupt handlers.
1091 *
1092 * @special
1093 */
1094#define chSysUnlockFromISR() { \
1095 __dbg_check_unlock_from_isr(); \
1096 port_unlock_from_isr(); \
1097}
1098
1099/**
1100 * @brief Puts the current thread to sleep into the specified state.
1101 *
1102 * @param[in] newstate the new thread state or a semaphore pointer
1103 * @return The wakeup message.
1104 *
1105 * @sclass
1106 */
1107#define chSchGoSleepS(newstate) chSchGoSleepTimeoutS(newstate, TIME_INFINITE)
1108
1109/**
1110 * @brief Wakes up a thread.
1111 *
1112 * @param[in] ntp the thread to be made ready
1113 * @param[in] msg the wakeup message
1114 *
1115 * @sclass
1116 */
1117#define chSchWakeupS(ntp, msg) do { \
1118 chSchReadyI(ntp, msg); \
1119 chSchRescheduleS(); \
1120} while (false)
1121
1122/**
1123 * @brief Evaluates if a reschedule is required.
1124 *
1125 * @retval true if there is a thread that must go in running state
1126 * immediately.
1127 * @retval false if preemption is not required.
1128 *
1129 * @iclass
1130 */
1131#define chSchIsRescRequiredI() ((bool)(nil.current != nil.next))
1132
1133/**
1134 * @brief Returns a pointer to the current @p thread_t.
1135 *
1136 * @xclass
1137 */
1138#define chThdGetSelfX() nil.current
1139
1140/**
1141 * @brief Returns the current thread priority.
1142 * @note Can be invoked in any context.
1143 *
1144 * @return The current thread priority.
1145 *
1146 * @xclass
1147 */
1148#define chThdGetPriorityX(void) (tprio_t)(nil.current - &nil.threads[0])
1149
1150/**
1151 * @brief Wakes up a thread waiting on a thread reference object.
1152 * @note This function must reschedule, it can only be called from thread
1153 * context.
1154 *
1155 * @param[in] trp a pointer to a thread reference object
1156 * @param[in] msg the message code
1157 *
1158 * @sclass
1159 */
1160#define chThdResumeS(trp, msg) do { \
1161 chThdResumeI(trp, msg); \
1162 chSchRescheduleS(); \
1163} while (false)
1164
1165/**
1166 * @brief Delays the invoking thread for the specified number of seconds.
1167 * @note The specified time is rounded up to a value allowed by the real
1168 * system clock.
1169 * @note The maximum specified value is implementation dependent.
1170 *
1171 * @param[in] secs time in seconds, must be different from zero
1172 *
1173 * @api
1174 */
1175#define chThdSleepSeconds(secs) chThdSleep(TIME_S2I(secs))
1176
1177/**
1178 * @brief Delays the invoking thread for the specified number of
1179 * milliseconds.
1180 * @note The specified time is rounded up to a value allowed by the real
1181 * system clock.
1182 * @note The maximum specified value is implementation dependent.
1183 *
1184 * @param[in] msecs time in milliseconds, must be different from zero
1185 *
1186 * @api
1187 */
1188#define chThdSleepMilliseconds(msecs) chThdSleep(TIME_MS2I(msecs))
1189
1190/**
1191 * @brief Delays the invoking thread for the specified number of
1192 * microseconds.
1193 * @note The specified time is rounded up to a value allowed by the real
1194 * system clock.
1195 * @note The maximum specified value is implementation dependent.
1196 *
1197 * @param[in] usecs time in microseconds, must be different from zero
1198 *
1199 * @api
1200 */
1201#define chThdSleepMicroseconds(usecs) chThdSleep(TIME_US2I(usecs))
1202
1203/**
1204 * @brief Suspends the invoking thread for the specified time.
1205 *
1206 * @param[in] timeout the delay in system ticks
1207 *
1208 * @sclass
1209 */
1210#define chThdSleepS(timeout) \
1211 (void) chSchGoSleepTimeoutS(NIL_STATE_SLEEPING, timeout)
1212
1213/**
1214 * @brief Suspends the invoking thread until the system time arrives to the
1215 * specified value.
1216 *
1217 * @param[in] abstime absolute system time
1218 *
1219 * @sclass
1220 */
1221#define chThdSleepUntilS(abstime) \
1222 (void) chSchGoSleepTimeoutS(NIL_STATE_SLEEPING, \
1223 chTimeDiffX(chVTGetSystemTimeX(), (abstime)))
1224
1225/**
1226 * @brief Initializes a threads queue object.
1227 *
1228 * @param[out] tqp pointer to the threads queue object
1229 *
1230 * @init
1231 */
1232#define chThdQueueObjectInit(tqp) ((tqp)->cnt = (cnt_t)0)
1233
1234/**
1235 * @brief Evaluates to @p true if the specified queue is empty.
1236 *
1237 * @param[out] tqp pointer to the threads queue object
1238 * @return The queue status.
1239 * @retval false if the queue is not empty.
1240 * @retval true if the queue is empty.
1241 *
1242 * @iclass
1243 */
1244#define chThdQueueIsEmptyI(tqp) ((bool)(tqp->cnt >= (cnt_t)0))
1245
1246/**
1247 * @brief Current system time.
1248 * @details Returns the number of system ticks since the @p chSysInit()
1249 * invocation.
1250 * @note The counter can reach its maximum and then restart from zero.
1251 * @note This function can be called from any context but its atomicity
1252 * is not guaranteed on architectures whose word size is less than
1253 * @p systime_t size.
1254 *
1255 * @return The system time in ticks.
1256 *
1257 * @xclass
1258 */
1259#if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__)
1260#define chVTGetSystemTimeX() (nil.systime)
1261#else
1262#define chVTGetSystemTimeX() port_timer_get_time()
1263#endif
1264
1265/**
1266 * @brief Returns the elapsed time since the specified start time.
1267 *
1268 * @param[in] start start time
1269 * @return The elapsed time.
1270 *
1271 * @xclass
1272 */
1273#define chVTTimeElapsedSinceX(start) \
1274 chTimeDiffX((start), chVTGetSystemTimeX())
1275
1276/**
1277 * @brief Checks if the current system time is within the specified time
1278 * window.
1279 * @note When start==end then the function returns always false because the
1280 * time window has zero size.
1281 *
1282 * @param[in] start the start of the time window (inclusive)
1283 * @param[in] end the end of the time window (non inclusive)
1284 * @retval true current time within the specified time window.
1285 * @retval false current time not within the specified time window.
1286 *
1287 * @xclass
1288 */
1289#define chVTIsSystemTimeWithinX(start, end) \
1290 chTimeIsInRangeX(chVTGetSystemTimeX(), start, end)
1291
1292/**
1293 * @brief Adds an interval to a system time returning a system time.
1294 *
1295 * @param[in] systime base system time
1296 * @param[in] interval interval to be added
1297 * @return The new system time.
1298 *
1299 * @xclass
1300 */
1301#define chTimeAddX(systime, interval) \
1302 ((systime_t)(systime) + (systime_t)(interval))
1303
1304/**
1305 * @brief Subtracts two system times returning an interval.
1306 *
1307 * @param[in] start first system time
1308 * @param[in] end second system time
1309 * @return The interval representing the time difference.
1310 *
1311 * @xclass
1312 */
1313#define chTimeDiffX(start, end) \
1314 ((sysinterval_t)((systime_t)((systime_t)(end) - (systime_t)(start))))
1315
1316/**
1317 * @brief Function parameters check.
1318 * @details If the condition check fails then the kernel panics and halts.
1319 * @note The condition is tested only if the @p CH_DBG_ENABLE_CHECKS switch
1320 * is specified in @p chconf.h else the macro does nothing.
1321 *
1322 * @param[in] c the condition to be verified to be true
1323 *
1324 * @api
1325 */
1326#if !defined(chDbgCheck)
1327#define chDbgCheck(c) do { \
1328 /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \
1329 if (CH_DBG_ENABLE_CHECKS != FALSE) { \
1330 if (!(c)) { \
1331 /*lint -restore*/ \
1332 chSysHalt(__func__); \
1333 } \
1334 } \
1335} while (false)
1336#endif /* !defined(chDbgCheck) */
1337
1338/**
1339 * @brief Condition assertion.
1340 * @details If the condition check fails then the kernel panics with a
1341 * message and halts.
1342 * @note The condition is tested only if the @p CH_DBG_ENABLE_ASSERTS
1343 * switch is specified in @p chconf.h else the macro does nothing.
1344 * @note The remark string is not currently used except for putting a
1345 * comment in the code about the assertion.
1346 *
1347 * @param[in] c the condition to be verified to be true
1348 * @param[in] r a remark string
1349 *
1350 * @api
1351 */
1352#if !defined(chDbgAssert)
1353#define chDbgAssert(c, r) do { \
1354 /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \
1355 if (CH_DBG_ENABLE_ASSERTS != FALSE) { \
1356 if (!(c)) { \
1357 /*lint -restore*/ \
1358 chSysHalt(__func__); \
1359 } \
1360 } \
1361} while (false)
1362#endif /* !defined(chDbgAssert) */
1363/** @} */
1364
1365/* Empty macros if the state checker is not enabled.*/
1366#if CH_DBG_SYSTEM_STATE_CHECK == FALSE
1367#define __dbg_enter_lock()
1368#define __dbg_leave_lock()
1369#define __dbg_check_disable()
1370#define __dbg_check_suspend()
1371#define __dbg_check_enable()
1372#define __dbg_check_lock()
1373#define __dbg_check_unlock()
1374#define __dbg_check_lock_from_isr()
1375#define __dbg_check_unlock_from_isr()
1376#define __dbg_check_enter_isr()
1377#define __dbg_check_leave_isr()
1378#define chDbgCheckClassI()
1379#define chDbgCheckClassS()
1380#endif
1381
1382/*===========================================================================*/
1383/* External declarations. */
1384/*===========================================================================*/
1385
1386#if !defined(__DOXYGEN__)
1387#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || defined(__DOXYGEN__)
1389#endif
1390extern os_instance_t nil;
1391extern const thread_descriptor_t nil_thd_configs[];
1392#endif
1393
1394#ifdef __cplusplus
1395extern "C" {
1396#endif
1397 thread_t *nil_find_thread(tstate_t state, void *p);
1398 cnt_t nil_ready_all(void *p, cnt_t cnt, msg_t msg);
1399 void chSysInit(void);
1400 void chSysHalt(const char *reason);
1401 void chSysTimerHandlerI(void);
1402 void chSysUnconditionalLock(void);
1403 void chSysUnconditionalUnlock(void);
1405 bool chSysIsCounterWithinX(rtcnt_t cnt, rtcnt_t start, rtcnt_t end);
1406 void chSysPolledDelayX(rtcnt_t cycles);
1407 void chSysRestoreStatusX(syssts_t sts);
1409 bool chSchIsPreemptionRequired(void);
1410 void chSchDoPreemption(void);
1411 void chSchRescheduleS(void);
1413 bool chTimeIsInRangeX(systime_t time, systime_t start, systime_t end);
1416 void chThdExit(msg_t msg);
1417#if CH_CFG_USE_WAITEXIT == TRUE
1419#endif
1421 void chThdResumeI(thread_reference_t *trp, msg_t msg);
1422 void chThdResume(thread_reference_t *trp, msg_t msg);
1423 void chThdSleep(sysinterval_t timeout);
1424 void chThdSleepUntil(systime_t abstime);
1427 void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg);
1428 void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg);
1429#if CH_DBG_SYSTEM_STATE_CHECK == TRUE
1430 void __dbg_check_disable(void);
1431 void __dbg_check_suspend(void);
1432 void __dbg_check_enable(void);
1433 void __dbg_check_lock(void);
1434 void __dbg_check_unlock(void);
1435 void __dbg_check_lock_from_isr(void);
1436 void __dbg_check_unlock_from_isr(void);
1437 void __dbg_check_enter_isr(void);
1438 void __dbg_check_leave_isr(void);
1439 void chDbgCheckClassI(void);
1440 void chDbgCheckClassS(void);
1441#endif
1442#ifdef __cplusplus
1443}
1444#endif
1445
1446/* Optional modules.*/
1447#include "chsem.h"
1448#include "chevt.h"
1449#include "chmsg.h"
1450#include "chlib.h"
1451
1452#endif /* CH_H */
1453
1454/** @} */
Port related template macros and structures.
Nil RTOS events header file.
ChibiOS/LIB main include file.
License Module macros and structures.
Template port system types.
#define CH_CFG_THREAD_EXT_FIELDS
Threads descriptor structure extension.
#define CH_CFG_MAX_THREADS
Maximum number of user threads in the application.
#define __dbg_check_unlock()
int32_t cnt_t
struct nil_threads_queue threads_queue_t
Type of a queue of threads.
void(* tfunc_t)(void *p)
Thread function.
#define __dbg_check_leave_isr()
int32_t msg_t
#define __dbg_check_suspend()
uint32_t sysinterval_t
Type of time interval.
struct nil_os_instance os_instance_t
Type of a structure representing the system.
uint8_t tstate_t
os_instance_t nil
System data structures.
Definition ch.c:40
cnt_t nil_ready_all(void *p, cnt_t cnt, msg_t msg)
Puts in ready state all thread matching the specified status and associated object.
Definition ch.c:94
uint32_t tprio_t
#define chDbgCheckClassS()
#define __dbg_check_lock()
#define chDbgCheckClassI()
struct nil_thread thread_t
Type of a structure representing a thread.
uint32_t eventmask_t
thread_t * thread_reference_t
Type of a thread reference.
#define __dbg_check_disable()
thread_t * nil_find_thread(tstate_t state, void *p)
Retrieves the highest priority thread in the specified state and associated to the specified object.
Definition ch.c:69
#define __dbg_check_enter_isr()
#define __dbg_check_enable()
uint32_t systime_t
Type of system time.
threads_queue_t semaphore_t
Type of a structure representing a semaphore.
port_stkalign_t stkalign_t
#define __dbg_check_unlock_from_isr()
#define __dbg_check_lock_from_isr()
int32_t cnt_t
Definition chearly.h:91
uint32_t eventflags_t
Definition chearly.h:90
int32_t msg_t
Definition chearly.h:87
uint8_t tstate_t
Definition chearly.h:83
port_syssts_t syssts_t
Definition chearly.h:78
uint32_t tprio_t
Definition chearly.h:86
struct ch_os_instance os_instance_t
Type of an OS instance structure.
Definition chearly.h:137
port_rtcnt_t rtcnt_t
Definition chearly.h:76
uint32_t eventmask_t
Definition chearly.h:89
uint32_t ucnt_t
Definition chearly.h:92
thread_t * thread_reference_t
Type of a thread reference.
Definition chobjects.h:135
int32_t eventid_t
Definition chearly.h:88
port_stkalign_t stkalign_t
Definition chearly.h:79
struct ch_thread thread_t
Type of a thread structure.
Definition chearly.h:132
uint64_t port_stkalign_t
Type of stack and memory alignment enforcement.
Definition chtypes.h:71
uint32_t port_rtcnt_t
Realtime counter.
Definition chtypes.h:53
uint32_t port_syssts_t
System status word.
Definition chtypes.h:63
void chSchRescheduleS(void)
Performs a reschedule if a higher priority thread is runnable.
Definition chschd.c:457
thread_t * chSchReadyI(thread_t *tp)
Inserts a thread in the Ready List placing it behind its peers.
Definition chschd.c:279
bool chSchIsPreemptionRequired(void)
Evaluates if preemption is required.
Definition chschd.c:484
void chSchDoPreemption(void)
Switches to the first thread on the runnable queue.
Definition chschd.c:516
msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout)
Puts the current thread to sleep into the specified state with timeout specification.
Definition chschd.c:358
struct ch_semaphore semaphore_t
Semaphore structure.
stkalign_t __main_thread_stack_end__
Definition chsys.c:60
syssts_t chSysGetStatusAndLockX(void)
Returns the execution status and enters a critical zone.
Definition chsys.c:422
bool chSysIsCounterWithinX(rtcnt_t cnt, rtcnt_t start, rtcnt_t end)
Realtime window test.
Definition chsys.c:480
void chSysTimerHandlerI(void)
Handles time ticks for round robin preemption and timer increments.
Definition chsys.c:385
void chSysPolledDelayX(rtcnt_t cycles)
Polled delay.
Definition chsys.c:497
static void chSysUnconditionalLock(void)
Unconditionally enters the kernel lock state.
Definition chsys.h:489
void chSysRestoreStatusX(syssts_t sts)
Restores the specified execution status and leaves a critical zone.
Definition chsys.c:447
static void chSysUnconditionalUnlock(void)
Unconditionally leaves the kernel lock state.
Definition chsys.h:505
stkalign_t __main_thread_stack_base__
void chSysInit(void)
System initialization.
Definition chsys.c:158
void chSysHalt(const char *reason)
Halts the system.
Definition chsys.c:208
msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout)
Enqueues the caller thread on a threads queue object.
Definition chthreads.c:867
void(* tfunc_t)(void *p)
Thread function.
Definition chthreads.h:51
void chThdExit(msg_t msg)
Terminates the current thread.
Definition chthreads.c:478
msg_t chThdWait(thread_t *tp)
Blocks the execution of the invoking thread until the specified thread terminates then the exit code ...
Definition chthreads.c:559
void chThdResume(thread_reference_t *trp, msg_t msg)
Wakes up a thread waiting on a thread reference object.
Definition chthreads.c:837
msg_t chThdSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout)
Sends the current thread sleeping and sets a reference variable.
Definition chthreads.c:767
thread_t * chThdCreateI(const thread_descriptor_t *tdp)
Creates a new thread.
Definition chthreads.c:263
void chThdResumeI(thread_reference_t *trp, msg_t msg)
Wakes up a thread waiting on a thread reference object.
Definition chthreads.c:792
static void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg)
Dequeues and wakes up one thread from the threads queue object.
Definition chthreads.h:493
void chThdSleep(sysinterval_t time)
Suspends the invoking thread for the specified time.
Definition chthreads.c:654
void chThdSleepUntil(systime_t time)
Suspends the invoking thread until the system time arrives to the specified value.
Definition chthreads.c:674
void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg)
Dequeues and wakes up one thread from the threads queue object, if any.
Definition chthreads.c:888
thread_t * chThdCreate(const thread_descriptor_t *tdp)
Creates a new thread.
Definition chthreads.c:284
void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg)
Dequeues and wakes up all threads from the threads queue object.
Definition chthreads.c:903
uint64_t systime_t
Type of system time.
Definition chtime.h:106
static bool chTimeIsInRangeX(systime_t time, systime_t start, systime_t end)
Checks if the specified time is within the specified time range.
Definition chtime.h:483
uint64_t time_conv_t
Type of time conversion variable.
Definition chtime.h:154
uint64_t sysinterval_t
Type of time interval.
Definition chtime.h:118
Nil RTOS synchronous messages header file.
Nil RTOS semaphores header file.
System data structure.
thread_t * next
Pointer to the next thread to be executed.
cnt_t lock_cnt
Lock nesting level.
volatile systime_t systime
System time.
const char *volatile dbg_panic_msg
Panic message.
systime_t lasttime
System time of the last tick event.
thread_t threads[CH_CFG_MAX_THREADS+1]
Thread structures for all the defined threads.
thread_t * current
Pointer to the running thread.
systime_t nexttime
Time of the next scheduled tick event.
cnt_t isr_cnt
ISR nesting level.
Structure representing a thread descriptor.
stkalign_t * wend
Thread working area end.
tprio_t prio
Thread priority slot.
tfunc_t funcp
Thread function.
stkalign_t * wbase
Thread working area base.
const char * name
Thread name, for debugging.
void * arg
Thread function argument.
Structure representing a thread.
eventmask_t epmask
Pending events mask.
stkalign_t * wabase
Thread stack boundary.
thread_reference_t * trp
Pointer to thread reference.
struct port_context ctx
Processor context.
thread_t * tp
Pointer to thread.
msg_t msg
Wake-up/exit message.
union nil_thread::@026120306060255304310364300164041237270105045230 u1
msg_t sntmsg
Sent message.
void * p
Generic pointer.
eventmask_t ewmask
Enabled events mask.
volatile sysinterval_t timeout
Timeout counter, zero if disabled.
semaphore_t * semp
Pointer to semaphore.
tstate_t state
Thread state.
threads_queue_t * tqp
Pointer to thread queue.
os_instance_t * nsp
Pointer to nil base struct.
Structure representing a queue of threads.
volatile cnt_t cnt
Threads Queue counter.
Platform dependent part of the thread_t structure.
Definition chcore.h:168
Type of a thread descriptor.
Definition chthreads.h:56
Type of a thread queue.
Definition osal.h:238