This repository has been archived by the owner on Jan 7, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[assert] Improve implementation, add asserts.
- Make header C-compatible so asserts can be called from C. - Specialize `assert_fail` function for context value. - Return condition from `xpcc_assert` for error handling. - Remove `exit()` calls from implementation. - Add assertions to core. - Update F469-DISCO assert example.
- Loading branch information
Showing
24 changed files
with
490 additions
and
173 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,68 @@ | ||
#include <xpcc/architecture/platform.hpp> | ||
|
||
#define XPCC_CAN_MODULE_NAME "can" | ||
#define XPCC_IOBUFFER_MODULE_NAME "iobuffer" | ||
#define XPCC_UART_MODULE_NAME "uart" | ||
|
||
using namespace Board; | ||
|
||
extern "C" void xpcc_abandon(const char * module, | ||
const char * location, | ||
const char * failure, | ||
uintptr_t context) | ||
{ | ||
XPCC_LOG_ERROR << "Assertion '" | ||
<< module << "." << location << "." << failure | ||
<< "' @ " << (void *) context | ||
<< " failed! Abandoning..." << xpcc::endl; | ||
|
||
LedGreen::setOutput(); | ||
while(1) { | ||
LedBlue::set(); | ||
xpcc::delayMilliseconds(20); | ||
LedBlue::reset(); | ||
xpcc::delayMilliseconds(180); | ||
} | ||
} | ||
|
||
static xpcc::Abandonment | ||
test_assertion_handler(const char * module, | ||
const char * /* location */, | ||
const char * /* failure */, | ||
uintptr_t /* context */) | ||
{ | ||
if (strcmp(module, XPCC_IOBUFFER_MODULE_NAME) == 0) | ||
if (!strcmp(module, "iobuffer")) { | ||
XPCC_LOG_ERROR << "Ignoring iobuffer full!" << xpcc::endl; | ||
return xpcc::Abandonment::Ignore; | ||
} | ||
return xpcc::Abandonment::DontCare; | ||
} | ||
XPCC_ASSERTION_HANDLER(test_assertion_handler); | ||
|
||
static xpcc::Abandonment | ||
core_assertion_handler(const char * module, | ||
const char * /* location */, | ||
const char * failure, | ||
uintptr_t context) | ||
{ | ||
if (!memcmp(module, "core\0nvic\0undefined", 19)) { | ||
XPCC_LOG_ERROR.printf("Ignoring undefined IRQ handler %d!\n", context); | ||
return xpcc::Abandonment::Ignore; | ||
} | ||
if (!memcmp(module, "core\0heap", 9)) { | ||
XPCC_LOG_ERROR.printf("Ignoring 'core.heap.%s' of size 0x%x!\n", failure, context); | ||
return xpcc::Abandonment::Ignore; | ||
} | ||
return xpcc::Abandonment::DontCare; | ||
} | ||
XPCC_ASSERTION_HANDLER(core_assertion_handler); | ||
|
||
// ---------------------------------------------------------------------------- | ||
int | ||
main() | ||
{ | ||
Board::initialize(); | ||
|
||
xpcc_assert(true, XPCC_CAN_MODULE_NAME, "init", "timeout"); | ||
// trigger an IRQ with undefined handler | ||
NVIC_EnableIRQ(RTC_Alarm_IRQn); | ||
NVIC_SetPendingIRQ(RTC_Alarm_IRQn); | ||
|
||
xpcc_assert_debug(false, XPCC_IOBUFFER_MODULE_NAME, "tx", "full"); | ||
// trigger an out of memory | ||
// we definitely don't have 32MB RAM on this board | ||
// returns NULL, asserts in debug mode | ||
volatile void * ptr = malloc(1 << 25); | ||
// returns NULL, asserts in debug mode | ||
ptr = new (std::nothrow) uint8_t[1 << 25]; | ||
// always asserts | ||
ptr = new uint8_t[1 << 25]; | ||
(void) ptr; | ||
|
||
xpcc_assert(false, XPCC_UART_MODULE_NAME, "init", "mode"); | ||
// does not fail, should not be optimized away | ||
volatile bool true_condition = true; | ||
xpcc_assert(true_condition, "can", "init", "timeout"); | ||
|
||
while(1) | ||
{ | ||
LedRed::toggle(); | ||
xpcc::delayMilliseconds(500); | ||
} | ||
// only fails for debug builds, but is ignored anyways | ||
xpcc_assert_debug(false, "iobuffer", "tx", "full"); | ||
|
||
return 0; | ||
// "accidentally" return from main, without even returning properly! | ||
// This should be cought by the debug assert core.main.exit! | ||
// while(1) ; | ||
// return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
[build] | ||
board = stm32f469_discovery | ||
buildpath = ${xpccpath}/build/stm32f469_discovery/${name} | ||
|
||
[defines] | ||
XPCC_DEBUG_BUILD=1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// coding: utf-8 | ||
/* Copyright (c) 2016-2017, Niklas Hauser | ||
* All Rights Reserved. | ||
* | ||
* The file is part of the xpcc library and is released under the 3-clause BSD | ||
* license. See the file `LICENSE` for the full license governing this code. | ||
*/ | ||
// ---------------------------------------------------------------------------- | ||
|
||
#ifndef XPCC_ASSERT_H | ||
#define XPCC_ASSERT_H | ||
|
||
#if defined(__cplusplus) && !defined(XPCC_ASSERT_HPP) | ||
# error "Don't include this file directly, use 'assert.hpp' instead!" | ||
#endif | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
#include <xpcc/architecture/utils.hpp> | ||
|
||
#ifndef __DOXYGEN__ | ||
|
||
// FIXME: <xpcc/architecture/driver/flash.hpp> is not C compatible! | ||
#ifdef XPCC__CPU_AVR | ||
# include <avr/pgmspace.h> | ||
# define xpcc_ifss(s) PSTR(s) | ||
#else | ||
# define xpcc_ifss(s) ((const char *)(s)) | ||
#endif | ||
|
||
#define xpcc_assert4(condition, module, location, failure) \ | ||
({ \ | ||
bool xpcc_assert_evaluated_condition = (bool) (condition); \ | ||
if (!xpcc_assert_evaluated_condition) { \ | ||
xpcc_assert_fail(xpcc_ifss(module "\0" location "\0" failure)); } \ | ||
xpcc_assert_evaluated_condition; \ | ||
}) | ||
|
||
|
||
#define xpcc_assert5(condition, module, location, failure, context) \ | ||
({ \ | ||
bool xpcc_assert_evaluated_condition = (bool) (condition); \ | ||
if (!xpcc_assert_evaluated_condition) { \ | ||
xpcc_assert_fail_context(xpcc_ifss(module "\0" location "\0" failure), (uintptr_t) context); } \ | ||
xpcc_assert_evaluated_condition; \ | ||
}) | ||
|
||
#define xpcc_assert_get_macro(_1,_2,_3,_4,_5,foo,...) foo | ||
#define xpcc_assert(...) \ | ||
xpcc_assert_get_macro(__VA_ARGS__, xpcc_assert5, xpcc_assert4)(__VA_ARGS__) | ||
|
||
#ifdef XPCC_DEBUG_BUILD | ||
#define xpcc_assert_debug(...) \ | ||
xpcc_assert_get_macro(__VA_ARGS__, xpcc_assert5, xpcc_assert4)(__VA_ARGS__) | ||
#else | ||
# define xpcc_assert_debug(condition, ...) \ | ||
({ \ | ||
bool xpcc_unused xpcc_assert_evaluated_condition = (bool) (condition); \ | ||
xpcc_assert_evaluated_condition; \ | ||
}) | ||
#endif | ||
|
||
xpcc_extern_c void | ||
xpcc_assert_fail_context(const char * identifier, uintptr_t context); | ||
|
||
xpcc_extern_c void | ||
xpcc_assert_fail(const char * identifier); | ||
|
||
xpcc_extern_c void | ||
xpcc_abandon(const char * module, const char * location, const char * failure, uintptr_t context); | ||
|
||
#endif // __DOXYGEN__ | ||
|
||
#endif // XPCC_ASSERT_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.