#include "trace.h" #include #include #include "itoa.h" #include "lock.h" #include "uart.h" namespace tracing { namespace { struct Event { uint32_t timestamp; TraceEvent event; }; constexpr size_t kTraceBufferSize = 256; std::array buffer; size_t write_ptr = 0; size_t size = 0; } // namespace void trace(int raw_event) { trace(static_cast(raw_event)); } void trace(TraceEvent event) { const std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); const uint32_t uptime_ticks = now.time_since_epoch().count(); { InterruptLock lock; buffer[write_ptr] = {.timestamp = uptime_ticks, .event = event}; write_ptr = (write_ptr + 1) % buffer.size(); size = std::min(size + 1, kTraceBufferSize); #if TRACE_DUMP_WHEN_FULL if (size == kTraceBufferSize) { dump(); } #endif // TRACE_DUMP_WHEN_FULL } } void dump() { InterruptLock lock; if (size == kTraceBufferSize) { std::rotate(buffer.begin(), buffer.begin() + write_ptr, buffer.end()); } char number[] = "00000000"; UartWriteCrash("----\r\n"); for (Event event : std::span{buffer}.subspan(0, size)) { itoa(static_cast(event.timestamp), number); UartWriteCrash(number); UartWriteCrash(" "); itoa(static_cast(event.event), number); UartWriteCrash(number); UartWriteCrash("\r\n"); } UartWriteCrash("----\r\n"); size = 0; write_ptr = 0; } } // namespace tracing