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