eive-obsw/gomspace/libcsp/include/csp/csp_debug.h
2020-11-23 11:42:22 +01:00

151 lines
4.4 KiB
C

/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_DEBUG_H_
#define _CSP_DEBUG_H_
#include <inttypes.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Debug levels */
typedef enum {
CSP_ERROR = 0,
CSP_WARN = 1,
CSP_INFO = 2,
CSP_BUFFER = 3,
CSP_PACKET = 4,
CSP_PROTOCOL = 5,
CSP_LOCK = 6,
} csp_debug_level_t;
/* Extract filename component from path */
#define BASENAME(_file) ((strrchr(_file, '/') ? : (strrchr(_file, '\\') ? : _file)) + 1)
/* Implement csp_assert_fail_action to override default failure action */
extern void __attribute__((weak)) csp_assert_fail_action(const char *assertion, const char *file, int line);
#ifndef NDEBUG
#define csp_assert(exp) \
do { \
if (!(exp)) { \
const char *assertion = #exp; \
const char *file = BASENAME(__FILE__); \
int line = __LINE__; \
printf("\E[1;31m[%02" PRIu8 "] Assertion \'%s\' failed in %s:%d\E[0m\r\n", \
csp_get_address(), assertion, file, line); \
if (csp_assert_fail_action) \
csp_assert_fail_action(assertion, file, line); \
} \
} while (0)
#else
#define csp_assert(...) do {} while (0)
#endif
#ifdef __AVR__
#include <stdio.h>
#include <avr/pgmspace.h>
#define CONSTSTR(data) PSTR(data)
#undef printf
#undef sscanf
#undef scanf
#undef sprintf
#undef snprintf
#define printf(s, ...) printf_P(PSTR(s), ## __VA_ARGS__)
#define sscanf(buf, s, ...) sscanf_P(buf, PSTR(s), ## __VA_ARGS__)
#define scanf(s, ...) scanf_P(PSTR(s), ## __VA_ARGS__)
#define sprintf(buf, s, ...) sprintf_P(buf, PSTR(s), ## __VA_ARGS__)
#define snprintf(buf, size, s, ...) snprintf_P(buf, size, PSTR(s), ## __VA_ARGS__)
#else
#define CONSTSTR(data) data
#endif
#ifdef CSP_DEBUG
#define csp_debug(level, format, ...) do { do_csp_debug(level, CONSTSTR(format), ##__VA_ARGS__); } while(0)
#else
#define csp_debug(...) do {} while (0)
#endif
#ifdef CSP_LOG_LEVEL_ERROR
#define csp_log_error(format, ...) csp_debug(CSP_ERROR, format, ##__VA_ARGS__)
#else
#define csp_log_error(...) do {} while (0)
#endif
#ifdef CSP_LOG_LEVEL_WARN
#define csp_log_warn(format, ...) csp_debug(CSP_WARN, format, ##__VA_ARGS__)
#else
#define csp_log_warn(...) do {} while (0)
#endif
#ifdef CSP_LOG_LEVEL_INFO
#define csp_log_info(format, ...) csp_debug(CSP_INFO, format, ##__VA_ARGS__)
#else
#define csp_log_info(...) do {} while (0)
#endif
#ifdef CSP_LOG_LEVEL_DEBUG
#define csp_log_buffer(format, ...) csp_debug(CSP_BUFFER, format, ##__VA_ARGS__)
#define csp_log_packet(format, ...) csp_debug(CSP_PACKET, format, ##__VA_ARGS__)
#define csp_log_protocol(format, ...) csp_debug(CSP_PROTOCOL, format, ##__VA_ARGS__)
#define csp_log_lock(format, ...) csp_debug(CSP_LOCK, format, ##__VA_ARGS__)
#else
#define csp_log_buffer(...) do {} while (0)
#define csp_log_packet(...) do {} while (0)
#define csp_log_protocol(...) do {} while (0)
#define csp_log_lock(...) do {} while (0)
#endif
/**
* This function should not be used directly, use csp_log_<level>() macro instead
* @param level
* @param format
*/
void do_csp_debug(csp_debug_level_t level, const char *format, ...);
/**
* Toggle debug level on/off
* @param level Level to toggle
*/
void csp_debug_toggle_level(csp_debug_level_t level);
/**
* Set debug level
* @param level Level to set
* @param value New level value
*/
void csp_debug_set_level(csp_debug_level_t level, bool value);
/**
* Get current debug level value
* @param level Level value to get
* @return Level value
*/
int csp_debug_get_level(csp_debug_level_t level);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_DEBUG_H_