libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
assert.h
Go to the documentation of this file.
1/** @defgroup debugging Debugging
2@ingroup CM3_defines
3
4@brief Macros and functions to aid in debugging
5
6@version 1.0.0
7
8@date 25 September 2012
9
10Two preprocessor defines control the behavior of assertion check macros in
11this module. They allow the choice between generated code size and ease of
12debugging.
13
14If NDEBUG is defined, all assertion checks are disabled and macros do not
15generate any code.
16
17If CM3_ASSERT_VERBOSE is defined, information regarding the position of
18assertion checks will be stored in the binary, allowing for more
19informative error messages, but also significantly increased code size. As
20default assertion checks do not use this information it is only useful if
21the application linked with libopencm3 defines its own
22cm3_assert_failed_verbose() implementation.
23
24LGPL License Terms @ref lgpl_license
25*/
26
27/*
28 * This file is part of the libopencm3 project.
29 *
30 * Copyright (C) 2012 Tomaz Solc <tomaz.solc@tablix.org>
31 *
32 * This library is free software: you can redistribute it and/or modify
33 * it under the terms of the GNU Lesser General Public License as published by
34 * the Free Software Foundation, either version 3 of the License, or
35 * (at your option) any later version.
36 *
37 * This library is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU Lesser General Public License for more details.
41 *
42 * You should have received a copy of the GNU Lesser General Public License
43 * along with this library. If not, see <http://www.gnu.org/licenses/>.
44 */
45
46/**@{*/
47
48#ifndef LIBOPENCM3_CM3_ASSERT_H
49#define LIBOPENCM3_CM3_ASSERT_H
50
52
53#define CM3_LIKELY(expr) (__builtin_expect(!!(expr), 1))
54
55#ifdef NDEBUG
56# define cm3_assert(expr) (void)0
57# define cm3_assert_not_reached() do { } while (1)
58#else
59# ifdef CM3_ASSERT_VERBOSE
60# define cm3_assert(expr) do { \
61 if (CM3_LIKELY(expr)) { \
62 (void)0; \
63 } else { \
64 cm3_assert_failed_verbose( \
65 __FILE__, __LINE__, \
66 __func__, #expr); \
67 } \
68 } while (0)
69# define cm3_assert_not_reached() \
70 cm3_assert_failed_verbose( \
71 __FILE__, __LINE__, \
72 __func__, 0)
73# else
74/** @brief Check if assertion is true.
75 *
76 * If NDEBUG macro is defined, this macro generates no code. Otherwise
77 * cm3_assert_failed() or cm3_assert_failed_verbose() is called if assertion
78 * is false.
79 *
80 * The purpose of this macro is to aid in debugging libopencm3 and
81 * applications using it. It can be used for example to check if function
82 * arguments are within expected ranges and stop execution in case an
83 * unexpected state is reached.
84 *
85 * @param expr expression to check */
86# define cm3_assert(expr) do { \
87 if (CM3_LIKELY(expr)) { \
88 (void)0; \
89 } else { \
90 cm3_assert_failed(); \
91 } \
92 } while (0)
93/** @brief Check if unreachable code is reached.
94 *
95 * If NDEBUG macro is defined, this macro generates code for an infinite loop.
96 * Otherwise cm3_assert_failed() or cm3_assert_failed_verbose() is called if
97 * the macro is ever reached.
98 *
99 * The purpose of this macro is to aid in debugging libopencm3 and
100 * applications using it. It can be used for example to stop execution if an
101 * unreachable portion of code is reached. */
102# define cm3_assert_not_reached() cm3_assert_failed()
103# endif
104#endif
105
107
108/** @brief Called on a failed assertion.
109 *
110 * Halts execution in an infinite loop. This function never returns.
111 *
112 * Defined as a weak symbol, so applications can define their own
113 * implementation. Usually, a custom implementation of this function should
114 * report an error in some way (print a message to a debug console, display,
115 * LED, ...) and halt execution or reboot the device. */
116void cm3_assert_failed(void) __attribute__((__noreturn__));
117
118/** @brief Called on a failed assertion with verbose messages enabled.
119 *
120 * Halts execution in an infinite loop. This function never returns.
121 *
122 * Defined as a weak symbol, so applications can define their own
123 * implementation. Usually, a custom implementation of this function should
124 * report an error in some way (print a message to a debug console, display,
125 * LED, ...) and halt execution or reboot the device.
126 *
127 * @param file File name where the failed assertion occurred
128 * @param line Line number where the failed assertion occurred
129 * @param func Name of the function where the failed assertion occurred
130 * @param assert_expr Expression that evaluated to false (can be NULL) */
131void cm3_assert_failed_verbose(const char *file, int line, const char *func,
132 const char *assert_expr) __attribute__((__noreturn__));
133
135
136#endif
137
138/**@}*/
#define END_DECLS
Definition: common.h:34
#define BEGIN_DECLS
Definition: common.h:33
void cm3_assert_failed_verbose(const char *file, int line, const char *func, const char *assert_expr)
Called on a failed assertion with verbose messages enabled.
Definition: assert.c:27
void cm3_assert_failed(void)
Called on a failed assertion.
Definition: assert.c:22