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