ChibiOS  21.6.0
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 0
48 
49 /**
50  * @name ChibiOS/NIL version identification
51  * @{
52  */
53 /**
54  * @brief Kernel version string.
55  */
56 #define CH_KERNEL_VERSION "4.1.0"
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 0
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 /*===========================================================================*/
378 /* Module data structures and types. */
379 /*===========================================================================*/
380 
381 #if defined(PORT_DOES_NOT_PROVIDE_TYPES) || defined(__DOXYGEN__)
382 /**
383  * @name Kernel types
384  * @{
385  */
386 typedef port_rtcnt_t rtcnt_t; /**< Realtime counter. */
387 typedef port_syssts_t syssts_t; /**< System status word. */
388 typedef port_stkalign_t stkalign_t; /**< Stack alignment type. */
389 
390 #if (PORT_ARCH_REGISTERS_WIDTH == 32) || defined(__DOXYGEN__)
391 typedef uint8_t tstate_t; /**< Thread state. */
392 typedef uint32_t tprio_t; /**< Thread priority. */
393 typedef int32_t msg_t; /**< Inter-thread message. */
394 typedef int32_t eventid_t; /**< Numeric event identifier. */
395 typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
396 typedef uint32_t eventflags_t; /**< Mask of event flags. */
397 typedef int32_t cnt_t; /**< Generic signed counter. */
398 typedef uint32_t ucnt_t; /**< Generic unsigned counter. */
399 #elif PORT_ARCH_REGISTERS_WIDTH == 16
400 typedef uint8_t tstate_t; /**< Thread state. */
401 typedef uint16_t tprio_t; /**< Thread priority. */
402 typedef int16_t msg_t; /**< Inter-thread message. */
403 typedef int16_t eventid_t; /**< Numeric event identifier. */
404 typedef uint16_t eventmask_t; /**< Mask of event identifiers. */
405 typedef uint16_t eventflags_t; /**< Mask of event flags. */
406 typedef int16_t cnt_t; /**< Generic signed counter. */
407 typedef uint16_t ucnt_t; /**< Generic unsigned counter. */
408 #elif PORT_ARCH_REGISTERS_WIDTH == 8
409 typedef uint8_t tstate_t; /**< Thread state. */
410 typedef uint8_t tprio_t; /**< Thread priority. */
411 typedef int16_t msg_t; /**< Inter-thread message. */
412 typedef int8_t eventid_t; /**< Numeric event identifier. */
413 typedef uint8_t eventmask_t; /**< Mask of event identifiers. */
414 typedef uint8_t eventflags_t; /**< Mask of event flags. */
415 typedef int8_t cnt_t; /**< Generic signed counter. */
416 typedef uint8_t ucnt_t; /**< Generic unsigned counter. */
417 #else
418 #error "unsupported PORT_ARCH_REGISTERS_WIDTH value"
419 #endif
420 /** @} */
421 #endif /* defined(PORT_DOES_NOT_PROVIDE_TYPES) */
422 
423 #if (CH_CFG_ST_RESOLUTION == 32) || defined(__DOXYGEN__)
424 /**
425  * @brief Type of system time.
426  * @note It is selectable in configuration between 16 or 32 bits.
427  */
428 typedef uint32_t systime_t;
429 
430 /**
431  * @brief Type of time interval.
432  * @note It is selectable in configuration between 16 or 32 bits.
433  */
434 typedef uint32_t sysinterval_t;
435 
436 /**
437  * @brief Type of time conversion variable.
438  * @note This type must have double width than other time types, it is
439  * only used internally for conversions.
440  */
441 typedef uint64_t time_conv_t;
442 
443 #else
444 typedef uint16_t systime_t;
445 typedef uint16_t sysinterval_t;
446 typedef uint32_t time_conv_t;
447 #endif
448 
449 /**
450  * @brief Type of a structure representing the system.
451  */
453 
454 /**
455  * @brief Thread function.
456  */
457 typedef void (*tfunc_t)(void *p);
458 
459 /**
460  * @brief Type of a thread descriptor.
461  */
463 
464 /**
465  * @brief Type of a structure representing a thread.
466  * @note It is required as an early definition.
467  */
468 typedef struct nil_thread thread_t;
469 
470 /**
471  * @brief Type of a thread reference.
472  */
474 
475 /**
476  * @brief Type of a queue of threads.
477  */
479 
480 #if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
481 /**
482  * @brief Type of a structure representing a semaphore.
483  * @note Semaphores are implemented on thread queues, the object is the
484  * same, the behavior is slightly different.
485  */
487 #endif /* CH_CFG_USE_SEMAPHORES == TRUE */
488 
489 /* Late inclusion of port core layer.*/
490 #include "chcore.h"
491 
492 /**
493  * @brief Structure representing a queue of threads.
494  */
496  volatile cnt_t cnt; /**< @brief Threads Queue counter. */
497 };
498 
499 /**
500  * @brief Structure representing a thread descriptor.
501  */
503  const char *name; /**< @brief Thread name, for debugging. */
504  stkalign_t *wbase; /**< @brief Thread working area base. */
505  stkalign_t *wend; /**< @brief Thread working area end. */
506  tprio_t prio; /**< @brief Thread priority slot. */
507  tfunc_t funcp; /**< @brief Thread function. */
508  void *arg; /**< @brief Thread function argument. */
509 };
510 
511 /**
512  * @brief Structure representing a thread.
513  */
514 struct nil_thread {
515  struct port_context ctx; /**< @brief Processor context. */
516  tstate_t state; /**< @brief Thread state. */
517  /* Note, the following union contains a pointer/value while the thread is
518  in a sleeping state or a wake-up message when the thread is made ready.*/
519  union {
520  msg_t msg; /**< @brief Wake-up/exit message. */
521  void *p; /**< @brief Generic pointer. */
522  os_instance_t *nsp; /**< @brief Pointer to nil base struct. */
523  thread_reference_t *trp; /**< @brief Pointer to thread reference.*/
524  threads_queue_t *tqp; /**< @brief Pointer to thread queue. */
525  thread_t *tp; /**< @brief Pointer to thread. */
526 #if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
527  semaphore_t *semp; /**< @brief Pointer to semaphore. */
528 #endif
529 #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
530  eventmask_t ewmask; /**< @brief Enabled events mask. */
531 #endif
532  } u1;
533  volatile sysinterval_t timeout; /**< @brief Timeout counter, zero
534  if disabled. */
535 #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
536  eventmask_t epmask; /**< @brief Pending events mask. */
537 #endif
538 #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
539  msg_t sntmsg; /**< @brief Sent message. */
540 #endif
541 #if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || defined(__DOXYGEN__)
542  stkalign_t *wabase; /**< @brief Thread stack boundary. */
543 #endif
544  /* Optional extra fields.*/
546 };
547 
548 /**
549  * @brief System data structure.
550  * @note This structure contain all the data areas used by the OS except
551  * stacks.
552  */
554  /**
555  * @brief Pointer to the running thread.
556  */
558  /**
559  * @brief Pointer to the next thread to be executed.
560  * @note This pointer must point at the same thread pointed by @p current
561  * or to an higher priority thread if a switch is required.
562  */
564 #if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__)
565  /**
566  * @brief System time.
567  */
568  volatile systime_t systime;
569 #endif
570 #if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__)
571  /**
572  * @brief System time of the last tick event.
573  */
575  /**
576  * @brief Time of the next scheduled tick event.
577  */
579 #endif
580 #if (CH_DBG_SYSTEM_STATE_CHECK == TRUE) || defined(__DOXYGEN__)
581  /**
582  * @brief ISR nesting level.
583  */
585  /**
586  * @brief Lock nesting level.
587  */
589 #endif
590 #if (NIL_DBG_ENABLED == TRUE) || defined(__DOXYGEN__)
591  /**
592  * @brief Panic message.
593  * @note This field is only present if some debug options have been
594  * activated.
595  * @note Accesses to this pointer must never be optimized out so the
596  * field itself is declared volatile.
597  */
598  const char * volatile dbg_panic_msg;
599 #endif
600  /**
601  * @brief Thread structures for all the defined threads.
602  */
604 };
605 
606 /*===========================================================================*/
607 /* Module macros. */
608 /*===========================================================================*/
609 
610 #if CH_DBG_SYSTEM_STATE_CHECK == TRUE
611 #define __dbg_enter_lock() (nil.lock_cnt = (cnt_t)1)
612 #define __dbg_leave_lock() (nil.lock_cnt = (cnt_t)0)
613 #endif
614 
615 /**
616  * @brief Utility to make the parameter a quoted string.
617  */
618 #define __CH_STRINGIFY(a) #a
619 
620 /**
621  * @name Threads tables definition macros
622  * @{
623  */
624 /**
625  * @brief Start of user threads table.
626  */
627 #define THD_TABLE_BEGIN \
628  const thread_descriptor_t nil_thd_configs[] = {
629 
630 /**
631  * @brief Entry of user threads table
632  */
633 #define THD_TABLE_THREAD(_prio, _name, _wap, _funcp, _arg) \
634  { \
635  .name = (_name), \
636  .wbase = (_wap), \
637  .wend = THD_WORKING_AREA_END(_wap), \
638  .prio = (_prio), \
639  .funcp = (_funcp), \
640  .arg = (_arg) \
641  },
642 
643 /**
644  * @brief End of user threads table.
645  */
646 #define THD_TABLE_END \
647  { \
648  .name = "idle", \
649  .wbase = THD_IDLE_BASE, \
650  .wend = THD_IDLE_END, \
651  .prio = CH_CFG_MAX_THREADS, \
652  .funcp = NULL, \
653  .arg = NULL \
654  } \
655 };
656 /** @} */
657 
658 /**
659  * @name Memory alignment support macros
660  * @{
661  */
662 /**
663  * @brief Alignment mask constant.
664  *
665  * @param[in] a alignment, must be a power of two
666  */
667 #define MEM_ALIGN_MASK(a) ((size_t)(a) - 1U)
668 
669 /**
670  * @brief Aligns to the previous aligned memory address.
671  *
672  * @param[in] p variable to be aligned
673  * @param[in] a alignment, must be a power of two
674  */
675 #define MEM_ALIGN_PREV(p, a) ((size_t)(p) & ~MEM_ALIGN_MASK(a))
676 
677 /**
678  * @brief Aligns to the new aligned memory address.
679  *
680  * @param[in] p variable to be aligned
681  * @param[in] a alignment, must be a power of two
682  */
683 #define MEM_ALIGN_NEXT(p, a) MEM_ALIGN_PREV((size_t)(p) + \
684  MEM_ALIGN_MASK(a), (a))
685 
686 /**
687  * @brief Returns whatever a pointer or memory size is aligned.
688  *
689  * @param[in] p variable to be aligned
690  * @param[in] a alignment, must be a power of two
691  */
692 #define MEM_IS_ALIGNED(p, a) (((size_t)(p) & MEM_ALIGN_MASK(a)) == 0U)
693 
694 /**
695  * @brief Returns whatever a constant is a valid alignment.
696  * @details Valid alignments are powers of two.
697  *
698  * @param[in] a alignment to be checked, must be a constant
699  */
700 #define MEM_IS_VALID_ALIGNMENT(a) \
701  (((size_t)(a) != 0U) && (((size_t)(a) & ((size_t)(a) - 1U)) == 0U))
702 /** @} */
703 
704 /**
705  * @name Working Areas
706  * @{
707  */
708 /**
709  * @brief Calculates the total Working Area size.
710  *
711  * @param[in] n the stack size to be assigned to the thread
712  * @return The total used memory in bytes.
713  *
714  * @api
715  */
716 #define THD_WORKING_AREA_SIZE(n) MEM_ALIGN_NEXT(PORT_WA_SIZE(n), \
717  PORT_STACK_ALIGN)
718 
719 /**
720  * @brief Static working area allocation.
721  * @details This macro is used to allocate a static thread working area
722  * aligned as both position and size.
723  *
724  * @param[in] s the name to be assigned to the stack array
725  * @param[in] n the stack size to be assigned to the thread
726  *
727  * @api
728  */
729 #define THD_WORKING_AREA(s, n) PORT_WORKING_AREA(s, n)
730 /** @} */
731 
732 /**
733  * @brief Returns the top address of a working area.
734  * @note The parameter is assumed to be an array of @p stkalign_t. The
735  * macros is invalid for anything else.
736  *
737  * @param[in] wa working area array
738  *
739  * @api
740  */
741 #define THD_WORKING_AREA_END(wa) \
742  ((wa) + ((sizeof wa) / sizeof (stkalign_t)))
743 
744 /**
745  * @name Threads abstraction macros
746  * @{
747  */
748 /**
749  * @brief Thread declaration macro.
750  * @note Thread declarations should be performed using this macro because
751  * the port layer could define optimizations for thread functions.
752  */
753 #define THD_FUNCTION(tname, arg) PORT_THD_FUNCTION(tname, arg)
754 /** @} */
755 
756 /**
757  * @name ISRs abstraction macros
758  * @{
759  */
760 /**
761  * @brief Priority level validation macro.
762  * @details This macro determines if the passed value is a valid priority
763  * level for the underlying architecture.
764  *
765  * @param[in] prio the priority level
766  * @return Priority range result.
767  * @retval false if the priority is invalid or if the architecture
768  * does not support priorities.
769  * @retval true if the priority is valid.
770  */
771 #if defined(PORT_IRQ_IS_VALID_PRIORITY) || defined(__DOXYGEN__)
772 #define CH_IRQ_IS_VALID_PRIORITY(prio) \
773  PORT_IRQ_IS_VALID_PRIORITY(prio)
774 #else
775 #define CH_IRQ_IS_VALID_PRIORITY(prio) false
776 #endif
777 
778 /**
779  * @brief Priority level validation macro.
780  * @details This macro determines if the passed value is a valid priority
781  * level that cannot preempt the kernel critical zone.
782  *
783  * @param[in] prio the priority level
784  * @return Priority range result.
785  * @retval false if the priority is invalid or if the architecture
786  * does not support priorities.
787  * @retval true if the priority is valid.
788  */
789 #if defined(PORT_IRQ_IS_VALID_KERNEL_PRIORITY) || defined(__DOXYGEN__)
790 #define CH_IRQ_IS_VALID_KERNEL_PRIORITY(prio) \
791  PORT_IRQ_IS_VALID_KERNEL_PRIORITY(prio)
792 #else
793 #define CH_IRQ_IS_VALID_KERNEL_PRIORITY(prio) false
794 #endif
795 
796 /**
797  * @brief IRQ handler enter code.
798  * @note Usually IRQ handlers functions are also declared naked.
799  * @note On some architectures this macro can be empty.
800  *
801  * @special
802  */
803 #define CH_IRQ_PROLOGUE() \
804  PORT_IRQ_PROLOGUE(); \
805  __dbg_check_enter_isr()
806 
807 /**
808  * @brief IRQ handler exit code.
809  * @note Usually IRQ handlers function are also declared naked.
810  *
811  * @special
812  */
813 #define CH_IRQ_EPILOGUE() \
814  __dbg_check_leave_isr(); \
815  PORT_IRQ_EPILOGUE()
816 
817 /**
818  * @brief Standard normal IRQ handler declaration.
819  * @note @p id can be a function name or a vector number depending on the
820  * port implementation.
821  *
822  * @special
823  */
824 #define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
825 /** @} */
826 
827 /**
828  * @name Fast ISRs abstraction macros
829  * @{
830  */
831 /**
832  * @brief Standard fast IRQ handler declaration.
833  * @note @p id can be a function name or a vector number depending on the
834  * port implementation.
835  * @note Not all architectures support fast interrupts.
836  *
837  * @special
838  */
839 #define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
840 /** @} */
841 
842 /**
843  * @name Time conversion utilities
844  * @{
845  */
846 /**
847  * @brief Seconds to time interval.
848  * @details Converts from seconds to system ticks number.
849  * @note The result is rounded upward to the next tick boundary.
850  * @note Use of this macro for large values is not secure because
851  * integer overflows, make sure your value can be correctly
852  * converted.
853  *
854  * @param[in] secs number of seconds
855  * @return The number of ticks.
856  *
857  * @api
858  */
859 #define TIME_S2I(secs) \
860  ((sysinterval_t)((time_conv_t)(secs) * (time_conv_t)CH_CFG_ST_FREQUENCY))
861 
862 /**
863  * @brief Milliseconds to time interval.
864  * @details Converts from milliseconds to system ticks number.
865  * @note The result is rounded upward to the next tick boundary.
866  * @note Use of this macro for large values is not secure because
867  * integer overflows, make sure your value can be correctly
868  * converted.
869  *
870  * @param[in] msecs number of milliseconds
871  * @return The number of ticks.
872  *
873  * @api
874  */
875 #define TIME_MS2I(msecs) \
876  ((sysinterval_t)((((time_conv_t)(msecs) * \
877  (time_conv_t)CH_CFG_ST_FREQUENCY) + \
878  (time_conv_t)999) / (time_conv_t)1000))
879 
880 /**
881  * @brief Microseconds to time interval.
882  * @details Converts from microseconds to system ticks number.
883  * @note The result is rounded upward to the next tick boundary.
884  * @note Use of this macro for large values is not secure because
885  * integer overflows, make sure your value can be correctly
886  * converted.
887  *
888  * @param[in] usecs number of microseconds
889  * @return The number of ticks.
890  *
891  * @api
892  */
893 #define TIME_US2I(usecs) \
894  ((sysinterval_t)((((time_conv_t)(usecs) * \
895  (time_conv_t)CH_CFG_ST_FREQUENCY) + \
896  (time_conv_t)999999) / (time_conv_t)1000000))
897 
898 /**
899  * @brief Time interval to seconds.
900  * @details Converts from system ticks number to seconds.
901  * @note The result is rounded up to the next second boundary.
902  * @note Use of this macro for large values is not secure because
903  * integer overflows, make sure your value can be correctly
904  * converted.
905  *
906  * @param[in] interval interval in ticks
907  * @return The number of seconds.
908  *
909  * @api
910  */
911 #define TIME_I2S(interval) \
912  (time_secs_t)(((time_conv_t)(interval) + \
913  (time_conv_t)CH_CFG_ST_FREQUENCY - \
914  (time_conv_t)1) / (time_conv_t)CH_CFG_ST_FREQUENCY)
915 
916 /**
917  * @brief Time interval to milliseconds.
918  * @details Converts from system ticks number to milliseconds.
919  * @note The result is rounded up to the next millisecond boundary.
920  * @note Use of this macro for large values is not secure because
921  * integer overflows, make sure your value can be correctly
922  * converted.
923  *
924  * @param[in] interval interval in ticks
925  * @return The number of milliseconds.
926  *
927  * @api
928  */
929 #define TIME_I2MS(interval) \
930  (time_msecs_t)((((time_conv_t)(interval) * (time_conv_t)1000) + \
931  (time_conv_t)CH_CFG_ST_FREQUENCY - (time_conv_t)1) / \
932  (time_conv_t)CH_CFG_ST_FREQUENCY)
933 
934 /**
935  * @brief Time interval to microseconds.
936  * @details Converts from system ticks number to microseconds.
937  * @note The result is rounded up to the next microsecond boundary.
938  * @note Use of this macro for large values is not secure because
939  * integer overflows, make sure your value can be correctly
940  * converted.
941  *
942  * @param[in] interval interval in ticks
943  * @return The number of microseconds.
944  *
945  * @api
946  */
947 #define TIME_I2US(interval) \
948  (time_msecs_t)((((time_conv_t)(interval) * (time_conv_t)1000000) + \
949  (time_conv_t)CH_CFG_ST_FREQUENCY - (time_conv_t)1) / \
950  (time_conv_t)CH_CFG_ST_FREQUENCY)
951 /** @} */
952 
953 /**
954  * @name Threads queues
955  * @{
956  */
957 /**
958  * @brief Data part of a static threads queue object initializer.
959  * @details This macro should be used when statically initializing a threads
960  * queue that is part of a bigger structure.
961  *
962  * @param[in] name the name of the threads queue variable
963  */
964 #define __THREADS_QUEUE_DATA(name) {(cnt_t)0}
965 
966 /**
967  * @brief Static threads queue object initializer.
968  * @details Statically initialized threads queues require no explicit
969  * initialization using @p queue_init().
970  *
971  * @param[in] name the name of the threads queue variable
972  */
973 #define THREADS_QUEUE_DECL(name) \
974  threads_queue_t name = __THREADS_QUEUE_DATA(name)
975 /** @} */
976 
977 /**
978  * @name Macro Functions
979  * @{
980  */
981 /**
982  * @brief Returns the current value of the system real time counter.
983  * @note This function is only available if the port layer supports the
984  * option @p PORT_SUPPORTS_RT.
985  *
986  * @return The value of the system realtime counter of
987  * type rtcnt_t.
988  *
989  * @xclass
990  */
991 #if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__)
992 #define chSysGetRealtimeCounterX() (rtcnt_t)port_rt_get_counter_value()
993 #endif
994 
995 /**
996  * @brief Raises the system interrupt priority mask to the maximum level.
997  * @details All the maskable interrupt sources are disabled regardless their
998  * hardware priority.
999  * @note Do not invoke this API from within a kernel lock.
1000  *
1001  * @special
1002  */
1003 #define chSysDisable() { \
1004  port_disable(); \
1005  __dbg_check_disable(); \
1006 }
1007 
1008 /**
1009  * @brief Raises the system interrupt priority mask to system level.
1010  * @details The interrupt sources that should not be able to preempt the kernel
1011  * are disabled, interrupt sources with higher priority are still
1012  * enabled.
1013  * @note Do not invoke this API from within a kernel lock.
1014  * @note This API is no replacement for @p chSysLock(), the @p chSysLock()
1015  * could do more than just disable the interrupts.
1016  *
1017  * @special
1018  */
1019 #define chSysSuspend() { \
1020  port_suspend(); \
1021  __dbg_check_suspend(); \
1022 }
1023 
1024 /**
1025  * @brief Lowers the system interrupt priority mask to user level.
1026  * @details All the interrupt sources are enabled.
1027  * @note Do not invoke this API from within a kernel lock.
1028  * @note This API is no replacement for @p chSysUnlock(), the
1029  * @p chSysUnlock() could do more than just enable the interrupts.
1030  *
1031  * @special
1032  */
1033 #define chSysEnable() { \
1034  __dbg_check_enable(); \
1035  port_enable(); \
1036 }
1037 
1038 /**
1039  * @brief Enters the kernel lock state.
1040  *
1041  * @special
1042  */
1043 #define chSysLock() { \
1044  port_lock(); \
1045  __dbg_check_lock(); \
1046 }
1047 
1048 /**
1049  * @brief Leaves the kernel lock state.
1050  *
1051  * @special
1052  */
1053 #define chSysUnlock() { \
1054  __dbg_check_unlock(); \
1055  port_unlock(); \
1056 }
1057 
1058 /**
1059  * @brief Enters the kernel lock state from within an interrupt handler.
1060  * @note This API may do nothing on some architectures, it is required
1061  * because on ports that support preemptable interrupt handlers
1062  * it is required to raise the interrupt mask to the same level of
1063  * the system mutual exclusion zone.<br>
1064  * It is good practice to invoke this API before invoking any I-class
1065  * syscall from an interrupt handler.
1066  * @note This API must be invoked exclusively from interrupt handlers.
1067  *
1068  * @special
1069  */
1070 #define chSysLockFromISR() { \
1071  port_lock_from_isr(); \
1072  __dbg_check_lock_from_isr(); \
1073 }
1074 
1075 /**
1076  * @brief Leaves the kernel lock state from within an interrupt handler.
1077  *
1078  * @note This API may do nothing on some architectures, it is required
1079  * because on ports that support preemptable interrupt handlers
1080  * it is required to raise the interrupt mask to the same level of
1081  * the system mutual exclusion zone.<br>
1082  * It is good practice to invoke this API after invoking any I-class
1083  * syscall from an interrupt handler.
1084  * @note This API must be invoked exclusively from interrupt handlers.
1085  *
1086  * @special
1087  */
1088 #define chSysUnlockFromISR() { \
1089  __dbg_check_unlock_from_isr(); \
1090  port_unlock_from_isr(); \
1091 }
1092 
1093 /**
1094  * @brief Puts the current thread to sleep into the specified state.
1095  *
1096  * @param[in] newstate the new thread state or a semaphore pointer
1097  * @return The wakeup message.
1098  *
1099  * @sclass
1100  */
1101 #define chSchGoSleepS(newstate) chSchGoSleepTimeoutS(newstate, TIME_INFINITE)
1102 
1103 /**
1104  * @brief Wakes up a thread.
1105  *
1106  * @param[in] ntp the thread to be made ready
1107  * @param[in] msg the wakeup message
1108  *
1109  * @sclass
1110  */
1111 #define chSchWakeupS(ntp, msg) do { \
1112  chSchReadyI(ntp, msg); \
1113  chSchRescheduleS(); \
1114 } while (false)
1115 
1116 /**
1117  * @brief Evaluates if a reschedule is required.
1118  *
1119  * @retval true if there is a thread that must go in running state
1120  * immediately.
1121  * @retval false if preemption is not required.
1122  *
1123  * @iclass
1124  */
1125 #define chSchIsRescRequiredI() ((bool)(nil.current != nil.next))
1126 
1127 /**
1128  * @brief Returns a pointer to the current @p thread_t.
1129  *
1130  * @xclass
1131  */
1132 #define chThdGetSelfX() nil.current
1133 
1134 /**
1135  * @brief Returns the current thread priority.
1136  * @note Can be invoked in any context.
1137  *
1138  * @return The current thread priority.
1139  *
1140  * @xclass
1141  */
1142 #define chThdGetPriorityX(void) (tprio_t)(nil.current - &nil.threads[0])
1143 
1144 /**
1145  * @brief Wakes up a thread waiting on a thread reference object.
1146  * @note This function must reschedule, it can only be called from thread
1147  * context.
1148  *
1149  * @param[in] trp a pointer to a thread reference object
1150  * @param[in] msg the message code
1151  *
1152  * @sclass
1153  */
1154 #define chThdResumeS(trp, msg) do { \
1155  chThdResumeI(trp, msg); \
1156  chSchRescheduleS(); \
1157 } while (false)
1158 
1159 /**
1160  * @brief Delays the invoking thread for the specified number of seconds.
1161  * @note The specified time is rounded up to a value allowed by the real
1162  * system clock.
1163  * @note The maximum specified value is implementation dependent.
1164  *
1165  * @param[in] secs time in seconds, must be different from zero
1166  *
1167  * @api
1168  */
1169 #define chThdSleepSeconds(secs) chThdSleep(TIME_S2I(secs))
1170 
1171 /**
1172  * @brief Delays the invoking thread for the specified number of
1173  * milliseconds.
1174  * @note The specified time is rounded up to a value allowed by the real
1175  * system clock.
1176  * @note The maximum specified value is implementation dependent.
1177  *
1178  * @param[in] msecs time in milliseconds, must be different from zero
1179  *
1180  * @api
1181  */
1182 #define chThdSleepMilliseconds(msecs) chThdSleep(TIME_MS2I(msecs))
1183 
1184 /**
1185  * @brief Delays the invoking thread for the specified number of
1186  * microseconds.
1187  * @note The specified time is rounded up to a value allowed by the real
1188  * system clock.
1189  * @note The maximum specified value is implementation dependent.
1190  *
1191  * @param[in] usecs time in microseconds, must be different from zero
1192  *
1193  * @api
1194  */
1195 #define chThdSleepMicroseconds(usecs) chThdSleep(TIME_US2I(usecs))
1196 
1197 /**
1198  * @brief Suspends the invoking thread for the specified time.
1199  *
1200  * @param[in] timeout the delay in system ticks
1201  *
1202  * @sclass
1203  */
1204 #define chThdSleepS(timeout) \
1205  (void) chSchGoSleepTimeoutS(NIL_STATE_SLEEPING, timeout)
1206 
1207 /**
1208  * @brief Suspends the invoking thread until the system time arrives to the
1209  * specified value.
1210  *
1211  * @param[in] abstime absolute system time
1212  *
1213  * @sclass
1214  */
1215 #define chThdSleepUntilS(abstime) \
1216  (void) chSchGoSleepTimeoutS(NIL_STATE_SLEEPING, \
1217  chTimeDiffX(chVTGetSystemTimeX(), (abstime)))
1218 
1219 /**
1220  * @brief Initializes a threads queue object.
1221  *
1222  * @param[out] tqp pointer to the threads queue object
1223  *
1224  * @init
1225  */
1226 #define chThdQueueObjectInit(tqp) ((tqp)->cnt = (cnt_t)0)
1227 
1228 /**
1229  * @brief Evaluates to @p true if the specified queue is empty.
1230  *
1231  * @param[out] tqp pointer to the threads queue object
1232  * @return The queue status.
1233  * @retval false if the queue is not empty.
1234  * @retval true if the queue is empty.
1235  *
1236  * @iclass
1237  */
1238 #define chThdQueueIsEmptyI(tqp) ((bool)(tqp->cnt >= (cnt_t)0))
1239 
1240 /**
1241  * @brief Current system time.
1242  * @details Returns the number of system ticks since the @p chSysInit()
1243  * invocation.
1244  * @note The counter can reach its maximum and then restart from zero.
1245  * @note This function can be called from any context but its atomicity
1246  * is not guaranteed on architectures whose word size is less than
1247  * @p systime_t size.
1248  *
1249  * @return The system time in ticks.
1250  *
1251  * @xclass
1252  */
1253 #if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__)
1254 #define chVTGetSystemTimeX() (nil.systime)
1255 #else
1256 #define chVTGetSystemTimeX() port_timer_get_time()
1257 #endif
1258 
1259 /**
1260  * @brief Returns the elapsed time since the specified start time.
1261  *
1262  * @param[in] start start time
1263  * @return The elapsed time.
1264  *
1265  * @xclass
1266  */
1267 #define chVTTimeElapsedSinceX(start) \
1268  chTimeDiffX((start), chVTGetSystemTimeX())
1269 
1270 /**
1271  * @brief Checks if the current system time is within the specified time
1272  * window.
1273  * @note When start==end then the function returns always false because the
1274  * time window has zero size.
1275  *
1276  * @param[in] start the start of the time window (inclusive)
1277  * @param[in] end the end of the time window (non inclusive)
1278  * @retval true current time within the specified time window.
1279  * @retval false current time not within the specified time window.
1280  *
1281  * @xclass
1282  */
1283 #define chVTIsSystemTimeWithinX(start, end) \
1284  chTimeIsInRangeX(chVTGetSystemTimeX(), start, end)
1285 
1286 /**
1287  * @brief Adds an interval to a system time returning a system time.
1288  *
1289  * @param[in] systime base system time
1290  * @param[in] interval interval to be added
1291  * @return The new system time.
1292  *
1293  * @xclass
1294  */
1295 #define chTimeAddX(systime, interval) \
1296  ((systime_t)(systime) + (systime_t)(interval))
1297 
1298 /**
1299  * @brief Subtracts two system times returning an interval.
1300  *
1301  * @param[in] start first system time
1302  * @param[in] end second system time
1303  * @return The interval representing the time difference.
1304  *
1305  * @xclass
1306  */
1307 #define chTimeDiffX(start, end) \
1308  ((sysinterval_t)((systime_t)((systime_t)(end) - (systime_t)(start))))
1309 
1310 /**
1311  * @brief Function parameters check.
1312  * @details If the condition check fails then the kernel panics and halts.
1313  * @note The condition is tested only if the @p CH_DBG_ENABLE_CHECKS switch
1314  * is specified in @p chconf.h else the macro does nothing.
1315  *
1316  * @param[in] c the condition to be verified to be true
1317  *
1318  * @api
1319  */
1320 #if !defined(chDbgCheck)
1321 #define chDbgCheck(c) do { \
1322  /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \
1323  if (CH_DBG_ENABLE_CHECKS != FALSE) { \
1324  if (!(c)) { \
1325  /*lint -restore*/ \
1326  chSysHalt(__func__); \
1327  } \
1328  } \
1329 } while (false)
1330 #endif /* !defined(chDbgCheck) */
1331 
1332 /**
1333  * @brief Condition assertion.
1334  * @details If the condition check fails then the kernel panics with a
1335  * message and halts.
1336  * @note The condition is tested only if the @p CH_DBG_ENABLE_ASSERTS
1337  * switch is specified in @p chconf.h else the macro does nothing.
1338  * @note The remark string is not currently used except for putting a
1339  * comment in the code about the assertion.
1340  *
1341  * @param[in] c the condition to be verified to be true
1342  * @param[in] r a remark string
1343  *
1344  * @api
1345  */
1346 #if !defined(chDbgAssert)
1347 #define chDbgAssert(c, r) do { \
1348  /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \
1349  if (CH_DBG_ENABLE_ASSERTS != FALSE) { \
1350  if (!(c)) { \
1351  /*lint -restore*/ \
1352  chSysHalt(__func__); \
1353  } \
1354  } \
1355 } while (false)
1356 #endif /* !defined(chDbgAssert) */
1357 /** @} */
1358 
1359 /* Empty macros if the state checker is not enabled.*/
1360 #if CH_DBG_SYSTEM_STATE_CHECK == FALSE
1361 #define __dbg_enter_lock()
1362 #define __dbg_leave_lock()
1363 #define __dbg_check_disable()
1364 #define __dbg_check_suspend()
1365 #define __dbg_check_enable()
1366 #define __dbg_check_lock()
1367 #define __dbg_check_unlock()
1368 #define __dbg_check_lock_from_isr()
1369 #define __dbg_check_unlock_from_isr()
1370 #define __dbg_check_enter_isr()
1371 #define __dbg_check_leave_isr()
1372 #define chDbgCheckClassI()
1373 #define chDbgCheckClassS()
1374 #endif
1375 
1376 /*===========================================================================*/
1377 /* External declarations. */
1378 /*===========================================================================*/
1379 
1380 #if !defined(__DOXYGEN__)
1381 #if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || defined(__DOXYGEN__)
1382 extern stkalign_t __main_thread_stack_base__, __main_thread_stack_end__;
1383 #endif
1384 extern os_instance_t nil;
1385 extern const thread_descriptor_t nil_thd_configs[];
1386 #endif
1387 
1388 #ifdef __cplusplus
1389 extern "C" {
1390 #endif
1391  thread_t *nil_find_thread(tstate_t state, void *p);
1392  cnt_t nil_ready_all(void *p, cnt_t cnt, msg_t msg);
1393  void chSysInit(void);
1394  void chSysHalt(const char *reason);
1395  void chSysTimerHandlerI(void);
1396  void chSysUnconditionalLock(void);
1397  void chSysUnconditionalUnlock(void);
1399  bool chSysIsCounterWithinX(rtcnt_t cnt, rtcnt_t start, rtcnt_t end);
1400  void chSysPolledDelayX(rtcnt_t cycles);
1401  void chSysRestoreStatusX(syssts_t sts);
1402  thread_t *chSchReadyI(thread_t *tp, msg_t msg);
1403  bool chSchIsPreemptionRequired(void);
1404  void chSchDoPreemption(void);
1405  void chSchRescheduleS(void);
1406  msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout);
1407  bool chTimeIsInRangeX(systime_t time, systime_t start, systime_t end);
1410  void chThdExit(msg_t msg);
1411 #if CH_CFG_USE_WAITEXIT == TRUE
1412  msg_t chThdWait(thread_t *tp);
1413 #endif
1415  void chThdResumeI(thread_reference_t *trp, msg_t msg);
1416  void chThdResume(thread_reference_t *trp, msg_t msg);
1417  void chThdSleep(sysinterval_t timeout);
1418  void chThdSleepUntil(systime_t abstime);
1420  void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg);
1421  void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg);
1422  void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg);
1423 #if CH_DBG_SYSTEM_STATE_CHECK == TRUE
1424  void __dbg_check_disable(void);
1425  void __dbg_check_suspend(void);
1426  void __dbg_check_enable(void);
1427  void __dbg_check_lock(void);
1428  void __dbg_check_unlock(void);
1429  void __dbg_check_lock_from_isr(void);
1430  void __dbg_check_unlock_from_isr(void);
1431  void __dbg_check_enter_isr(void);
1432  void __dbg_check_leave_isr(void);
1433  void chDbgCheckClassI(void);
1434  void chDbgCheckClassS(void);
1435 #endif
1436 #ifdef __cplusplus
1437 }
1438 #endif
1439 
1440 /* Optional modules.*/
1441 #include "chsem.h"
1442 #include "chevt.h"
1443 #include "chmsg.h"
1444 #include "chlib.h"
1445 
1446 #endif /* CH_H */
1447 
1448 /** @} */
nil_thread::p
void * p
Generic pointer.
Definition: nil/include/ch.h:521
nil_thread::tqp
threads_queue_t * tqp
Pointer to thread queue.
Definition: nil/include/ch.h:524
nil_thread::ctx
struct port_context ctx
Processor context.
Definition: nil/include/ch.h:515
chSysRestoreStatusX
void chSysRestoreStatusX(syssts_t sts)
Restores the specified execution status and leaves a critical zone.
Definition: chsys.c:423
chSysHalt
void chSysHalt(const char *reason)
Halts the system.
Definition: chsys.c:209
chSysIsCounterWithinX
bool chSysIsCounterWithinX(rtcnt_t cnt, rtcnt_t start, rtcnt_t end)
Realtime window test.
Definition: chsys.c:455
chThdSuspendTimeoutS
msg_t chThdSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout)
Sends the current thread sleeping and sets a reference variable.
Definition: chthreads.c:777
tprio_t
uint32_t tprio_t
Definition: chearly.h:87
chSchReadyI
thread_t * chSchReadyI(thread_t *tp)
Inserts a thread in the Ready List placing it behind its peers.
Definition: chschd.c:276
port_stkalign_t
uint64_t port_stkalign_t
Type of stack and memory alignment enforcement.
Definition: chtypes.h:72
stkalign_t
port_stkalign_t stkalign_t
Definition: chearly.h:80
chSysUnconditionalUnlock
void chSysUnconditionalUnlock(void)
Unconditionally leaves the kernel lock state.
Definition: ch.c:472
nil_thread::msg
msg_t msg
Wake-up/exit message.
Definition: nil/include/ch.h:520
chlicense.h
License Module macros and structures.
nil_thread_descriptor::name
const char * name
Thread name, for debugging.
Definition: nil/include/ch.h:503
tfunc_t
void(* tfunc_t)(void *p)
Thread function.
Definition: nil/include/ch.h:457
nil_thread_descriptor
Structure representing a thread descriptor.
Definition: nil/include/ch.h:502
nil_threads_queue::cnt
volatile cnt_t cnt
Threads Queue counter.
Definition: nil/include/ch.h:496
systime_t
uint64_t systime_t
Type of system time.
Definition: chtime.h:107
time_conv_t
uint64_t time_conv_t
Type of time conversion variable.
Definition: nil/include/ch.h:441
ch_os_instance
System instance data structure.
Definition: chobjects.h:394
nil_thread::sntmsg
msg_t sntmsg
Sent message.
Definition: nil/include/ch.h:539
chSysTimerHandlerI
void chSysTimerHandlerI(void)
Handles time ticks for round robin preemption and timer increments.
Definition: chsys.c:366
nil_os_instance::dbg_panic_msg
const char *volatile dbg_panic_msg
Panic message.
Definition: nil/include/ch.h:598
stkalign_t
port_stkalign_t stkalign_t
Definition: nil/include/ch.h:388
nil_thread::tp
thread_t * tp
Pointer to thread.
Definition: nil/include/ch.h:525
rtcnt_t
port_rtcnt_t rtcnt_t
Definition: nil/include/ch.h:386
nil_os_instance::nexttime
systime_t nexttime
Time of the next scheduled tick event.
Definition: nil/include/ch.h:578
nil_thread::semp
semaphore_t * semp
Pointer to semaphore.
Definition: nil/include/ch.h:527
eventmask_t
uint32_t eventmask_t
Definition: chearly.h:90
chThdCreateI
thread_t * chThdCreateI(const thread_descriptor_t *tdp)
Creates a new thread into a static memory area.
Definition: chthreads.c:270
nil_thread_descriptor::arg
void * arg
Thread function argument.
Definition: nil/include/ch.h:508
nil_ready_all
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
chlib.h
ChibiOS/LIB main include file.
tstate_t
uint8_t tstate_t
Definition: chearly.h:84
msg_t
int32_t msg_t
Definition: chearly.h:88
chSchGoSleepTimeoutS
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:355
tprio_t
uint32_t tprio_t
Definition: nil/include/ch.h:392
chThdDequeueAllI
void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg)
Dequeues and wakes up all threads from the threads queue object.
Definition: chthreads.c:913
chThdEnqueueTimeoutS
msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout)
Enqueues the caller thread on a threads queue object.
Definition: chthreads.c:877
nil_os_instance::isr_cnt
cnt_t isr_cnt
ISR nesting level.
Definition: nil/include/ch.h:584
thread_reference_t
thread_t * thread_reference_t
Type of a thread reference.
Definition: nil/include/ch.h:473
systime_t
uint32_t systime_t
Type of system time.
Definition: nil/include/ch.h:428
nil_os_instance
System data structure.
Definition: nil/include/ch.h:553
nil
os_instance_t nil
System data structures.
Definition: ch.c:41
chThdDoDequeueNextI
void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg)
Dequeues and wakes up one thread from the threads queue object.
Definition: ch.c:1032
chSysUnconditionalLock
void chSysUnconditionalLock(void)
Unconditionally enters the kernel lock state.
Definition: ch.c:458
nil_thread::wabase
stkalign_t * wabase
Thread stack boundary.
Definition: nil/include/ch.h:542
nil_thread_descriptor::funcp
tfunc_t funcp
Thread function.
Definition: nil/include/ch.h:507
nil_thread_descriptor::wbase
stkalign_t * wbase
Thread working area base.
Definition: nil/include/ch.h:504
chThdResumeI
void chThdResumeI(thread_reference_t *trp, msg_t msg)
Wakes up a thread waiting on a thread reference object.
Definition: chthreads.c:802
ch_thread
Structure representing a thread.
Definition: chobjects.h:156
chSysPolledDelayX
void chSysPolledDelayX(rtcnt_t cycles)
Polled delay.
Definition: chsys.c:472
cnt_t
int32_t cnt_t
Definition: chearly.h:92
syssts_t
port_syssts_t syssts_t
Definition: chearly.h:79
nil_thread::trp
thread_reference_t * trp
Pointer to thread reference.
Definition: nil/include/ch.h:523
nil_thread_descriptor::wend
stkalign_t * wend
Thread working area end.
Definition: nil/include/ch.h:505
eventid_t
int32_t eventid_t
Definition: nil/include/ch.h:394
chThdWait
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:569
rtcnt_t
port_rtcnt_t rtcnt_t
Definition: chearly.h:77
port_rtcnt_t
uint32_t port_rtcnt_t
Realtime counter.
Definition: chtypes.h:54
cnt_t
int32_t cnt_t
Definition: nil/include/ch.h:397
tstate_t
uint8_t tstate_t
Definition: nil/include/ch.h:391
ch_semaphore
Semaphore structure.
Definition: rt/include/chsem.h:52
nil_threads_queue
Structure representing a queue of threads.
Definition: nil/include/ch.h:495
chcore.h
Port related template macros and structures.
nil_thread::epmask
eventmask_t epmask
Pending events mask.
Definition: nil/include/ch.h:536
CH_CFG_MAX_THREADS
#define CH_CFG_MAX_THREADS
Maximum number of user threads in the application.
Definition: nil/templates/chconf.h:51
nil_os_instance::lasttime
systime_t lasttime
System time of the last tick event.
Definition: nil/include/ch.h:574
nil_thread
Structure representing a thread.
Definition: nil/include/ch.h:514
thread_descriptor_t
Type of a thread descriptor.
Definition: chthreads.h:57
semaphore_t
threads_queue_t semaphore_t
Type of a structure representing a semaphore.
Definition: nil/include/ch.h:486
chSysGetStatusAndLockX
syssts_t chSysGetStatusAndLockX(void)
Returns the execution status and enters a critical zone.
Definition: chsys.c:400
chSchRescheduleS
void chSchRescheduleS(void)
Performs a reschedule if a higher priority thread is runnable.
Definition: chschd.c:454
threads_queue_t
Type of a thread queue.
Definition: osal.h:238
nil_os_instance::systime
volatile systime_t systime
System time.
Definition: nil/include/ch.h:568
eventflags_t
uint32_t eventflags_t
Definition: nil/include/ch.h:396
chevt.h
Nil RTOS events header file.
msg_t
int32_t msg_t
Definition: nil/include/ch.h:393
nil_thread::ewmask
eventmask_t ewmask
Enabled events mask.
Definition: nil/include/ch.h:530
chSchDoPreemption
void chSchDoPreemption(void)
Switches to the first thread on the runnable queue.
Definition: chschd.c:513
nil_thread::state
tstate_t state
Thread state.
Definition: nil/include/ch.h:516
nil_os_instance::next
thread_t * next
Pointer to the next thread to be executed.
Definition: nil/include/ch.h:563
chSchIsPreemptionRequired
bool chSchIsPreemptionRequired(void)
Evaluates if preemption is required.
Definition: chschd.c:481
nil_os_instance::current
thread_t * current
Pointer to the running thread.
Definition: nil/include/ch.h:557
chmsg.h
Nil RTOS synchronous messages header file.
sysinterval_t
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:119
eventmask_t
uint32_t eventmask_t
Definition: nil/include/ch.h:395
chThdSleep
void chThdSleep(sysinterval_t time)
Suspends the invoking thread for the specified time.
Definition: chthreads.c:664
nil_thread::timeout
volatile sysinterval_t timeout
Timeout counter, zero if disabled.
Definition: nil/include/ch.h:533
chThdCreate
thread_t * chThdCreate(const thread_descriptor_t *tdp)
Creates a new thread into a static memory area.
Definition: chthreads.c:291
chThdDequeueNextI
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:898
chtypes.h
Template port system types.
chSysInit
void chSysInit(void)
System initialization.
Definition: chsys.c:159
sysinterval_t
uint32_t sysinterval_t
Type of time interval.
Definition: nil/include/ch.h:434
nil_thread::nsp
os_instance_t * nsp
Pointer to nil base struct.
Definition: nil/include/ch.h:522
nil_thread_descriptor::prio
tprio_t prio
Thread priority slot.
Definition: nil/include/ch.h:506
chThdResume
void chThdResume(thread_reference_t *trp, msg_t msg)
Wakes up a thread waiting on a thread reference object.
Definition: chthreads.c:847
chsem.h
Nil RTOS semaphores header file.
nil_find_thread
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
port_syssts_t
uint32_t port_syssts_t
System status word.
Definition: chtypes.h:64
syssts_t
port_syssts_t syssts_t
Definition: nil/include/ch.h:387
nil_os_instance::lock_cnt
cnt_t lock_cnt
Lock nesting level.
Definition: nil/include/ch.h:588
ucnt_t
uint32_t ucnt_t
Definition: nil/include/ch.h:398
chTimeIsInRangeX
bool chTimeIsInRangeX(systime_t time, systime_t start, systime_t end)
Checks if the specified time is within the specified time range.
Definition: ch.c:743
port_context
Platform dependent part of the thread_t structure.
Definition: chcore.h:169
chThdSleepUntil
void chThdSleepUntil(systime_t time)
Suspends the invoking thread until the system time arrives to the specified value.
Definition: chthreads.c:684
chThdExit
void chThdExit(msg_t msg)
Terminates the current thread.
Definition: chthreads.c:488
nil_os_instance::threads
thread_t threads[CH_CFG_MAX_THREADS+1]
Thread structures for all the defined threads.
Definition: nil/include/ch.h:603
CH_CFG_THREAD_EXT_FIELDS
#define CH_CFG_THREAD_EXT_FIELDS
Threads descriptor structure extension.
Definition: nil/templates/chconf.h:431