st/st.h
Dominic Höglinger b76a97e394 Rename to "ST"
Name change due to confusion with the common programming verb "set".
2025-05-15 20:35:36 +02:00

286 lines
11 KiB
C

/*
* ST: Streaming Trace - A tiny tracing library
* Copyright (C) 2025 Dominic Hoeglinger
*
* 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 ST_H_INCLUDED_
#define ST_H_INCLUDED_
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
/** Maxmum signal name / tag length considered for the identifying hash */
#define ST_MAX_TAG_LEN (126)
/** Number of cached hashes */
#define ST_HASHCACHE_LINES (64)
/** Switch to enable or disable floating point support */
#define ST_FLOAT_DISABLE (false)
/** Overflow policy for the tracebuffer */
typedef enum
{
st_overwrite, /**< Overwrite oldest samples */
st_drop /**< Drop newest samples */
} st_overflow_policy_t;
/** Element used to allocate the tracebuffer */
typedef struct
{
char const * m_tag;
uint32_t m_timestamp;
uint32_t m_value;
uint8_t m_type;
uint8_t m_sub;
} st_trace_t;
/** @brief Integration hook writing out a packet to the desired interface
* @param[in] str Packet data
* @param[in] len Packet data length
* @return None
*/
void st_out(const char* const str, size_t len);
/** @brief Integration hook for retrieving a timestamp
* @return Timestamp value
*/
uint32_t st_timestamp(void);
/** @brief Integration hook which locks the tracebuffer
* This can be for instance a mutex or interrupt lock.
* @param[out] h handle value which will be passed to the #set_crit_off function
*/
void st_crit_on(uint32_t *h);
/** @brief Integration hook which unlocks the tracebuffer
* @param[in] h handle value set by #set_crit_on
*/
void st_crit_off(const uint32_t h);
/** @brief Initializes PET with the provided trace buffer
* @param[in] str Trace buffer array
* @param[in] len Trace buffer array length
* @return None
*/
void st_init(st_trace_t tracebuffer[], size_t ntraces);
/** @brief Returns the current trace buffer utilization
* @return Number of items used in the trace buffer
*/
size_t st_get_buffer_items(void);
/** @brief Enables or disables TTY mode
* TTY mode esures packet output is friendly for interactive console usage without a client.
* This means that at most 4 packets are sent at once, the data is encoded as hex digits
* and position is restored with each transmit. To erase a transmitted packet, see st_tty_rubout.
* @param[in] enable If true, enable TTY mode
* @return None
*/
void st_tty_mode(const bool enable);
/** @brief Creates a rubout packet clearing the maximum amount of data transmitted in TTY mode.
* This consists of a ANSI store, enough spaces to overwrite sent data and an ANSI restore.
* @param[out] buffer output buffer to render the rubout packet
* @param[in] buffer_size the size of the output buffer
* @return The packet size written to the buffer
*/
size_t st_tty_rubout(char buffer[], const size_t buffer_size);
/** @brief Enables tracing with the provided overflow policy
* @param[in] policy Either overwrite to overwrite oldest trace, or drop to drop the newest sample
* @return None
*/
void st_enable(const st_overflow_policy_t policy);
/** @brief Disables tracing
* @return None
*/
void st_disable(void);
/** @brief Clears the trace buffer deleting all captures samples
* @return None
*/
void st_clear(void);
/** @brief Render a set amount of tracebuffer items and write them out using st_out
* This function is for basic usage where the output function writes into a managed stream such as stdout
* @param[in] n Number of tracebuffer items to render, or 0 for the current size of the tracebuffer
* @param[in] compress if true, render the packets compressed
* @param[in] rubout if true, sends a rubout packet at the end clearing the trace output on a terminal
* @return None
*/
size_t st_output(size_t n, const bool compress, const bool rubout);
/** @brief Render a set amount of tracebuffer items and store them in the provided buffer
* This advanced function is intended to be used with DMA buffers.
* @param[out] buffer output buffer to render the packets
* @param[in] buffer_size the size of the output buffer
* @param[in] n Number of tracebuffer items to render, or 0 for the current size of the tracebuffer
* @param[in] compress if true, render the packets compressed
* @return None
*/
size_t st_render(char buffer[], const size_t buffer_size, const size_t n, const bool compress);
/** @brief Adds diagnostic samples to the tracebuffer
* Signals include:
* - ST.BufferItems:u32 - The current amount of tracebuffer items
* - ST.BufferHealth:u8 - The buffer utilization, zero means that the buffer is full while 255 means the buffer is free
* - ST.CompressionLevel:u8 - The average compression level if packets are rendered compressed
* - ST.CompressionTime:u32 - The average compression time spent for one packet render
* - ST.RenderTime:u32 - The average render time for one packet
* - ST.ItemsSent:u32 - The number of items sent since the last call to this function
* @return None
*/
void st_diagtrace(void);
/** @brief Trace an event
* @param[in] tag Signal name of the trace
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_evtrace(const char* const tag, const bool skip_time);
/** @brief Trace an u8 value
* @param[in] tag Signal name of the trace
* @param[in] value Value to trace
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_u8trace(const char* const tag, const uint8_t value, const bool skip_time);
/** @brief Trace an u16 value
* @param[in] tag Signal name of the trace
* @param[in] value Value to trace
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_u16trace(const char* const tag, const uint16_t value, const bool skip_time);
/** @brief Trace an u32 value
* @param[in] tag Signal name of the trace
* @param[in] value Value to trace
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_u32trace(const char* const tag, const uint32_t value, const bool skip_time);
/** @brief Trace an s8 value
* @param[in] tag Signal name of the trace
* @param[in] value Value to trace
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_s8trace(const char* const tag, const int8_t value, const bool skip_time);
/** @brief Trace an s16 value
* @param[in] tag Signal name of the trace
* @param[in] value Value to trace
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_s16trace(const char* const tag, const int16_t value, const bool skip_time);
/** @brief Trace an s32 value
* @param[in] tag Signal name of the trace
* @param[in] value Value to trace
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_s32trace(const char* const tag, const int32_t value, const bool skip_time);
/** @brief Trace an array of u8 values
* @param[in] tag Signal name of the trace
* @param[in] value Value array to trace
* @param[in] size Size of the value array, must be an integer literal for the client to detect the signal correctly
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_au8trace(const char* const tag, const uint8_t value[const], const uint8_t size, const bool skip_time);
/** @brief Trace an array of u16 values
* @param[in] tag Signal name of the trace
* @param[in] value Value array to trace
* @param[in] size Size of the value array, must be an integer literal for the client to detect the signal correctly
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_au16trace(const char* const tag, const uint16_t value[const], const uint8_t size, const bool skip_time);
/** @brief Trace an array of u32 values
* @param[in] tag Signal name of the trace
* @param[in] value Value array to trace
* @param[in] size Size of the value array, must be an integer literal for the client to detect the signal correctly
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_au32trace(const char* const tag, const uint32_t value[const], const uint8_t size, const bool skip_time);
/** @brief Trace an array of s8 values
* @param[in] tag Signal name of the trace
* @param[in] value Value array to trace
* @param[in] size Size of the value array, must be an integer literal for the client to detect the signal correctly
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_as8trace(const char* const tag, const int8_t value[const], const uint8_t size, const bool skip_time);
/** @brief Trace an array of s16 values
* @param[in] tag Signal name of the trace
* @param[in] value Value array to trace
* @param[in] size Size of the value array, must be an integer literal for the client to detect the signal correctly
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_as16trace(const char* const tag, const int16_t value[const], const uint8_t size, const bool skip_time);
/** @brief Trace an array of s32 values
* @param[in] tag Signal name of the trace
* @param[in] value Value array to trace
* @param[in] size Size of the value array, must be an integer literal for the client to detect the signal correctly
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_as32trace(const char* const tag, const int32_t value[const], const uint8_t size, const bool skip_time);
/** @brief Trace a string
* @param[in] tag Signal name of the trace
* @param[in] str String to trace
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_strtrace(const char* const tag, const char* const str, const bool skip_time);
#if (!ST_FLOAT_DISABLE)
/** @brief Trace an f32 value
* @param[in] tag Signal name of the trace
* @param[in] value Value to trace
* @param[in] skip_time Use last recorded timestamp for this trace
* @return None
*/
void st_f32trace(const char* const tag, const float value, const bool skip_time);
#endif
#endif