mirror of
https://github.com/OpenSolo/OpenSolo.git
synced 2025-04-30 06:34:38 +02:00
115 lines
2.6 KiB
C++
115 lines
2.6 KiB
C++
#ifndef SERIAL_LOG_H
|
|
#define SERIAL_LOG_H
|
|
|
|
#include <stdint.h>
|
|
#include <pthread.h>
|
|
#include "CircularBuffer.h"
|
|
|
|
// Log all traffic to/from the STM32.
|
|
// The log is just a circular buffer to which packets are written,
|
|
// prepended by a timestamp, length, and flags:
|
|
//
|
|
// uint64_t timestamp; usec since unix epoch
|
|
// uint16_t num_bytes; size of packet[]
|
|
// uint8_t flags; upstream or downstream
|
|
// uint8_t packet[]; packet bytes, as passed to or received from the slip
|
|
// encoder
|
|
|
|
class SerialLog
|
|
{
|
|
|
|
public:
|
|
// Header logged for each packet.
|
|
struct __attribute((__packed__)) PacketEntry {
|
|
uint64_t timestamp;
|
|
uint16_t num_bytes;
|
|
uint8_t flags;
|
|
uint8_t packet[0]; // variable-length
|
|
};
|
|
|
|
SerialLog(unsigned log_size, unsigned timeout_us = 0);
|
|
|
|
~SerialLog();
|
|
|
|
// PacketEntry.flags field
|
|
static const int PKTFLG_DIR = 0x01; // mask
|
|
static const int PKTFLG_UP = 0x00; // STM32->i.MX6
|
|
static const int PKTFLG_DOWN = 0x01; // i.MX6->STM32
|
|
|
|
// Log a packet (PacketEntry followed by the supplied bytes)
|
|
bool log_packet(const void *packet, unsigned num_bytes, uint8_t flags);
|
|
|
|
// Return enable status of this logger. Logging is automatically
|
|
// disabled when the timeout is reached.
|
|
bool enabled(void) const
|
|
{
|
|
return _enabled;
|
|
}
|
|
|
|
// Size of logging buffer
|
|
unsigned size(void) const
|
|
{
|
|
return _c_buf.size();
|
|
}
|
|
|
|
// Bytes used in buffer
|
|
unsigned used(void) const
|
|
{
|
|
return _c_buf.used();
|
|
}
|
|
|
|
// Free bytes in buffer
|
|
unsigned free(void) const
|
|
{
|
|
return _c_buf.free();
|
|
}
|
|
|
|
// Get bytes from buffer.
|
|
bool get(void *p, unsigned num_bytes)
|
|
{
|
|
return _c_buf.get(p, num_bytes);
|
|
}
|
|
|
|
// Get structure from buffer.
|
|
template < class type >
|
|
bool get(type *p)
|
|
{
|
|
return get(p, sizeof(type));
|
|
}
|
|
|
|
// Discard a number of bytes from the buffer.
|
|
bool discard(unsigned num_bytes)
|
|
{
|
|
return _c_buf.discard(num_bytes);
|
|
}
|
|
|
|
private:
|
|
CircularBuffer _c_buf;
|
|
pthread_mutex_t _mutex;
|
|
bool _mutex_initted;
|
|
unsigned _timeout_us;
|
|
uint64_t _last_up_time_us;
|
|
bool _enabled;
|
|
|
|
// Discard a packet
|
|
bool discard_packet(void);
|
|
void check_timeout(uint64_t now);
|
|
|
|
void lock(void)
|
|
{
|
|
pthread_mutex_lock(&_mutex);
|
|
}
|
|
|
|
void unlock(void)
|
|
{
|
|
pthread_mutex_unlock(&_mutex);
|
|
}
|
|
};
|
|
|
|
std::ostream &operator<<(std::ostream &, SerialLog::PacketEntry &);
|
|
|
|
// destructive dump; log is empty after this
|
|
std::ostream &operator<<(std::ostream &, SerialLog &);
|
|
|
|
#endif // SERIAL_LOG_H
|