mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
187 lines
7.0 KiB
C
187 lines
7.0 KiB
C
/*
|
|
* Copyright (C) 2018 Eistec AB
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup tests
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief Another peripheral timer test application
|
|
*
|
|
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
|
|
*
|
|
* @}
|
|
*/
|
|
|
|
#include "print_results.h"
|
|
#include "matstat.h"
|
|
#include "fmt.h"
|
|
#include "bench_timers_config.h"
|
|
|
|
static void print_statistics(const matstat_state_t *state, const stat_limits_t *limits)
|
|
{
|
|
if (state->count == 0) {
|
|
print_str("no samples\n");
|
|
return;
|
|
}
|
|
if (state->count == 1) {
|
|
print_str("single sample: ");
|
|
print_s32_dec((int32_t)state->sum);
|
|
print("\n", 1);
|
|
return;
|
|
}
|
|
int32_t mean = matstat_mean(state);
|
|
uint64_t variance = matstat_variance(state);
|
|
|
|
char buf[20];
|
|
print(buf, fmt_lpad(buf, fmt_u32_dec(buf, state->count), 8, ' '));
|
|
print(" ", 1);
|
|
print(buf, fmt_lpad(buf, fmt_s64_dec(buf, state->sum), 9, ' '));
|
|
print(" ", 1);
|
|
print(buf, fmt_lpad(buf, fmt_u64_dec(buf, state->sum_sq), 12, ' '));
|
|
print(" ", 1);
|
|
print(buf, fmt_lpad(buf, fmt_s32_dec(buf, state->min), 6, ' '));
|
|
print(" ", 1);
|
|
print(buf, fmt_lpad(buf, fmt_s32_dec(buf, state->max), 5, ' '));
|
|
print(" ", 1);
|
|
print(buf, fmt_lpad(buf, fmt_s32_dec(buf, mean), 5, ' '));
|
|
print(" ", 1);
|
|
print(buf, fmt_lpad(buf, fmt_u64_dec(buf, variance), 6, ' '));
|
|
if (limits) {
|
|
if ((mean < limits->mean_low) || (limits->mean_high < mean) ||
|
|
(variance < limits->variance_low) || (limits->variance_high < variance) ) {
|
|
/* mean or variance is outside the expected range, alert the user */
|
|
print_str(" <=== SIC!");
|
|
}
|
|
}
|
|
print("\n", 1);
|
|
}
|
|
|
|
static void print_totals(const matstat_state_t *states, size_t nelem, const stat_limits_t *limits)
|
|
{
|
|
matstat_state_t totals;
|
|
matstat_clear(&totals);
|
|
for (size_t k = 0; k < nelem; ++k) {
|
|
matstat_merge(&totals, &states[k]);
|
|
}
|
|
print_statistics(&totals, limits);
|
|
}
|
|
|
|
static void print_detailed(const matstat_state_t *states, size_t nelem, unsigned int test_min, const stat_limits_t *limits)
|
|
{
|
|
if (LOG2_STATS) {
|
|
print_str(" interval count sum sum_sq min max mean variance\n");
|
|
for (unsigned int k = 0; k < nelem; ++k) {
|
|
char buf[20];
|
|
unsigned int num = (1 << k);
|
|
if (num >= TEST_NUM) {
|
|
break;
|
|
}
|
|
unsigned int start = num + test_min;
|
|
if (num == 1) {
|
|
/* special case, bitarithm_msb will return 0 for both 0 and 1 */
|
|
start = test_min;
|
|
}
|
|
print(buf, fmt_lpad(buf, fmt_u32_dec(buf, start), 4, ' '));
|
|
print_str(" - ");
|
|
print(buf, fmt_lpad(buf, fmt_u32_dec(buf, test_min + (num * 2) - 1), 4, ' '));
|
|
print_str(": ");
|
|
print_statistics(&states[k], limits);
|
|
}
|
|
print_str(" TOTAL ");
|
|
}
|
|
else {
|
|
print_str("interval count sum sum_sq min max mean variance\n");
|
|
for (unsigned int k = 0; k < nelem; ++k) {
|
|
char buf[10];
|
|
print(buf, fmt_lpad(buf, fmt_u32_dec(buf, k + test_min), 7, ' '));
|
|
print_str(": ");
|
|
print_statistics(&states[k], limits);
|
|
}
|
|
print_str(" TOTAL: ");
|
|
}
|
|
print_totals(states, nelem, limits);
|
|
}
|
|
|
|
void print_results(const result_presentation_t *pres, const matstat_state_t *ref_states, const matstat_state_t *int_states)
|
|
{
|
|
static char buf[48]; /* String formatting temporary buffer, not thread safe */
|
|
print_str("------------- BEGIN STATISTICS --------------\n");
|
|
print_str("===== Reference timer statistics =====\n");
|
|
print_str("Limits: mean: [");
|
|
print_s32_dec(pres->ref_limits->mean_low);
|
|
print_str(", ");
|
|
print_s32_dec(pres->ref_limits->mean_high);
|
|
print_str("], variance: [");
|
|
print_u32_dec(pres->ref_limits->variance_low);
|
|
print_str(", ");
|
|
print_u32_dec(pres->ref_limits->variance_high);
|
|
print_str("]\n");
|
|
print_str("Target error (actual trigger time - expected trigger time), in reference timer ticks\n");
|
|
print_str("positive: timer under test is late, negative: timer under test is early\n");
|
|
|
|
if (DETAILED_STATS) {
|
|
static const unsigned int count = ((LOG2_STATS) ? (TEST_LOG2NUM) : (TEST_NUM));
|
|
unsigned k = 0;
|
|
for (unsigned g = 0; g < pres->num_groups; ++g) {
|
|
for (unsigned c = 0; c < pres->groups[g].num_sub_labels; ++c) {
|
|
print_str("=== ");
|
|
print_str(pres->groups[g].label);
|
|
print(" ", 1);
|
|
print_str(pres->groups[g].sub_labels[c]);
|
|
print_str(" ===\n");
|
|
print_detailed(&ref_states[k * count], count, pres->offsets[k], pres->ref_limits);
|
|
++k;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
print_str("function count sum sum_sq min max mean variance\n");
|
|
unsigned k = 0;
|
|
for (unsigned g = 0; g < pres->num_groups; ++g) {
|
|
print("\n", 1);
|
|
print(buf, fmt_lpad(buf, fmt_str(buf, pres->groups[g].label), 18, ' '));
|
|
print(" ", 1);
|
|
print_totals(&ref_states[k], pres->groups[g].num_sub_labels, pres->ref_limits);
|
|
for (unsigned c = 0; c < pres->groups[g].num_sub_labels; ++c) {
|
|
print(buf, fmt_lpad(buf, fmt_str(buf, pres->groups[g].sub_labels[c]), 18, ' '));
|
|
print(" ", 1);
|
|
print_statistics(&ref_states[k], pres->ref_limits);
|
|
++k;
|
|
}
|
|
}
|
|
}
|
|
print_str("===== introspective statistics =====\n");
|
|
print_str("Limits: mean: [");
|
|
print_s32_dec(pres->int_limits->mean_low);
|
|
print_str(", ");
|
|
print_s32_dec(pres->int_limits->mean_high);
|
|
print_str("], variance: [");
|
|
print_u32_dec(pres->int_limits->variance_low);
|
|
print_str(", ");
|
|
print_u32_dec(pres->int_limits->variance_high);
|
|
print_str("]\n");
|
|
print_str("self-referencing error (TUT time elapsed - expected TUT interval), in timer under test ticks\n");
|
|
print_str("positive: timer target handling is slow, negative: TUT is dropping ticks or triggering callback early\n");
|
|
print_str("function count sum sum_sq min max mean variance\n");
|
|
for (unsigned k = 0, g = 0; g < pres->num_groups; ++g) {
|
|
print("\n", 1);
|
|
print(buf, fmt_lpad(buf, fmt_str(buf, pres->groups[g].label), 18, ' '));
|
|
print(" ", 1);
|
|
print_totals(&int_states[k], pres->groups[g].num_sub_labels, pres->int_limits);
|
|
for (unsigned c = 0; c < pres->groups[g].num_sub_labels; ++c) {
|
|
print(buf, fmt_lpad(buf, fmt_str(buf, pres->groups[g].sub_labels[c]), 18, ' '));
|
|
print(" ", 1);
|
|
print_statistics(&int_states[k], pres->int_limits);
|
|
++k;
|
|
}
|
|
}
|
|
|
|
print_str("-------------- END STATISTICS ---------------\n");
|
|
}
|