diff --git a/src/Stream/traceStream.cpp b/src/Stream/traceStream.cpp new file mode 100644 index 0000000..ade9d4c --- /dev/null +++ b/src/Stream/traceStream.cpp @@ -0,0 +1,160 @@ +#include "traceStream.hpp" +#include "../trace.h" +#include + +#define MAX_LINE_LEN 128 + +#ifdef TRACE_LOG_COLORS + #define TRACE_LOG_COLOR_BLACK "30" + #define TRACE_LOG_COLOR_RED "31" // ERROR + #define TRACE_LOG_COLOR_GREEN "32" // INFO + #define TRACE_LOG_COLOR_YELLOW "33" // WARNING + #define TRACE_LOG_COLOR_BLUE "34" + #define TRACE_LOG_COLOR_MAGENTA "35" + #define TRACE_LOG_COLOR_CYAN "36" // DEBUG + #define TRACE_LOG_COLOR_GRAY "37" // VERBOSE + #define TRACE_LOG_COLOR_WHITE "38" + + #define TRACE_LOG_COLOR(COLOR) "\033[0;" COLOR "m" + #define TRACE_LOG_BOLD(COLOR) "\033[1;" COLOR "m" + #define TRACE_LOG_RESET_COLOR "\033[0m" + + #define TRACE_LOG_COLOR_E TRACE_LOG_COLOR(TRACE_LOG_COLOR_RED) + #define TRACE_LOG_COLOR_W TRACE_LOG_COLOR(TRACE_LOG_COLOR_YELLOW) + #define TRACE_LOG_COLOR_I TRACE_LOG_COLOR(TRACE_LOG_COLOR_GREEN) + #define TRACE_LOG_COLOR_D TRACE_LOG_COLOR(TRACE_LOG_COLOR_CYAN) + #define TRACE_LOG_COLOR_V TRACE_LOG_COLOR(TRACE_LOG_COLOR_GRAY) + #define TRACE_LOG_COLOR_PRINT(letter) log_printf(TRACE_LOG_COLOR_##letter) + #define TRACE_LOG_COLOR_PRINT_END log_printf(TRACE_LOG_RESET_COLOR) +#else + #define TRACE_LOG_COLOR_E + #define TRACE_LOG_COLOR_W + #define TRACE_LOG_COLOR_I + #define TRACE_LOG_COLOR_D + #define TRACE_LOG_COLOR_V + #define TRACE_LOG_RESET_COLOR + #define TRACE_LOG_COLOR_PRINT(letter) + #define TRACE_LOG_COLOR_PRINT_END +#endif + +#define TRACE_SHORT_LOG_FORMAT(letter, format) PSTR(TRACE_LOG_COLOR_##letter "%s" TRACE_LOG_RESET_COLOR "\r\n"), format +#define TRACE_LOG_FORMAT(letter, format) PSTR(TRACE_LOG_COLOR_##letter "[%6lu][" #letter "] %s" TRACE_LOG_RESET_COLOR "\r\n"), millis(), format + +static Stream * _out = nullptr; // vystupni stream + +static void (*message_cb)(const char *) = nullptr; + +static void print(const uint8_t severity, const char * buffer, const int length) { + + if (_out) { + if (severity == TRACE_ERROR) + _out->printf_P(TRACE_LOG_FORMAT(E, buffer)); + else if (severity == TRACE_DEBUG) + _out->printf_P(TRACE_LOG_FORMAT(D, buffer)); + else if (severity == TRACE_WARNING) + _out->printf_P(TRACE_LOG_FORMAT(W, buffer)); + else if (severity == TRACE_INFO) + _out->printf_P(TRACE_LOG_FORMAT(I, buffer)); + else if (severity == TRACE_VERBOSE) + _out->printf_P(TRACE_LOG_FORMAT(V, buffer)); + } +} + +void trace_init() { +} + +void trace_clear() { +} + +void trace_end() { + + trace_clear(); +} + +void trace_print(const uint8_t severity, const __FlashStringHelper * fmt, ...) { + char buffer[MAX_LINE_LEN + 1]; + va_list args; + + va_start(args, fmt); + const int length = vsnprintf_P(buffer, sizeof(buffer), (const char *) fmt, args); + va_end(args); + + print(severity, buffer, length); +} + +void trace_print(const uint8_t severity, const char * fmt, ...) { + char buffer[MAX_LINE_LEN + 1]; + va_list args; + + va_start(args, fmt); + const int length = vsnprintf(buffer, sizeof(buffer), fmt, args); + va_end(args); + + print(severity, buffer, length); +} + +void trace_registermessagecb(void (*cb)(const char *)) { + + message_cb = cb; +} + +static char hexascii(uint8_t n) { + + n &= 0xf; + if (n > 9) + return n + ('A' - 10); + else + return n + '0'; +} + +void trace_dump(const uint8_t severity, const char * prefix, const uint8_t * address, size_t size) { + char buffer[MAX_LINE_LEN + 1 + 3]; + int idx = 0; + + if (prefix) + idx = snprintf_P(buffer, MAX_LINE_LEN, PSTR("%s"), prefix); + + while ((idx < MAX_LINE_LEN) && size) { + buffer[idx] = hexascii(*address >> 4); + ++idx; + buffer[idx] = hexascii(*address); + ++idx; + buffer[idx] = 0x20; + ++idx; + ++address; + --size; + } + buffer[idx] = 0; + print(severity, buffer, idx); +} + +void trace_dump(const uint8_t severity, const __FlashStringHelper * prefix, const uint8_t * address, size_t size) { + char buffer[MAX_LINE_LEN + 1 + 3]; + int idx = 0; + + if (prefix) { + char dummy[64]; + + strcpy_P(dummy, (const char *) prefix); + idx = snprintf_P(buffer, MAX_LINE_LEN, PSTR("%s"), dummy); + } + + while ((idx < MAX_LINE_LEN) && size) { + buffer[idx] = hexascii(*address >> 4); + ++idx; + buffer[idx] = hexascii(*address); + ++idx; + buffer[idx] = 0x20; + ++idx; + ++address; + --size; + } + buffer[idx] = 0; + print(severity, buffer, idx); +} + +void trace_setstream(Stream * out) { + + _out = out; +} +// EOF diff --git a/src/Stream/traceStream.hpp b/src/Stream/traceStream.hpp new file mode 100644 index 0000000..128d1fc --- /dev/null +++ b/src/Stream/traceStream.hpp @@ -0,0 +1,88 @@ +/** + * @file traceStream.hpp + * @author Pavel Brychta, http://www.xpablo.cz + * + * Copyright (c) 2016-24 Pavel Brychta. All rights reserved. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#pragma once + +#include + +/** + * @brief Inicializace modulu + */ +void trace_init(); + +/** + * @brief Vyprazdneni stopovaciho bufferu + */ +void trace_clear(); + +/** + * @brief Ukonceni prace stopare - vyprazdni buffer + */ +void trace_end(); + +/** + * @brief Ulozeni zpravy s obsahem z programove pameti (PROGMEM, F, ...) + * + * @param[in] severity Uroven - viz. TRACE_ERROR, TRACE_WARNING, ... + * @param[in] fmt Formatovaci retezec vysledne zpravy. Je ulozeny v PROGMEM + * @param[in] Parametry, ktere jsou dosazeny do formatovaciho retezce + */ +void trace_print(uint8_t severity, const __FlashStringHelper * fmt, ...); + +/** + * @brief Ulozeni zpravy + * + * @param[in] severity Uroven - viz. TRACE_ERROR, TRACE_WARNING, ... + * @param[in] fmt Formatovaci retezec vysledne zpravy. + * @param[in] Parametry, ktere jsou dosazeny do formatovaciho retezce + */ +void trace_print(uint8_t severity, const char * fmt, ...); + +/** + * @brief Registrace callback metody - je volana pri kazde zmene (zapisu) do stopare + * + * @param[in] Ukazatel na volanou metodu + */ +void trace_registermessagecb(void (*)(const char * msg)); + +void trace_printfunc(uint8_t severity, const char * func, const char * file, int line, const char * fmt, ...); + +/** + * @brief Vypis oblasti pameti (dump) + * + * @param[in] severity Uroven - viz. TRACE_ERROR, TRACE_WARNING, ... + * @param[in] prefix Prefix (text), ktery je uvedeny pred vlastnim vypisem pameti + * @param address Adresa pocatku vypisu + * @param[in] size Pocet vypisovanych bytu (POZOR!!! musi se vejit do jednoho radku stopare!!!) + */ +void trace_dump(uint8_t severity, const char * prefix, uint8_t * address, size_t size); + +/** + * @brief Vypis oblasti pameti (dump) + * + * @param[in] severity Uroven - viz. TRACE_ERROR, TRACE_WARNING, ... + * @param[in] prefix Prefix (text), ktery je uvedeny pred vlastnim vypisem pameti + * @param address Adresa pocatku vypisu + * @param[in] size Pocet vypisovanych bytu (POZOR!!! musi se vejit do jednoho radku stopare!!!) + */ +void trace_dump(uint8_t severity, const __FlashStringHelper * prefix, uint8_t * address, size_t size); + +void trace_setstream(Stream * out); diff --git a/src/trace.h b/src/trace.h index cda46bc..bb6993f 100644 --- a/src/trace.h +++ b/src/trace.h @@ -21,7 +21,7 @@ */ #pragma once -// Vydefinujeme-li promennou TRACE_ALL=1, pak TRACEPLUS se bude vypisovat vsechny zpravy +// Vydefinujeme-li promennou TRACE_ALL=1, pak TRACEPLUS bude vypisovat vsechny zpravy nezavisle od povoleni/zakazani // Definice jednotlivych typu hlaseni do trasovani #define TRACE_NONE (-1) // nic @@ -52,6 +52,21 @@ #define TRACE_ADDWEB(srv) trace_addweb(srv) #define TRACE_FORCEUPDATE(a) trace_forceupdate() +#elif defined(TRACE_USE_STREAM) + #include "Stream/traceStream.hpp" + + #define TRACE(severity, text, ...) \ + do { \ + constexpr bool trace_limit = (severity <= TRACE_LIMIT); \ + if (trace_limit) \ + trace_print(severity, PSTR(text), ##__VA_ARGS__); \ + } while (0) + #define TRACEFUNC(severity, ...) trace_printfunc(severity, __func__, __FILE__, TOSTRING(__LINE__), __VA_ARGS__) + #define TRACEDUMP(severity, prefix, address, size) trace_dump(severity, prefix, address, size) + #define TRACE_INIT(a) trace_init() + #define TRACE_ADDWEB(srv) ((void) 0) + #define TRACE_FORCEUPDATE(a) ((void) 0) + #else #if defined(ESP32) #include