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