From 7000c2e825b3c89be65f56f07974b4b8f59cd0c7 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Fri, 1 May 2026 10:33:39 -0700 Subject: [PATCH] extract debug_log into its own static library; expose log_view iterator instead of raw ring_buffer --- CMakeLists.txt | 2 ++ debug_log/CMakeLists.txt | 7 ++++ debug_log/debug_log.cpp | 28 +++++++++++++++ debug_log/debug_log.h | 52 ++++++++++++++++++++++++++++ {include => debug_log}/ring_buffer.h | 0 include/debug_log.h | 39 --------------------- src/handlers.cpp | 3 +- 7 files changed, 91 insertions(+), 40 deletions(-) create mode 100644 debug_log/CMakeLists.txt create mode 100644 debug_log/debug_log.cpp create mode 100644 debug_log/debug_log.h rename {include => debug_log}/ring_buffer.h (100%) delete mode 100644 include/debug_log.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d16b6c1..1f1a2ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.13) add_subdirectory(w6300) +add_subdirectory(debug_log) add_library(limen STATIC src/arp.cpp @@ -23,6 +24,7 @@ target_compile_options(limen PRIVATE -Wall -Wextra -Wno-unused-parameter) target_link_libraries(limen PUBLIC w6300 + debug_log pico_stdlib pico_sha256 pico_unique_id diff --git a/debug_log/CMakeLists.txt b/debug_log/CMakeLists.txt new file mode 100644 index 0000000..4ad77f1 --- /dev/null +++ b/debug_log/CMakeLists.txt @@ -0,0 +1,7 @@ +add_library(debug_log STATIC debug_log.cpp) + +target_include_directories(debug_log PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +target_compile_options(debug_log PRIVATE -Wall -Wextra -Wno-unused-parameter) + +target_link_libraries(debug_log PUBLIC pico_stdlib) diff --git a/debug_log/debug_log.cpp b/debug_log/debug_log.cpp new file mode 100644 index 0000000..1f1d039 --- /dev/null +++ b/debug_log/debug_log.cpp @@ -0,0 +1,28 @@ +#include "debug_log.h" +#include +#include +#include "ring_buffer.h" + +namespace { + +constexpr uint16_t LOG_CAP = 32; +ring_buffer buf; + +} // namespace + +void dlog(std::string_view msg) { + buf.push_overwrite(log_entry{static_cast(time_us_32()), std::string(msg)}); +} + +void dlogf(const char* fmt, ...) { + char b[128]; + va_list args; + va_start(args, fmt); + vsnprintf(b, sizeof(b), fmt, args); + va_end(args); + dlog(b); +} + +log_view log_entries() { + return log_view{buf.data.data(), buf.head, LOG_CAP, buf.used()}; +} diff --git a/debug_log/debug_log.h b/debug_log/debug_log.h new file mode 100644 index 0000000..0838283 --- /dev/null +++ b/debug_log/debug_log.h @@ -0,0 +1,52 @@ +#pragma once +#include +#include +#include +#include "pico/time.h" + +struct log_entry { + uint32_t timestamp_us; + std::string message; +}; + +class log_iterator { + const log_entry* data; + uint16_t base; + uint16_t cap; + uint16_t pos; +public: + log_iterator(const log_entry* d, uint16_t b, uint16_t c, uint16_t p) + : data(d), base(b), cap(c), pos(p) {} + const log_entry& operator*() const { return data[(base + pos) % cap]; } + log_iterator& operator++() { ++pos; return *this; } + bool operator!=(const log_iterator& o) const { return pos != o.pos; } +}; + +class log_view { + const log_entry* data; + uint16_t base; + uint16_t cap; + uint16_t count; +public: + log_view(const log_entry* d, uint16_t b, uint16_t c, uint16_t n) + : data(d), base(b), cap(c), count(n) {} + log_iterator begin() const { return {data, base, cap, 0}; } + log_iterator end() const { return {data, base, cap, count}; } +}; + +log_view log_entries(); + +void dlog(std::string_view msg); + +__attribute__((format(printf, 1, 2))) +void dlogf(const char* fmt, ...); + +template +inline void dlog_if_slow(std::string_view label, uint32_t threshold_us, F&& fn) { + uint32_t t0 = time_us_32(); + fn(); + uint32_t elapsed = time_us_32() - t0; + if (elapsed > threshold_us) { + dlogf("%.*s %luus", static_cast(label.size()), label.data(), static_cast(elapsed)); + } +} diff --git a/include/ring_buffer.h b/debug_log/ring_buffer.h similarity index 100% rename from include/ring_buffer.h rename to debug_log/ring_buffer.h diff --git a/include/debug_log.h b/include/debug_log.h deleted file mode 100644 index ce241a9..0000000 --- a/include/debug_log.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include "pico/time.h" -#include "ring_buffer.h" - -struct log_entry { - uint32_t timestamp_us; - std::string message; -}; - -inline ring_buffer g_debug_log; - -inline void dlog(std::string_view msg) { - g_debug_log.push_overwrite(log_entry{static_cast(time_us_32()), std::string(msg)}); -} - -__attribute__((format(printf, 1, 2))) -inline void dlogf(const char* fmt, ...) { - char buf[128]; - va_list args; - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - dlog(buf); -} - -template -inline void dlog_if_slow(std::string_view label, uint32_t threshold_us, F&& fn) { - uint32_t t0 = time_us_32(); - fn(); - uint32_t elapsed = time_us_32() - t0; - if (elapsed > threshold_us) - dlogf("%.*s %luus", static_cast(label.size()), label.data(), static_cast(elapsed)); -} - diff --git a/src/handlers.cpp b/src/handlers.cpp index c010095..cb7e6d5 100644 --- a/src/handlers.cpp +++ b/src/handlers.cpp @@ -45,8 +45,9 @@ std::optional handle_info(const responder&, const RequestInfo&) { std::optional handle_log(const responder&, const RequestLog&) { ResponseLog resp; - for (auto& e : g_debug_log) + for (auto& e : log_entries()) { resp.entries.push_back(LogEntry{e.timestamp_us, e.message}); + } return resp; }