Commit 374c392c authored by Tristan Gingold's avatar Tristan Gingold

Add stresstests directory.

parent 39ccbd44
# If it exists includes Makefile.specific. In this Makefile, you should put
# specific Makefile code that you want to run before this. For example,
# build a particular environment.
-include Makefile.specific
# include parent_common.mk for buildsystem's defines
# It allows you to inherit an environment configuration from larger project
REPO_PARENT ?= ..
-include $(REPO_PARENT)/parent_common.mk
TRTL ?= ../../dependencies/mock-turtle/software
CFLAGS += -Wall -g -O0
CFLAGS += -I. -I../include -I$(TRTL)/include -I$(TRTL)/lib -I../lib
CFLAGS += $(EXTRACFLAGS)
LDLIBS += ../lib/libwrtd.a $(TRTL)/lib/libmockturtle.a
PROGS= wrtd-timetest wrtd-freqmeter
all: $(PROGS)
wrtd-timetest: wrtd-timetest.c $(LDLIBS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
wrtd-freqmeter: wrtd-freqmeter.c $(LDLIBS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
.PHONY: all clean
clean:
rm -f $(PROGS) *.o *~
This diff is collapsed.
/*
* Copyright (C) 2018 CERN (www.cern.ch)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @TODO software trigger test
*/
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <inttypes.h>
#include <libmockturtle.h>
#include <libwrtd.h>
#define AssertIntEquals(VAL, EXPR) do \
{ \
int val = (VAL); \
int expr = (EXPR); \
if (val != expr) { \
fprintf(stderr, \
"%s:%d: unexpected value (got %d, expect %d)\n", \
__FILE__, __LINE__, expr, val); \
exit (1); \
} \
} while (0)
#define AssertPtrNotNull(EXPR) do \
{ \
void *ptr = (EXPR); \
if (ptr == NULL) { \
fprintf(stderr, \
"%s:%d: unexpected null pointer\n", \
__FILE__, __LINE__); \
exit (1); \
} \
} while (0)
/* Clear counters. */
static void clear_counters(struct wrtd_node *wrtd)
{
AssertIntEquals(0, wrtd_out_global_counters_reset(wrtd));
AssertIntEquals(0, wrtd_in_global_counters_reset(wrtd));
AssertIntEquals(0, wrtd_out_counters_reset(wrtd, 0));
AssertIntEquals(0, wrtd_in_counters_reset(wrtd, 0));
AssertIntEquals(0, wrtd_out_counters_reset(wrtd, 1));
AssertIntEquals(0, wrtd_in_counters_reset(wrtd, 1));
}
/* Path:
* Lun0/Out2 ->
* Lun0/In1 -> tid1 -> Lun1/Out1 ->
* Lun0/In2
*/
static struct wrtd_node *wrtd_0, *wrtd_1;
static struct wrtd_trigger_handle h_1;
static void setup(int delay_us)
{
struct wrtd_trig_id tid_1 = {0, 0, 1};
struct wrtd_trig_id tid_2 = {0, 0, 2};
const uint64_t tdelay = delay_us * 1000 * 1000;
wrtd_0 = wrtd_open(1);
AssertPtrNotNull(wrtd_0);
wrtd_1 = wrtd_open(2);
AssertPtrNotNull(wrtd_1);
clear_counters(wrtd_0);
clear_counters(wrtd_1);
/* Assign trigger input */
AssertIntEquals(0, wrtd_in_trigger_assign(wrtd_0, 0, &tid_1));
AssertIntEquals(0, wrtd_in_trigger_assign(wrtd_0, 1, &tid_2));
AssertIntEquals(0, wrtd_in_trigger_mode_set(wrtd_0, 0, WRTD_TRIGGER_MODE_AUTO));
AssertIntEquals(0, wrtd_in_trigger_mode_set(wrtd_0, 1, WRTD_TRIGGER_MODE_AUTO));
/* Assign trigger output */
AssertIntEquals(0, wrtd_out_trig_assign(wrtd_1, 0, &h_1, &tid_1, NULL));
AssertIntEquals(0, wrtd_out_trig_delay_set(wrtd_1, &h_1, tdelay));
AssertIntEquals(0, wrtd_out_trigger_mode_set(wrtd_1, 0, WRTD_TRIGGER_MODE_AUTO));
AssertIntEquals(0, wrtd_in_dead_time_set(wrtd_0, 0, 80000000));
AssertIntEquals(0, wrtd_in_dead_time_set(wrtd_0, 1, 80000000));
/* Enable and Arm */
AssertIntEquals(0, wrtd_out_arm(wrtd_1, 0, 1));
AssertIntEquals(0, wrtd_out_enable(wrtd_1, 0, 1));
AssertIntEquals(0, wrtd_out_trig_enable(wrtd_1, &h_1, 1));
AssertIntEquals(0, wrtd_in_arm(wrtd_0, 0, 1));
AssertIntEquals(0, wrtd_in_arm(wrtd_0, 1, 1));
AssertIntEquals(0, wrtd_in_enable(wrtd_0, 0, 1));
AssertIntEquals(0, wrtd_in_enable(wrtd_0, 1, 1));
}
static void test_timing(int count)
{
struct wrtd_input_state sti_l0c0, sti_l0c1;
int i;
for (i = 1; i <= count; i++) {
/* Generate a pulse. */
AssertIntEquals(0, wrtd_out_trigger_sw_now(wrtd_0, 1));
usleep(500);
/* Get stats. */
AssertIntEquals(0, wrtd_in_state_get(wrtd_0, 0, &sti_l0c0));
AssertIntEquals(0, wrtd_in_state_get(wrtd_0, 1, &sti_l0c1));
/* Check them. */
AssertIntEquals(i, sti_l0c0.sent_triggers);
AssertIntEquals(i, sti_l0c1.sent_triggers);
/* Check time. */
/* TODO. */
}
}
static void print_ts(struct wr_timestamp ts)
{
uint64_t ns = ts.ticks * 8ULL;
printf ("%llu:%03llu,%03llu,%03lluns",
(long long)(ts.seconds),
(ns / (1000LL * 1000)),
(ns / 1000LL) % 1000,
ns % 1000ULL);
}
static void disp_timing(int count, int delay_us)
{
struct wrtd_input_state sti_l0c0, sti_l0c1;
struct wr_timestamp d;
int i;
uint64_t pico;
int ecount;
for (i = 1, ecount = 0; i <= count; i++) {
/* Generate a pulse. */
AssertIntEquals(0, wrtd_out_trigger_sw_now(wrtd_0, 1));
usleep(5000);
/* Get stats. */
AssertIntEquals(0, wrtd_in_state_get(wrtd_0, 0, &sti_l0c0));
AssertIntEquals(0, wrtd_in_state_get(wrtd_0, 1, &sti_l0c1));
/* Check them. */
AssertIntEquals(i, sti_l0c0.sent_triggers);
if (sti_l0c1.sent_triggers == ecount + 1) {
/* Check time. */
AssertIntEquals(0, 0);
wrtd_ts_sub(&d,
&sti_l0c1.last_pulse,
&sti_l0c0.last_pulse);
wrtd_ts_to_pico(&d, &pico);
printf("Delay: %"PRIu64"ps [", pico);
print_ts(sti_l0c1.last_pulse);
printf(" - ");
print_ts(sti_l0c0.last_pulse);
printf("]\n");
ecount++;
if (pico < delay_us * 1000 * 1000) {
printf ("Below timing!\n");
break;
}
}
else {
printf("Missing!\n");
}
}
printf ("%d/%d missing pulses\n", count - ecount, count);
}
static void teardown(void)
{
/* Stop. */
AssertIntEquals(0, wrtd_in_enable(wrtd_0, 0, 0));
AssertIntEquals(0, wrtd_in_enable(wrtd_0, 1, 0));
AssertIntEquals(0, wrtd_out_enable(wrtd_0, 0, 0));
AssertIntEquals(0, wrtd_out_enable(wrtd_1, 0, 0));
#if 0
/* Last sent trigger is the last executed */
AssertIntEquals(sti_l1c0.last_sent.seq,
sto_l0c1.last_executed.seq);
AssertIntEquals(sti_l0c0.last_sent.seq,
sto_l1c0.last_executed.seq);
AssertIntEquals(sti_l0c1.last_sent.seq,
sto_l0c0.last_executed.seq);
AssertIntEquals(0, memcmp(&sti_l1c0.last_sent.id,
&sto_l0c1.last_executed.id,
sizeof(struct wrtd_trig_id)));
AssertIntEquals(0, memcmp(&sti_l0c0.last_sent.id,
&sto_l1c0.last_executed.id,
sizeof(struct wrtd_trig_id)));
AssertIntEquals(0, memcmp(&sti_l0c1.last_sent.id,
&sto_l0c0.last_executed.id,
sizeof(struct wrtd_trig_id)));
#endif
AssertIntEquals(0, wrtd_out_trig_unassign(wrtd_1, &h_1));
/* Close */
wrtd_close(wrtd_0);
wrtd_close(wrtd_1);
}
static void help(void)
{
printf("usage: wrtd-timetest [-c COUNT] [-d DELAY_US]\n");
}
int main(int argc, char **argv)
{
int c;
int count;
int delay_us;
char *endptr;
count = 100;
delay_us = 200;
while ((c = getopt (argc, argv, "hc:d:")) != -1) {
switch (c) {
case 'h':
case '?':
help();
break;
case 'c':
count = strtol(optarg, &endptr, 0);
if (*endptr != 0)
count = -1;
break;
case 'd':
delay_us = strtol(optarg, &endptr, 0);
if (*endptr != 0)
delay_us = -1;
break;
}
}
if (count < 1) {
fprintf(stderr, "bad count value (must be > 0)\n");
exit(1);
}
if (delay_us < 1) {
fprintf(stderr, "bad delay value (must be > 0)\n");
exit(1);
}
setup(delay_us);
if (1)
disp_timing(count, delay_us);
else
test_timing(count);
teardown();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment