10 #include <hal_test/catch.hpp>
30 static Catch::SimplePcg32 global_prng = Catch::rng();
34 global_prng.seed(0xED743CC4u);
39 return u8(global_prng());
48 return (msb << 32) | lsb;
53 static std::map<std::string, unsigned> counts;
54 if (counts.find(pre) == counts.end()) counts[pre] = 0;
55 unsigned idx = counts[pre]++;
58 snprintf(buff,
sizeof(buff),
"simulations/%s_%03u.%s", pre, idx, ext);
59 return std::string(buff);
75 log::Log(log::ERROR,
"Unexpected null source.");
85 if (next == data[a]) {
88 log::Log(log::ERROR,
"String mismatch @ index")
98 log::Log(log::ERROR,
"Unexpected trailing bytes").
write10(rcvd - nbytes);
100 }
else if (rcvd < nbytes) {
104 return (match == nbytes);
117 for (
unsigned a = 0 ; a < nbytes ; ++a)
128 const unsigned PRINT_LIMIT = 100;
133 if (++diff <= PRINT_LIMIT) {
134 log::Log(log::ERROR,
"Stream mismatch @ index")
140 if (diff > PRINT_LIMIT) {
141 log::Log(log::ERROR,
"Stream mismatch truncated, additional errors")
142 .
write10(u32(diff - PRINT_LIMIT));
154 return (diff == 0) && (trail == 0);
157 CborParser::CborParser(
Readable* src,
bool verbose)
158 : m_len(src->get_read_ready())
161 REQUIRE(m_len <=
sizeof(m_dat));
169 #if SATCAT5_CBOR_ENABLE
172 static const QCBORItem ITEM_ERROR = {
183 QCBORDecodeContext cbor;
184 QCBORDecode_Init(&cbor, {m_dat, m_len}, QCBOR_DECODE_MODE_NORMAL);
188 int errcode = QCBORDecode_GetNext(&cbor, &item);
189 if (errcode || item.uDataType != QCBOR_TYPE_MAP)
return ITEM_ERROR;
197 errcode = QCBORDecode_GetNext(&cbor, &item);
198 if (errcode)
return ITEM_ERROR;
199 if (item.uNestingLevel > 1)
continue;
200 if (item.uLabelType == QCBOR_TYPE_INT64) {
201 errcode = QCBOR_Int64ToUInt32(item.label.int64, &key_rcvd);
202 if (errcode)
return ITEM_ERROR;
203 if (key_req == key_rcvd)
return item;
210 UsefulBufC key_buf = UsefulBuf_FromSZ(key_req);
213 QCBORDecodeContext cbor;
214 QCBORDecode_Init(&cbor, {m_dat, m_len}, QCBOR_DECODE_MODE_NORMAL);
218 int errcode = QCBORDecode_GetNext(&cbor, &item);
219 if (errcode || item.uDataType != QCBOR_TYPE_MAP)
return ITEM_ERROR;
226 errcode = QCBORDecode_GetNext(&cbor, &item);
227 if (errcode)
return ITEM_ERROR;
228 if (item.uNestingLevel > 1)
continue;
229 if (item.uLabelType == QCBOR_TYPE_BYTE_STRING ||
230 item.uLabelType == QCBOR_TYPE_TEXT_STRING) {
231 int diff = UsefulBuf_Compare(key_buf, item.label.string);
232 if (diff == 0)
return item;
242 : satcat5::eth::Protocol(dispatch, ethertype)
254 : satcat5::cfg::ConfigBusMmap(m_regs, satcat5::irq::IRQ_NONE)
260 for (
unsigned a = 0 ; a < cfg::MAX_DEVICES ; ++a)
265 u32* dev =
m_regs + devaddr * satcat5::cfg::REGS_PER_DEVICE;
266 for (
unsigned a = 0 ; a < cfg::REGS_PER_DEVICE ; ++a)
275 : satcat5::cfg::Interrupt(cfg)
282 static constexpr u32 MOCK_IRQ_ENABLE = (1u << 0);
283 static constexpr u32 MOCK_IRQ_REQUEST = (1u << 1);
286 : satcat5::cfg::Interrupt(cfg, 0, regaddr)
297 m_cfg->
read(m_regaddr, rdval);
298 m_cfg->
write(m_regaddr, rdval | MOCK_IRQ_REQUEST);
299 if (rdval & MOCK_IRQ_ENABLE) m_cfg->
irq_poll();
308 , ArrayRead(m_buffptr, len)
311 for (
unsigned a = 0 ; a <
len ; ++a)
343 {
return sqrt(
msq()); }
345 {
return sqrt(
var()); }
353 TimerSimulation::TimerSimulation()
354 : TimeRef(1000000), m_tref(0), m_tnow(0)
360 TimerSimulation::~TimerSimulation() {
370 if (m_tnow - m_tref >= 1000) {
382 m_tnow += 1000 - (m_tnow % 1000);
390 if (dly_msec > 10000000)
392 for (
unsigned a = 0 ; a < dly_msec ; ++a) {
394 satcat5::poll::service_all();
virtual satcat5::cfg::IoStatus read(unsigned regaddr, u32 &rdval)=0
Basic single-register read operation.
void irq_poll()
Poll all registered ConfigBus interrupt handlers.
virtual satcat5::cfg::IoStatus write(unsigned regaddr, u32 wrval)=0
Basic single-register write operation.
void irq_event() override
Method called whenever an interrupt is triggered.
Implemention of "net::Dispatch" for Ethernet frames.
Ephemeral Readable interface for a simple array.
void read_reset(unsigned len)
Reset read position to the start of the backing array, and set the readable length to the specified v...
Limited read of next N bytes.
unsigned get_read_ready() const override
How many bytes can be read without blocking?
Abstract API for reading byte-streams and packets.
u8 read_u8()
One of many functions for reading integer/floating point values, see details.
virtual bool read_bytes(unsigned nbytes, void *dst)
Read 0 or more bytes into a buffer.
virtual void read_finalize()
Consume any remaining bytes in this frame, if applicable.
virtual unsigned get_read_ready() const =0
How many bytes can be read without blocking?
Abstract API for writing byte-streams and packets.
virtual void write_bytes(unsigned nbytes, const void *src)
Write 0 or more bytes from a buffer.
void write_u8(u8 data)
One of many functions for writing integer/floating point values, see details.
virtual bool write_finalize()
Mark end of frame and release temporary working data.
The Log class creates and formats one log message.
Log & write10(s32 val)
Print integer as a decimal value with no leading zeros.
Log & write(const char *str)
Formatting methods for various data types.
void request_poll()
Call this method to request polling at a later time.
void set_clock(satcat5::util::TimeRef *timer)
Immediately set the system time reference.
satcat5::util::TimeRef * get_clock() const
Get the system time reference, if one is set.
A simple CBOR decoder for use in unit tests.
QCBORItem get(const char *key) const
Attempt to fetch top-level QCBOR item for the given key.
Log any received Ethernet traffic of the designated type.
LogProtocol(satcat5::eth::Dispatch *dispatch, const satcat5::eth::MacType ðertype)
Attach this object to an Ethernet interface and set filter.
void frame_rcvd(satcat5::io::LimitedRead &src) override
Dispatch calls frame_rcvd(...) for each incoming frame with with a matching net::Type value.
Mockup for a memory-mapped ConfigBus.
void clear_all(u32 val=0)
Clear all registers for all devices.
u32 m_regs[satcat5::cfg::MAX_TOTAL_REGS]
Simulated register-map for up to 256 devices.
void clear_dev(unsigned devaddr, u32 val=0)
Clear all registers for the specified device-ID.
void irq_event()
Make event-handler accessible (normally private)
MockConfigBusMmap()
Create this mock interface.
Mockup for a ConfigBus interrupt register.
void fire()
Trigger a virtual interrupt.
MockInterrupt(satcat5::cfg::ConfigBus *cfg)
No associated register, assumes interrupt has fired.
Readable source for a pseudorandom block of data.
RandomSource(unsigned len)
Generate a pseudorandom block of data.
satcat5::io::Readable * read()
Prepare to read or re-read data from start of block.
unsigned len() const
Length of the internal block.
Measure various statistics of a discrete-time series.
double m_max
Running maximum.
double rms() const
Root-mean-square.
double var() const
Variance.
Statistics()
Create an empty dataset.
double std() const
Standard deviation.
void add(double x)
Add a new data point.
double min() const
Minimum over all inputs.
double msq() const
Mean-square.
double m_sumsq
Sum of squares.
double max() const
Maximum over all inputs.
double m_sum
Sum of inputs.
unsigned m_count
Number of data points.
double m_min
Running minimum.
double mean() const
Mean of all data points.
Timekeeper object for granular simulation of elapsed time.
void sim_step()
Step forward one millisecond.
void sim_wait(unsigned dly_msec)
Step forward N milliseconds.
u32 raw() override
Read current time in arbitrary "ticks".
u8 *const m_buffptr
Pointer to the underlying buffer.
I/O interface core definitions.
Diagnostic logging to UART and/or Ethernet ports.
Timekeeper timekeeper
There is a single global instance of the Timekeeper class.
General-purpose ConfigBus emulator utilities.
Miscellaneous simulation and test helper functions.
u8 rand_u8()
Reproducible PRNG used for unit tests.
bool write_random_final(satcat5::io::Writeable *dst, unsigned nbytes)
Write random bytes and finalize.
u32 rand_u32()
Reproducible PRNG used for unit tests.
u64 rand_u64()
Reproducible PRNG used for unit tests.
bool read(satcat5::io::Readable *src, unsigned nbytes, const u8 *data)
Compare next frame to reference array.
bool read_equal(satcat5::io::Readable *src1, satcat5::io::Readable *src2)
Check if two streams are equal.
std::string sim_filename(const char *pre, const char *ext)
Generate a unique filename for storing unit-test results.
bool pre_test_reset()
Reset the global PRNG state used for rand_*(), below.
bool write(satcat5::io::Writeable *dst, unsigned nbytes, const u8 *data)
Write byte array and finalize.
void write_random_bytes(satcat5::io::Writeable *dst, unsigned nbytes)
Write random bytes, without finalizing.
EtherType field (uint16) is used a protocol-ID [1536..65535].
u16 value
The 16-bit value is stored in processor-native order.
Timestamp for measuring elapsed time.
Miscellaneous mathematical utility functions.