mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-14 05:58:13 +08:00
575 lines
33 KiB
C
575 lines
33 KiB
C
/**
|
|
******************************************************************************
|
|
* @file Debug.h
|
|
* @author William Xu
|
|
* @version V1.0.0
|
|
* @date 05-May-2014
|
|
* @brief This header contains defines, macros, and functions to aid in
|
|
* debugging the MICO project.
|
|
******************************************************************************
|
|
*
|
|
* The MIT License
|
|
* Copyright (c) 2014 MXCHIP Inc.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is furnished
|
|
* to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
|
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
******************************************************************************
|
|
*/
|
|
|
|
#ifndef __Debug_h__
|
|
#define __Debug_h__
|
|
|
|
#ifndef MICO_PREBUILT_LIBS
|
|
#include "platform.h"
|
|
#include "platform_config.h"
|
|
#endif
|
|
|
|
#include "mico_rtos.h"
|
|
#include "platform_assert.h"
|
|
|
|
// ==== LOGGING ====
|
|
#ifdef __GNUC__
|
|
#define SHORT_FILE __FILENAME__
|
|
#else
|
|
#define SHORT_FILE strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__
|
|
#endif
|
|
|
|
#define YesOrNo(x) (x ? "YES" : "NO")
|
|
|
|
#ifdef DEBUG
|
|
#ifndef MICO_DISABLE_STDIO
|
|
#ifndef NO_MICO_RTOS
|
|
extern int mico_debug_enabled;
|
|
extern mico_mutex_t stdio_tx_mutex;
|
|
|
|
#define custom_log(N, M, ...) do {if (mico_debug_enabled==0)break;\
|
|
mico_rtos_lock_mutex( &stdio_tx_mutex );\
|
|
printf("[%ld][%s: %s:%4d] " M "\r\n", mico_rtos_get_time(), N, SHORT_FILE, __LINE__, ##__VA_ARGS__);\
|
|
mico_rtos_unlock_mutex( &stdio_tx_mutex );}while(0==1)
|
|
|
|
#ifndef MICO_ASSERT_INFO_DISABLE
|
|
#define debug_print_assert(A,B,C,D,E,F) do {if (mico_debug_enabled==0)break;\
|
|
mico_rtos_lock_mutex( &stdio_tx_mutex );\
|
|
printf("[%ld][MICO:%s:%s:%4d] **ASSERT** %s""\r\n", mico_rtos_get_time(), D, F, E, (C!=NULL) ? C : "" );\
|
|
mico_rtos_unlock_mutex( &stdio_tx_mutex );}while(0==1)
|
|
#else // !MICO_ASSERT_INFO_ENABLE
|
|
#define debug_print_assert(A,B,C,D,E,F)
|
|
#endif // MICO_ASSERT_INFO_ENABLE
|
|
|
|
#ifdef TRACE
|
|
#define custom_log_trace(N) do {if (mico_debug_enabled==0)break;\
|
|
mico_rtos_lock_mutex( &stdio_tx_mutex );\
|
|
printf("[%s: [TRACE] %s] %s()\r\n", N, SHORT_FILE, __PRETTY_FUNCTION__);\
|
|
mico_rtos_unlock_mutex( &stdio_tx_mutex );}while(0==1)
|
|
#else // !TRACE
|
|
#define custom_log_trace(N)
|
|
#endif // TRACE
|
|
#else // NO_MICO_RTOS
|
|
#define custom_log(N, M, ...) do {printf("[%s: %s:%4d] " M "\r\n", N, SHORT_FILE, __LINE__, ##__VA_ARGS__);}while(0==1)
|
|
|
|
|
|
#ifndef MICO_ASSERT_INFO_DISABLE
|
|
#define debug_print_assert(A,B,C,D,E,F) do {printf("[MICO:%s:%s:%4d] **ASSERT** %s""\r\n", D, F, E, (C!=NULL) ? C : "" );}while(0==1)
|
|
#else
|
|
#define debug_print_assert(A,B,C,D,E,F)
|
|
#endif
|
|
|
|
#ifdef TRACE
|
|
#define custom_log_trace(N) do {printf("[%s: [TRACE] %s] %s()\r\n", N, SHORT_FILE, __PRETTY_FUNCTION__);}while(0==1)
|
|
#else // !TRACE
|
|
#define custom_log_trace(N)
|
|
#endif // TRACE
|
|
#endif
|
|
#else
|
|
#define custom_log(N, M, ...)
|
|
|
|
#define custom_log_trace(N)
|
|
|
|
#define debug_print_assert(A,B,C,D,E,F)
|
|
#endif //MICO_DISABLE_STDIO
|
|
#else // DEBUG = 0
|
|
// IF !DEBUG, make the logs NO-OP
|
|
#define custom_log(N, M, ...)
|
|
|
|
#define custom_log_trace(N)
|
|
|
|
#define debug_print_assert(A,B,C,D,E,F)
|
|
#endif // DEBUG
|
|
|
|
// ==== PLATFORM TIMEING FUNCTIONS ====
|
|
#ifdef TIME_PLATFORM
|
|
#define function_timer_log(M, N, ...) fprintf(stderr, "[FUNCTION TIMER: " N "()] " M "\n", ##__VA_ARGS__)
|
|
|
|
#define TIMEPLATFORM( FUNC, FUNC_NAME ) \
|
|
do \
|
|
{ \
|
|
struct timespec startTime; \
|
|
clock_gettime(CLOCK_MONOTONIC, &startTime); \
|
|
{ FUNC; } \
|
|
struct timespec endTime; \
|
|
clock_gettime(CLOCK_MONOTONIC, &endTime); \
|
|
struct timespec timeDiff = TimeDifference( startTime, endTime ); \
|
|
function_timer_log("%lld us", \
|
|
FUNC_NAME, \
|
|
ElapsedTimeInMicroseconds( timeDiff )); \
|
|
} \
|
|
while( 1==0 )
|
|
#else
|
|
#define function_timer_log(M, N, ...)
|
|
|
|
#define TIMEPLATFORM( FUNC, FUNC_NAME ) \
|
|
do \
|
|
{ \
|
|
{ FUNC; } \
|
|
} \
|
|
while( 1==0 )
|
|
#endif
|
|
|
|
|
|
// ==== BRANCH PREDICTION & EXPRESSION EVALUATION ====
|
|
#if( !defined( unlikely ) )
|
|
//#define unlikely( EXPRESSSION ) __builtin_expect( !!(EXPRESSSION), 0 )
|
|
#define unlikely( EXPRESSSION ) !!(EXPRESSSION)
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined check
|
|
@abstract Check that an expression is true (non-zero).
|
|
@discussion
|
|
|
|
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
|
|
function name, etc.) using the default debugging output method.
|
|
|
|
Code inside check() statements is not compiled into production builds.
|
|
*/
|
|
|
|
#if( !defined( check ) )
|
|
#define check( X ) \
|
|
do \
|
|
{ \
|
|
if( unlikely( !(X) ) ) \
|
|
{ \
|
|
debug_print_assert( 0, #X, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined check_string
|
|
@abstract Check that an expression is true (non-zero) with an explanation.
|
|
@discussion
|
|
|
|
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
|
|
function name, etc.) using the default debugging output method.
|
|
|
|
Code inside check() statements is not compiled into production builds.
|
|
*/
|
|
|
|
#if( !defined( check_string ) )
|
|
#define check_string( X, STR ) \
|
|
do \
|
|
{ \
|
|
if( unlikely( !(X) ) ) \
|
|
{ \
|
|
debug_print_assert( 0, #X, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
|
MICO_ASSERTION_FAIL_ACTION(); \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined require
|
|
@abstract Requires that an expression evaluate to true.
|
|
@discussion
|
|
|
|
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
|
|
function name, etc.) using the default debugging output method then jumps to a label.
|
|
*/
|
|
|
|
#if( !defined( require ) )
|
|
#define require( X, LABEL ) \
|
|
do \
|
|
{ \
|
|
if( unlikely( !(X) ) ) \
|
|
{ \
|
|
debug_print_assert( 0, #X, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
|
goto LABEL; \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined require_string
|
|
@abstract Requires that an expression evaluate to true with an explanation.
|
|
@discussion
|
|
|
|
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
|
|
function name, etc.) and a custom explanation string using the default debugging output method then jumps to a label.
|
|
*/
|
|
|
|
#if( !defined( require_string ) )
|
|
#define require_string( X, LABEL, STR ) \
|
|
do \
|
|
{ \
|
|
if( unlikely( !(X) ) ) \
|
|
{ \
|
|
debug_print_assert( 0, #X, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
|
goto LABEL; \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined require_quiet
|
|
@abstract Requires that an expression evaluate to true.
|
|
@discussion
|
|
|
|
If expression evalulates to false, this jumps to a label. No debugging information is printed.
|
|
*/
|
|
|
|
#if( !defined( require_quiet ) )
|
|
#define require_quiet( X, LABEL ) \
|
|
do \
|
|
{ \
|
|
if( unlikely( !(X) ) ) \
|
|
{ \
|
|
goto LABEL; \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined require_noerr
|
|
@abstract Require that an error code is noErr (0).
|
|
@discussion
|
|
|
|
If the error code is non-0, this prints debugging information (actual expression string, file, line number,
|
|
function name, etc.) using the default debugging output method then jumps to a label.
|
|
*/
|
|
|
|
#if( !defined( require_noerr ) )
|
|
#define require_noerr( ERR, LABEL ) \
|
|
do \
|
|
{ \
|
|
OSStatus localErr; \
|
|
\
|
|
localErr = (OSStatus)(ERR); \
|
|
if( unlikely( localErr != 0 ) ) \
|
|
{ \
|
|
debug_print_assert( localErr, NULL, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
|
goto LABEL; \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined require_noerr_string
|
|
@abstract Require that an error code is noErr (0).
|
|
@discussion
|
|
|
|
If the error code is non-0, this prints debugging information (actual expression string, file, line number,
|
|
function name, etc.), and a custom explanation string using the default debugging output method using the
|
|
default debugging output method then jumps to a label.
|
|
*/
|
|
|
|
#if( !defined( require_noerr_string ) )
|
|
#define require_noerr_string( ERR, LABEL, STR ) \
|
|
do \
|
|
{ \
|
|
OSStatus localErr; \
|
|
\
|
|
localErr = (OSStatus)(ERR); \
|
|
if( unlikely( localErr != 0 ) ) \
|
|
{ \
|
|
debug_print_assert( localErr, NULL, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
|
goto LABEL; \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined require_noerr_action_string
|
|
@abstract Require that an error code is noErr (0).
|
|
@discussion
|
|
|
|
If the error code is non-0, this prints debugging information (actual expression string, file, line number,
|
|
function name, etc.), and a custom explanation string using the default debugging output method using the
|
|
default debugging output method then executes an action and jumps to a label.
|
|
*/
|
|
|
|
#if( !defined( require_noerr_action_string ) )
|
|
#define require_noerr_action_string( ERR, LABEL, ACTION, STR ) \
|
|
do \
|
|
{ \
|
|
OSStatus localErr; \
|
|
\
|
|
localErr = (OSStatus)(ERR); \
|
|
if( unlikely( localErr != 0 ) ) \
|
|
{ \
|
|
debug_print_assert( localErr, NULL, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
|
{ ACTION; } \
|
|
goto LABEL; \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined require_noerr_quiet
|
|
@abstract Require that an error code is noErr (0).
|
|
@discussion
|
|
|
|
If the error code is non-0, this jumps to a label. No debugging information is printed.
|
|
*/
|
|
|
|
#if( !defined( require_noerr_quiet ) )
|
|
#define require_noerr_quiet( ERR, LABEL ) \
|
|
do \
|
|
{ \
|
|
if( unlikely( (ERR) != 0 ) ) \
|
|
{ \
|
|
goto LABEL; \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined require_noerr_action
|
|
@abstract Require that an error code is noErr (0) with an action to execute otherwise.
|
|
@discussion
|
|
|
|
If the error code is non-0, this prints debugging information (actual expression string, file, line number,
|
|
function name, etc.) using the default debugging output method then executes an action and jumps to a label.
|
|
*/
|
|
|
|
#if( !defined( require_noerr_action ) )
|
|
#define require_noerr_action( ERR, LABEL, ACTION ) \
|
|
do \
|
|
{ \
|
|
OSStatus localErr; \
|
|
\
|
|
localErr = (OSStatus)(ERR); \
|
|
if( unlikely( localErr != 0 ) ) \
|
|
{ \
|
|
debug_print_assert( localErr, NULL, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
|
{ ACTION; } \
|
|
goto LABEL; \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined require_noerr_action_quiet
|
|
@abstract Require that an error code is noErr (0) with an action to execute otherwise.
|
|
@discussion
|
|
|
|
If the error code is non-0, this executes an action and jumps to a label. No debugging information is printed.
|
|
*/
|
|
|
|
#if( !defined( require_noerr_action_quiet ) )
|
|
#define require_noerr_action_quiet( ERR, LABEL, ACTION ) \
|
|
do \
|
|
{ \
|
|
if( unlikely( (ERR) != 0 ) ) \
|
|
{ \
|
|
{ ACTION; } \
|
|
goto LABEL; \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined require_action
|
|
@abstract Requires that an expression evaluate to true with an action to execute otherwise.
|
|
@discussion
|
|
|
|
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
|
|
function name, etc.) using the default debugging output method then executes an action and jumps to a label.
|
|
*/
|
|
|
|
#if( !defined( require_action ) )
|
|
#define require_action( X, LABEL, ACTION ) \
|
|
do \
|
|
{ \
|
|
if( unlikely( !(X) ) ) \
|
|
{ \
|
|
debug_print_assert( 0, #X, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
|
{ ACTION; } \
|
|
goto LABEL; \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined require_action_string
|
|
@abstract Requires that an expression evaluate to true with an explanation and action to execute otherwise.
|
|
@discussion
|
|
|
|
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
|
|
function name, etc.) and a custom explanation string using the default debugging output method then executes an
|
|
action and jumps to a label.
|
|
*/
|
|
|
|
#if( !defined( require_action_string ) )
|
|
#define require_action_string( X, LABEL, ACTION, STR ) \
|
|
do \
|
|
{ \
|
|
if( unlikely( !(X) ) ) \
|
|
{ \
|
|
debug_print_assert( 0, #X, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
|
{ ACTION; } \
|
|
goto LABEL; \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined require_action_quiet
|
|
@abstract Requires that an expression evaluate to true with an action to execute otherwise.
|
|
@discussion
|
|
|
|
If expression evalulates to false, this executes an action and jumps to a label. No debugging information is printed.
|
|
*/
|
|
|
|
#if( !defined( require_action_quiet ) )
|
|
#define require_action_quiet( X, LABEL, ACTION ) \
|
|
do \
|
|
{ \
|
|
if( unlikely( !(X) ) ) \
|
|
{ \
|
|
{ ACTION; } \
|
|
goto LABEL; \
|
|
} \
|
|
\
|
|
} while( 1==0 )
|
|
#endif
|
|
|
|
// ==== ERROR MAPPING ====
|
|
#define global_value_errno( VALUE ) ( errno ? errno : kUnknownErr )
|
|
|
|
#define map_global_value_errno( TEST, VALUE ) ( (TEST) ? 0 : global_value_errno(VALUE) )
|
|
#define map_global_noerr_errno( ERR ) ( !(ERR) ? 0 : global_value_errno(ERR) )
|
|
#define map_fd_creation_errno( FD ) ( IsValidFD( FD ) ? 0 : global_value_errno( FD ) )
|
|
#define map_noerr_errno( ERR ) map_global_noerr_errno( (ERR) )
|
|
|
|
#define socket_errno( SOCK ) ( errno ? errno : kUnknownErr )
|
|
#define socket_value_errno( SOCK, VALUE ) socket_errno( SOCK )
|
|
#define map_socket_value_errno( SOCK, TEST, VALUE ) ( (TEST) ? 0 : socket_value_errno( (SOCK), (VALUE) ) )
|
|
#define map_socket_noerr_errno( SOCK, ERR ) ( !(ERR) ? 0 : socket_errno( (SOCK) ) )
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
/*! @defined check_ptr_overlap
|
|
@abstract Checks that two ptrs do not overlap.
|
|
*/
|
|
|
|
#define check_ptr_overlap( P1, P1_SIZE, P2, P2_SIZE ) \
|
|
do \
|
|
{ \
|
|
check( !( ( (uintptr_t)(P1) >= (uintptr_t)(P2) ) && \
|
|
( (uintptr_t)(P1) < ( ( (uintptr_t)(P2) ) + (P2_SIZE) ) ) ) ); \
|
|
check( !( ( (uintptr_t)(P2) >= (uintptr_t)(P1) ) && \
|
|
( (uintptr_t)(P2) < ( ( (uintptr_t)(P1) ) + (P1_SIZE) ) ) ) ); \
|
|
\
|
|
} while( 1==0 )
|
|
|
|
#define IsValidFD( X ) ( ( X ) >= 0 )
|
|
|
|
|
|
//------------------------------------------Memory debug------------------------------------------------------------------
|
|
|
|
typedef struct
|
|
{
|
|
int num_of_chunks; /**< number of free chunks*/
|
|
int total_memory; /**< maximum total allocated space*/
|
|
int allocted_memory; /**< total allocated space*/
|
|
int free_memory; /**< total free space*/
|
|
} micoMemInfo_t;
|
|
|
|
#define MicoGetMemoryInfo mico_memory_info
|
|
|
|
/**
|
|
* @brief Get memory usage information
|
|
*
|
|
* @param None
|
|
*
|
|
* @return Point to structure of memory usage information in heap
|
|
*/
|
|
micoMemInfo_t* MicoGetMemoryInfo( void );
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
#ifdef DEBUG
|
|
#include "platform_assert.h"
|
|
#define MICO_BREAK_IF_DEBUG( ) MICO_ASSERTION_FAIL_ACTION()
|
|
#else
|
|
#define MICO_BREAK_IF_DEBUG( )
|
|
#endif
|
|
|
|
#ifdef PRINT_PLATFORM_PERMISSION
|
|
int platform_wprint_permission(void);
|
|
#define PRINT_PLATFORM_PERMISSION_FUNC() platform_print_permission()
|
|
#else
|
|
#ifdef DEBUG
|
|
#define PRINT_PLATFORM_PERMISSION_FUNC() 1
|
|
#else
|
|
#define PRINT_PLATFORM_PERMISSION_FUNC() 0
|
|
#endif
|
|
#endif
|
|
|
|
/******************************************************
|
|
* Print declarations
|
|
******************************************************/
|
|
#define PRINT_ENABLE_LIB_INFO
|
|
#define PRINT_ENABLE_LIB_DEBUG
|
|
#define PRINT_ENABLE_LIB_ERROR
|
|
|
|
#define PRINT_MACRO(args) do {if (PRINT_PLATFORM_PERMISSION_FUNC()) printf args;} while(0==1)
|
|
|
|
/* printing macros for general SDK/Library functions*/
|
|
#ifdef PRINT_ENABLE_LIB_INFO
|
|
#define WPRINT_LIB_INFO(args) PRINT_MACRO(args)
|
|
#else
|
|
#define WPRINT_LIB_INFO(args)
|
|
#endif
|
|
#ifdef PRINT_ENABLE_LIB_DEBUG
|
|
#define WPRINT_LIB_DEBUG(args) PRINT_MACRO(args)
|
|
#else
|
|
#define WPRINT_LIB_DEBUG(args)
|
|
#endif
|
|
#ifdef PRINT_ENABLE_LIB_ERROR
|
|
#define WPRINT_LIB_ERROR(args) { PRINT_MACRO(args); MICO_BREAK_IF_DEBUG(); }
|
|
#else
|
|
#define WPRINT_LIB_ERROR(args) { MICO_BREAK_IF_DEBUG(); }
|
|
#endif
|
|
|
|
|
|
#endif // __Debug_h__
|
|
|