Commit 3dcfa10c authored by Dimitris Lampridis's avatar Dimitris Lampridis Committed by Dimitris Lampridis

tools: migrate tools to python

parent 9ffb64dd
......@@ -10,7 +10,7 @@ REPO_PARENT ?= $(CURDIR)/..
# on Mock Turtle.
WRTD_DEP_TRTL ?= $(CURDIR)/../dependencies/mock-turtle
DIRS = $(WRTD_DEP_TRTL)/software lib tools firmware
DIRS = $(WRTD_DEP_TRTL)/software lib firmware
all clean: $(DIRS)
......
......@@ -21,6 +21,16 @@ class wrtd_tstamp(Structure):
("ns", c_uint32),
("frac", c_uint32)]
def __init__(self, seconds = 0, ns = 0, frac = 0):
self.seconds = seconds
self.ns = ns
self.frac = frac
def __iter__(self):
yield 'seconds', self.seconds
yield 'ns' , self.ns
yield 'frac' , self.seconds
def encode_arguments(func):
"""Used to convert arguments from strings to bytes"""
def wrapper(self, *args, **kwargs):
......@@ -299,17 +309,18 @@ class PyWrtd():
return value.value.decode('ascii')
@encode_arguments
def set_attr_tstamp(self, rep_cap_id, id, seconds = 0, ns = 0, frac = 0):
def set_attr_tstamp(self, rep_cap_id, id,
seconds = 0, ns = 0, frac = 0):
tstamp = wrtd_tstamp(seconds, ns, frac)
self.wrtd_lib.wrtd_set_attr_tstamp(self.wrtd_p, rep_cap_id,
id, byref(tstamp))
@encode_arguments
def get_attr_tstamp(self, rep_cap_id, id):
value = wrtd_tstamp(0, 0, 0)
tstamp = wrtd_tstamp()
self.wrtd_lib.wrtd_get_attr_tstamp(self.wrtd_p, rep_cap_id,
id, byref(value))
return value.seconds, value.ns, value.frac
id, byref(tstamp))
return dict(tstamp)
def clear_event_log_entries(self):
self.wrtd_lib.clear_event_log_entries(self.wrtd_p)
......
# 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
DESTDIR ?= /usr/local
WRTD_DEP_TRTL ?= ../../dependencies/mock-turtle/
CFLAGS += -Wall -Werror -ggdb
CFLAGS += -I. -I../include -I$(WRTD_DEP_TRTL)/software/include -I$(WRTD_DEP_TRTL)/software/lib -I../lib
CFLAGS += $(EXTRACFLAGS)
CFLAGS += $(EXTRACFLAGS)
LDLIBS += ../lib/libwrtd.a $(WRTD_DEP_TRTL)/software/lib/libmockturtle.a
PROGS := wrtd-config wrtd-logging
all: $(PROGS)
install:
install -d $(DESTDIR)/bin
install -D $(PROGS) $(DESTDIR)/bin
wrtd-inout-common.o: wrtd-inout-common.c
$(CC) -c $(CFLAGS) $^ -o $@
$(PROGS): wrtd-inout-common.o ../lib/libwrtd.a
# make nothing for modules_install, but avoid errors
modules_install:
clean:
rm -f $(PROGS) *.o *~
.PHONY: all clean
This diff is collapsed.
This diff is collapsed.
/**
* @file wrtd-inout-common.c
*
* Copyright (c) 2018-2019 CERN (home.cern)
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <mockturtle/libmockturtle.h>
#include <libwrtd.h>
#include <wrtd-common.h>
#include <wrtd-internal.h>
void print_ns(uint32_t ns)
{
printf("%03lu,%03lu,%03luns",
(ns / (1000L * 1000)),
(ns / 1000L) % 1000,
ns % 1000UL);
}
void print_ts(const struct wrtd_tstamp *ts)
{
struct tm *tm;
time_t t;
char out[64];
t = ts->seconds;
tm = gmtime(&t);
if (tm == NULL)
return;
strftime(out, 64, "%F,%T", tm);
printf("%s.%03lu.%03lu.%03lu+%03d", out,
(ts->ns / (1000L * 1000)),
(ts->ns / 1000L) % 1000,
ts->ns % 1000UL,
ts->frac >> (32 - 9));
}
void help_commands(struct wrtd_commands *cmds)
{
int i;
fprintf(stderr, "Available commands:\n");
for(i = 0; cmds[i].handler; i++) {
fprintf(stderr, " %s %s\n\t%s\n\n",
cmds[i].name, cmds[i].parm, cmds[i].desc);
}
}
#if 0
void help_log_level()
{
fprintf(stderr, "Log Levels\n");
fprintf(stderr, "You can set more than one log level. Here the list of valid log level strings:\n\n");
fprintf(stderr, "\toff, Raw, Sent, Promiscious, Executed, Missed.\n\n");
fprintf(stderr, "For details about their meaning refer, for example, to the library documentation.\n\n");
}
void help_trig_mode()
{
fprintf(stderr, "Trigger Modes\n");
fprintf(stderr, "You can active only one trigger mode at time. Following the list of valid trigger mode strings:\n\n");
fprintf(stderr, "\tauto, single\n\n");
fprintf(stderr, "For details about their meaning refer, for example, to the library documentation.\n\n");
}
void help_trig_id()
{
fprintf(stderr, "Trigger ID\n");
fprintf(stderr, "The trigger Id is made of 3 number separated by a colon\n\n");
fprintf(stderr, "\t<number>:<number>:<number>\n\n");
fprintf(stderr, "Looking at them from their semantic point of view:\n\n");
fprintf(stderr, "\t<system>:<port>:<trigger>\n\n");
fprintf(stderr, "For details about their meaning refer, for example, to the library documentation.\n\n");
}
void decode_flags(char *buf, uint32_t flags)
{
int l;
strcpy(buf,"");
if( flags & WRTD_ENABLED )
strcat(buf, "Enabled ");
if( flags & WRTD_TRIGGER_ASSIGNED )
strcat(buf, "TrigAssigned ");
if( flags & WRTD_LAST_VALID )
strcat(buf, "LastTimestampValid ");
if( flags & WRTD_ARMED )
strcat(buf, "Armed ");
if( flags & WRTD_TRIGGERED )
strcat(buf, "Triggered ");
if( flags & WRTD_NO_WR )
strcat(buf, "NoWRTiming ");
l = strlen(buf);
if(l)
buf[l-1] = 0;
}
void decode_mode(char *buf, int mode)
{
switch(mode)
{
case WRTD_TRIGGER_MODE_AUTO:
strcpy(buf, "Auto");
break;
case WRTD_TRIGGER_MODE_SINGLE:
strcpy(buf, "Single shot");
break;
default:
strcpy(buf,"?");
break;
}
}
void format_ts(char *buf, struct wr_timestamp ts, int with_seconds)
{
uint64_t picoseconds = (uint64_t) ts.ticks * 8000 + (uint64_t)ts.frac * 8000ULL / 4096ULL;
if(with_seconds)
{
sprintf (buf, "%llu:%03llu,%03llu,%03llu ns + %3llu ps",
(long long)(ts.seconds),
(picoseconds / (1000LL * 1000 * 1000)),
(picoseconds / (1000LL * 1000) % 1000),
(picoseconds / (1000LL) % 1000),
(picoseconds % 1000LL));
} else {
sprintf (buf, "%03llu,%03llu,%03llu ns + %3llu ps",
(picoseconds / (1000LL * 1000 * 1000)),
(picoseconds / (1000LL * 1000) % 1000),
(picoseconds / (1000LL) % 1000),
(picoseconds % 1000LL));
}
}
void format_ago(char *buf, struct wr_timestamp ts, struct wr_timestamp current)
{
uint64_t delta = current.seconds - ts.seconds;
char when[16];
if (delta < 0)
{
sprintf(when, "future");
delta = -delta;
} else {
sprintf(when, "past");
}
if(delta < 60)
sprintf(buf, "%lu seconds in the %s", delta, when);
else if (delta < 3600)
sprintf(buf, "%lu minutes in the %s", delta/60, when);
else if (delta < 3600*24)
sprintf(buf, "%lu hours in the %s", delta/3600, when);
else
sprintf(buf, "%lu days in the %s", delta/(24*3600), when);
}
void format_id(char *buf, struct wrtd_trig_id id)
{
sprintf( buf, "%04x:%04x:%08x", id.system, id.source_port,id.trigger);
}
uint64_t ts_to_picos(struct wr_timestamp ts)
{
return (uint64_t) ts.seconds * 1000LL * 1000 * 1000 * 1000
+ (uint64_t) ts.ticks * 8000ULL +
+ (uint64_t) ts.frac * 8000LL / 4096LL;
}
#endif
int parse_delay(char *dly, uint64_t *delay_ps)
{
char *endptr;
int l = strlen(dly);
char last;
uint64_t mult;
double d;
if(!l)
return -1;
last = dly[l-1];
mult=1;
switch(last) {
case 'm': mult = 1000ULL * 1000 * 1000; l--; break;
case 'u': mult = 1000ULL * 1000; l--; break;
case 'n': mult = 1000ULL; l--; break;
case 'p': mult = 1; l--; break;
default: mult = 1; break;
}
dly[l] = 0;
d = strtod(dly, &endptr);
if (*endptr != 0)
return -1;
*delay_ps = (uint64_t) (d * (double) mult);
return 0;
}
void ts_add_ps(struct wrtd_tstamp *ts, uint64_t ps)
{
uint32_t frac;
uint64_t ns;
uint32_t sec;
uint64_t v;
ns = ps / 1000;
frac = ps - (ns * 1000);
v = ts->frac + ((1ULL << 32) * frac / 1000);
if (v >= (1ULL << 32)) {
v -= (1ULL << 32);
ns++;
}
ts->frac = v;
v = ts->ns + ns;
if (v >= 1000000000) {
sec = v / 1000000000;
ts->ns = v - sec * 1000000000ULL;
ts->seconds += sec;
}
else
ts->ns = v;
}
void ts_sub_ps(struct wrtd_tstamp *ts, uint64_t ps)
{
uint32_t frac;
uint64_t ns;
uint32_t sec;
int64_t v;
ns = ps / 1000;
frac = ps - (ns * 1000);
v = ts->frac - ((1ULL << 32) * frac / 1000);
if (v < 0) {
v += (1ULL << 32);
ns++;
}
ts->frac = v;
v = ts->ns - ns;
if (v < 0) {
sec = v / 1000000000;
ts->ns = v + sec * 1000000000ULL;
ts->seconds -= sec;
}
else
ts->ns = v;
}
#if 0
int parse_mode (char *mode_str, enum wrtd_trigger_mode *mode)
{
if(!strcmp(mode_str, "auto"))
*mode = WRTD_TRIGGER_MODE_AUTO;
else if(!strcmp(mode_str, "single"))
*mode = WRTD_TRIGGER_MODE_SINGLE;
else
return -1;
return 0;
}
int parse_trigger_id(const char *str, struct wrtd_trig_id *id)
{
return (sscanf(str,"%x:%x:%x", &id->system, &id->source_port, &id->trigger) == 3 ? 0 : -1);
}
int parse_log_level (char *list[], int count, int *log_level)
{
uint32_t l = 0, tmp;
while(count--) {
if(!list[0])
return -1;
tmp = wrtd_strlogging_to_level(list[0]);
if (tmp == WRTD_LOG_ALL || tmp == WRTD_LOG_NOTHING) {
l = tmp;
break;
}
l |= tmp;
if(!strcmp(list[0], "all")) {
l = WRTD_LOG_ALL;
break;
}
list++;
}
*log_level = l;
return 0;
}
#endif
/**
* @file wrtd-internal.h
*
* Copyright (c) 2018-2019 CERN (home.cern)
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef __WRTD_TOOLS_INTERNAL_H__
#define __WRTD_TOOLS_INTERNAL_H__
#include <mockturtle/libmockturtle.h>
#include <libwrtd.h>
struct wrtd_commands {
const char *name;
const char *parm;
const char *desc;
enum wrtd_status (*handler)(struct wrtd_dev *wrtd,
int argc, char **argv);
};
/**
* @file wrtd-inout-common.c
*/
extern void help_commands(struct wrtd_commands *cmds);
extern void help_log_level();
extern void help_trig_mode();
extern void help_trig_id();
extern void decode_flags(char *buf, uint32_t flags);
extern void decode_mode(char *buf, int mode);
extern void decode_log_level(char *buf, uint32_t flags);
extern int parse_delay(char *dly, uint64_t *delay_ps);
extern int parse_log_level (char *list[], int count, int *log_level);
extern void ts_add_ps(struct wrtd_tstamp *ts, uint64_t ps);
extern void ts_sub_ps(struct wrtd_tstamp *ts, uint64_t ps);
extern void print_ts(const struct wrtd_tstamp *ts);
extern void print_ns(uint32_t ns);
#endif
/**
* @file wrtd-logging.c
*
* Copyright (c) 2018-2019 CERN (home.cern)
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <inttypes.h>
#include "libwrtd.h"
#include "libwrtd-private.h"
#include "wrtd-internal.h"
static void help(void)
{
fprintf(stderr, "wrtd-logging -D <device>\n");
fprintf(stderr, "It shows logging information coming from Real-Time applications\n");
fprintf(stderr, "-D device id\n");
fprintf(stderr, "-n number of messages to read (0 means infinite)\n");
exit(1);
}
static void print_logging (struct wrtd_dev *wrtd, int n_read)
{
char log_entry[WRTD_LOG_ENTRY_SIZE];
enum wrtd_status status;
unsigned int i;
for(i = 0; i < n_read || n_read == 0; i++) {
do {
status = wrtd_get_next_event_log_entry(
wrtd, WRTD_LOG_ENTRY_SIZE, log_entry);
if (status > WRTD_SUCCESS) {
fprintf(stderr, "Warning: log entry truncated, "
"missing %d characters\n",
status - WRTD_LOG_ENTRY_SIZE);
}
else if (status != WRTD_SUCCESS) {
char error_message[256];
enum wrtd_status error_status;
wrtd_get_error (wrtd, &error_status, 256, error_message);
fprintf(stderr, "Error: %s\n", error_message);
return;
}
} while (strlen(log_entry) == 0);
printf("%s\n", log_entry);
fflush(stdout);
}
}
int main(int argc, char *argv[])
{
struct wrtd_dev *wrtd;
const char *dev_name = NULL;
enum wrtd_status status;
char *endptr;
int n_read = 0;
char c;
while ((c = getopt (argc, argv, "hD:n:")) != -1) {
switch (c) {
default:
help();
break;
case 'D':
dev_name = optarg;
break;
case 'n':
n_read = strtoul(optarg, &endptr, 0);
if (*endptr != 0) {
fprintf(stderr, "bad value for -n");
exit (1);
}
break;
}
}
if (dev_name == NULL) {
help();
exit(1);
}
/* Open. */
status = wrtd_init(dev_name, 0, NULL, &wrtd);
if (status != WRTD_SUCCESS) {
char error_message[256];
enum wrtd_status error_status;
wrtd_get_error (wrtd, &error_status, 256, error_message);
fprintf(stderr, "Cannot open WRTD: %s\n", error_message);
return 1;
}
print_logging (wrtd, n_read);
wrtd_close(wrtd);
exit(0);
}
"""
@file wrtd-logging.py
@copyright: Copyright (c) 2019 CERN (home.cern)
SPDX-License-Identifier: LGPL-3.0-or-later
"""
import sys
import signal
import argparse
from PyWrtd import *
def signal_handler(sig, frame):
sys.exit(0)
def print_logging(wrtd, count):
n_read = 0
while ((count == 0) or (n_read < count)):
log_entry = wrtd.get_next_event_log_entry()
if len(log_entry):
print(log_entry)
n_read += 1
def main():
signal.signal(signal.SIGINT, signal_handler)
parser = argparse.ArgumentParser(description='WRTD node log monitoring tool')
parser.add_argument('-D', '--dev-id', dest='dev', required=True, type=int,
help='MockTurtle device ID (integer) to open')
parser.add_argument('-c', '--count', dest='count', type=int, default=0,
help='Number of entries to read (0 = infinite)')
args = parser.parse_args()
dev = 'MT' + str(args.dev)
wrtd = PyWrtd(dev)
print_logging(wrtd, args.count)
if __name__ == "__main__":
main()
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