ChibiOS  21.6.0
chdebug.c
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 rt/src/chdebug.c
22  * @brief Debug support code.
23  *
24  * @addtogroup checks_assertions
25  * @details Debug APIs and services:
26  * - Runtime system state and call protocol check. The following
27  * panic messages can be generated:
28  * - SV#1, misplaced @p chSysDisable().
29  * - Called from an ISR.
30  * - Called from a critical zone.
31  * .
32  * - SV#2, misplaced @p chSysSuspend()
33  * - Called from an ISR.
34  * - Called from a critical zone.
35  * .
36  * - SV#3, misplaced @p chSysEnable().
37  * - Called from an ISR.
38  * - Called from a critical zone.
39  * .
40  * - SV#4, misplaced @p chSysLock().
41  * - Called from an ISR.
42  * - Called from a critical zone.
43  * .
44  * - SV#5, misplaced @p chSysUnlock().
45  * - Called from an ISR.
46  * - Not called from a critical zone.
47  * .
48  * - SV#6, misplaced @p chSysLockFromISR().
49  * - Not called from an ISR.
50  * - Called from a critical zone.
51  * .
52  * - SV#7, misplaced @p chSysUnlockFromISR().
53  * - Not called from an ISR.
54  * - Not called from a critical zone.
55  * .
56  * - SV#8, misplaced @p CH_IRQ_PROLOGUE().
57  * - Not called at ISR begin.
58  * - Called from a critical zone.
59  * .
60  * - SV#9, misplaced @p CH_IRQ_EPILOGUE().
61  * - @p CH_IRQ_PROLOGUE() missing.
62  * - Not called at ISR end.
63  * - Called from a critical zone.
64  * .
65  * - SV#10, misplaced I-class function.
66  * - I-class function not called from within a critical zone.
67  * .
68  * - SV#11, misplaced S-class function.
69  * - S-class function not called from within a critical zone.
70  * - Called from an ISR.
71  * .
72  * - Parameters check.
73  * - Kernel assertions.
74  * .
75  * @note Stack checks are not implemented in this module but in the port
76  * layer in an architecture-dependent way.
77  * @{
78  */
79 
80 #include "ch.h"
81 
82 /*===========================================================================*/
83 /* Module local definitions. */
84 /*===========================================================================*/
85 
86 /*===========================================================================*/
87 /* Module exported variables. */
88 /*===========================================================================*/
89 
90 /*===========================================================================*/
91 /* Module local types. */
92 /*===========================================================================*/
93 
94 /*===========================================================================*/
95 /* Module local variables. */
96 /*===========================================================================*/
97 
98 /*===========================================================================*/
99 /* Module local functions. */
100 /*===========================================================================*/
101 
102 /*===========================================================================*/
103 /* Module exported functions. */
104 /*===========================================================================*/
105 
106 #if (CH_DBG_SYSTEM_STATE_CHECK == TRUE) || defined(__DOXYGEN__)
107 /**
108  * @brief Guard code for @p chSysDisable().
109  *
110  * @notapi
111  */
113  os_instance_t *oip = currcore;
114 
115  if (unlikely((oip->dbg.isr_cnt != (cnt_t)0) ||
116  (oip->dbg.lock_cnt != (cnt_t)0))) {
117  chSysHalt("SV#1");
118  }
119 }
120 
121 /**
122  * @brief Guard code for @p chSysSuspend().
123  *
124  * @notapi
125  */
127  os_instance_t *oip = currcore;
128 
129  if (unlikely((oip->dbg.isr_cnt != (cnt_t)0) ||
130  (oip->dbg.lock_cnt != (cnt_t)0))) {
131  chSysHalt("SV#2");
132  }
133 }
134 
135 /**
136  * @brief Guard code for @p chSysEnable().
137  *
138  * @notapi
139  */
140 void __dbg_check_enable(void) {
141  os_instance_t *oip = currcore;
142 
143  if (unlikely((oip->dbg.isr_cnt != (cnt_t)0) ||
144  (oip->dbg.lock_cnt != (cnt_t)0))) {
145  chSysHalt("SV#3");
146  }
147 }
148 
149 /**
150  * @brief Guard code for @p chSysLock().
151  *
152  * @notapi
153  */
154 void __dbg_check_lock(void) {
155  os_instance_t *oip = currcore;
156 
157  if (unlikely((oip->dbg.isr_cnt != (cnt_t)0) ||
158  (oip->dbg.lock_cnt != (cnt_t)0))) {
159  chSysHalt("SV#4");
160  }
161  oip->dbg.lock_cnt = (cnt_t)1;
162 }
163 
164 /**
165  * @brief Guard code for @p chSysUnlock().
166  *
167  * @notapi
168  */
169 void __dbg_check_unlock(void) {
170  os_instance_t *oip = currcore;
171 
172  if (unlikely((oip->dbg.isr_cnt != (cnt_t)0) ||
173  (oip->dbg.lock_cnt <= (cnt_t)0))) {
174  chSysHalt("SV#5");
175  }
176  oip->dbg.lock_cnt = (cnt_t)0;
177 }
178 
179 /**
180  * @brief Guard code for @p chSysLockFromIsr().
181  *
182  * @notapi
183  */
185  os_instance_t *oip = currcore;
186 
187  if (unlikely((oip->dbg.isr_cnt <= (cnt_t)0) ||
188  (oip->dbg.lock_cnt != (cnt_t)0))) {
189  chSysHalt("SV#6");
190  }
191  oip->dbg.lock_cnt = (cnt_t)1;
192 }
193 
194 /**
195  * @brief Guard code for @p chSysUnlockFromIsr().
196  *
197  * @notapi
198  */
200  os_instance_t *oip = currcore;
201 
202  if (unlikely((oip->dbg.isr_cnt <= (cnt_t)0) ||
203  (oip->dbg.lock_cnt <= (cnt_t)0))) {
204  chSysHalt("SV#7");
205  }
206  oip->dbg.lock_cnt = (cnt_t)0;
207 }
208 
209 /**
210  * @brief Guard code for @p CH_IRQ_PROLOGUE().
211  *
212  * @notapi
213  */
215  os_instance_t *oip = currcore;
216 
218  if (unlikely((oip->dbg.isr_cnt < (cnt_t)0) ||
219  (oip->dbg.lock_cnt != (cnt_t)0))) {
220  chSysHalt("SV#8");
221  }
222  oip->dbg.isr_cnt++;
224 }
225 
226 /**
227  * @brief Guard code for @p CH_IRQ_EPILOGUE().
228  *
229  * @notapi
230  */
232  os_instance_t *oip = currcore;
233 
235  if (unlikely((oip->dbg.isr_cnt <= (cnt_t)0) ||
236  (oip->dbg.lock_cnt != (cnt_t)0))) {
237  chSysHalt("SV#9");
238  }
239  oip->dbg.isr_cnt--;
241 }
242 
243 /**
244  * @brief I-class functions context check.
245  * @details Verifies that the system is in an appropriate state for invoking
246  * an I-class API function. A panic is generated if the state is
247  * not compatible.
248  *
249  * @api
250  */
251 void chDbgCheckClassI(void) {
252  os_instance_t *oip = currcore;
253 
254  if (unlikely((oip->dbg.isr_cnt < (cnt_t)0) ||
255  (oip->dbg.lock_cnt <= (cnt_t)0))) {
256  chSysHalt("SV#10");
257  }
258 }
259 
260 /**
261  * @brief S-class functions context check.
262  * @details Verifies that the system is in an appropriate state for invoking
263  * an S-class API function. A panic is generated if the state is
264  * not compatible.
265  *
266  * @api
267  */
268 void chDbgCheckClassS(void) {
269  os_instance_t *oip = currcore;
270 
271  if (unlikely((oip->dbg.isr_cnt != (cnt_t)0) ||
272  (oip->dbg.lock_cnt <= (cnt_t)0))) {
273  chSysHalt("SV#11");
274  }
275 }
276 
277 #endif /* CH_DBG_SYSTEM_STATE_CHECK == TRUE */
278 
279 /** @} */
__dbg_check_lock
void __dbg_check_lock(void)
Guard code for chSysLock().
Definition: chdebug.c:154
chSysHalt
void chSysHalt(const char *reason)
Halts the system.
Definition: chsys.c:209
__dbg_check_lock_from_isr
void __dbg_check_lock_from_isr(void)
Guard code for chSysLockFromIsr().
Definition: chdebug.c:184
currcore
#define currcore
Access to current core's instance structure.
Definition: chsys.h:90
ch_os_instance
System instance data structure.
Definition: chobjects.h:394
port_unlock_from_isr
static void port_unlock_from_isr(void)
Kernel-unlock action from an interrupt handler.
Definition: chcore.h:377
__dbg_check_leave_isr
void __dbg_check_leave_isr(void)
Guard code for CH_IRQ_EPILOGUE().
Definition: chdebug.c:231
__dbg_check_enable
void __dbg_check_enable(void)
Guard code for chSysEnable().
Definition: chdebug.c:140
cnt_t
int32_t cnt_t
Definition: chearly.h:92
ch_system_debug::isr_cnt
cnt_t isr_cnt
ISR nesting level.
Definition: chdebug.h:75
chDbgCheckClassI
void chDbgCheckClassI(void)
I-class functions context check.
Definition: chdebug.c:251
port_lock_from_isr
static void port_lock_from_isr(void)
Kernel-lock action from an interrupt handler.
Definition: chcore.h:367
__dbg_check_enter_isr
void __dbg_check_enter_isr(void)
Guard code for CH_IRQ_PROLOGUE().
Definition: chdebug.c:214
ch_system_debug::lock_cnt
cnt_t lock_cnt
Lock nesting level.
Definition: chdebug.h:79
__dbg_check_suspend
void __dbg_check_suspend(void)
Guard code for chSysSuspend().
Definition: chdebug.c:126
ch_os_instance::dbg
system_debug_t dbg
System debug.
Definition: chobjects.h:433
unlikely
#define unlikely(x)
Marks a boolean expression as likely false.
Definition: chearly.h:191
__dbg_check_unlock_from_isr
void __dbg_check_unlock_from_isr(void)
Guard code for chSysUnlockFromIsr().
Definition: chdebug.c:199
chDbgCheckClassS
void chDbgCheckClassS(void)
S-class functions context check.
Definition: chdebug.c:268
__dbg_check_disable
void __dbg_check_disable(void)
Guard code for chSysDisable().
Definition: chdebug.c:112
__dbg_check_unlock
void __dbg_check_unlock(void)
Guard code for chSysUnlock().
Definition: chdebug.c:169