From: muench Date: Tue, 31 Aug 1999 10:37:23 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=fae10759d7be835fca22cdfd8b803b2850e4218a;p=daqdata.git *** empty log message *** --- fae10759d7be835fca22cdfd8b803b2850e4218a diff --git a/hadaq/Makefile b/hadaq/Makefile new file mode 100644 index 0000000..14ed4c2 --- /dev/null +++ b/hadaq/Makefile @@ -0,0 +1,195 @@ +# UNIX +#CC = c89 +#RPCGEN = rpcgen +#LOADLIBES = -L$(HOME)/lib/$(SYSTYPE) -lhadesstd -L/usr/fore/lib -latm -lrt -ltk -lX11 -ltcl -lm +#INCLUDES = -I$(HOME)/include -I/usr/fore/include +#DEFINES = -UNDEBUG -DHADESSTD_NEXITSTAT -DHADESSTD_NGETOPT + +# UNIX w/o ATM +#CC = c89 +#RPCGEN = rpcgen +#LOADLIBES = -L$(HOME)/lib/$(SYSTYPE) -lhadesstd -lrt -ltk -lX11 -ltcl -lm +#INCLUDES = -I$(HOME)/include -I/usr/fore/include +#DEFINES = -UNDEBUG -DHADESSTD_NEXITSTAT -DHADESSTD_NGETOPT -DNOATM + +# Linux +#CC = gcc +#RPCGEN = rpcgen -k +#LOADLIBES = -L$(HOME)/lib/$(SYSTYPE) -lhadesstd -llvme +#INCLUDES = -I$(HOME)/include +#DEFINES = -UNDEBUG -DHADESSTD_NEXITSTAT -DHADESSTD_NGETOPT -DNOATM + +# LynxOS +CC = gcc +RPCGEN = rpcgen +LOADLIBES = -L/usr/local/lib -L$(HOME)/lib/$(SYSTYPE) -lhadesstd -llvme -ltcl -lm -lrpc -lnetinet -L/lib/ces -lvme -lbma -luio +INCLUDES = -I/usr/local/include -I$(HOME)/include +DEFINES = -UNDEBUG -DHADESSTD_NEXITSTAT -DNOATM + +CFLAGS = -g $(INCLUDES) $(DEFINES) + +HW_OBJS = hwrich.o hwrace.o rc.o +#HW_OBJS = hwsoft.o + + +DAQ_XMANAGE_OBJS = tcldaq.o tkAppInit.o \ + agent_clnt.o agent_xdr.o worker.o psxshm.o mman.o +DAQ_MANAGE_OBJS = tcldaq.o tclAppInit.o \ + agent_clnt.o agent_xdr.o worker.o psxshm.o mman.o +DAQ_AGENT_OBJS = agent.o agent_svc.o agent_xdr.o \ + worker.o psxshm.o mman.o +DAQ_READOUT_OBJS = readout.o \ + worker.o \ + $(HW_OBJS) param.o subevt.o \ + shmtrans.o semaphore.o hadtuqueue.o \ + psxshm.o mman.o \ + hadtu.o \ + latm.o +DAQ_MEMNET_OBJS = memnet.o \ + worker.o \ + shmtrans.o semaphore.o hadtuqueue.o \ + psxshm.o mman.o \ + nettrans.o pkt.o latm.o \ + hadtu.o +DAQ_NETMEM_OBJS = netmem.o \ + worker.o \ + shmtrans.o semaphore.o hadtuqueue.o \ + psxshm.o mman.o \ + nettrans.o pkt.o latm.o \ + hadtu.o +DAQ_EVTBUILD_OBJS = evtbuild.o \ + worker.o \ + shmtrans.o semaphore.o hadtuqueue.o \ + psxshm.o mman.o \ + online.o online_svc.o online_xdr.o \ + evt.o subevt.o \ + hadtu.o +DAQ_CTRLCTU_OBJS = ctrlctu.o \ + worker.o psxshm.o mman.o +DAQ_SNIFF_OBJS = sniff.o online_clnt.o online_xdr.o +DAQ_ANAL_OBJS = showevt.o hldread.o evt.o subevt.o hadtu.o + +mini: daq_readout daq_evtbuild +seb: daq_readout daq_memnet daq_agent +eb: daq_netmem daq_evtbuild +anal: daq_sniff daq_anal +manage: daq_manage +xmanage: daq_xmanage anal + +all : seb eb anal + +daq_xmanage: $(DAQ_XMANAGE_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_XMANAGE_OBJS) $(LOADLIBES) -o daq_xmanage + +daq_manage: $(DAQ_MANAGE_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_MANAGE_OBJS) $(LOADLIBES) -o daq_manage + +daq_agent: $(DAQ_AGENT_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_AGENT_OBJS) $(LOADLIBES) -o daq_agent + +daq_ctrlctu: $(DAQ_CTRLCTU_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_CTRLCTU_OBJS) $(LOADLIBES) -o daq_ctrlctu + +daq_readout: $(DAQ_READOUT_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_READOUT_OBJS) $(LOADLIBES) -o daq_readout + +daq_memnet: $(DAQ_MEMNET_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_MEMNET_OBJS) $(LOADLIBES) -o daq_memnet + +daq_netmem: $(DAQ_NETMEM_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_NETMEM_OBJS) $(LOADLIBES) -o daq_netmem + +daq_evtbuild: $(DAQ_EVTBUILD_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_EVTBUILD_OBJS) $(LOADLIBES) -o daq_evtbuild + +daq_sniff: $(DAQ_SNIFF_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_SNIFF_OBJS) $(LOADLIBES) -o daq_sniff + +daq_anal: $(DAQ_ANAL_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(DAQ_ANAL_OBJS) $(LOADLIBES) -o daq_anal + +clean: + rm -f *.o *.out core tags \ + agent.h agent_clnt.c agent_svc.c agent_xdr.c \ + online.h online_clnt.c online_svc.c online_xdr.c + +latm.o: latm.c latm.h + cc $(CFLAGS) -c latm.c + +online_clnt.c: online.x + $(RPCGEN) -l online.x >online_clnt.c + +online_svc.c: online.x + $(RPCGEN) -m online.x >online_svc.c + +online_xdr.c: online.x + $(RPCGEN) -c online.x >online_xdr.c + +online.h: online.x + $(RPCGEN) -h online.x >online.h + +agent_clnt.c: agent.x + $(RPCGEN) -l agent.x >agent_clnt.c + +agent_svc.c: agent.x + $(RPCGEN) -s tcp agent.x >agent_svc.c + +agent_xdr.c: agent.x + $(RPCGEN) -c agent.x >agent_xdr.c + +agent.h: agent.x + $(RPCGEN) -h agent.x >agent.h + +depend: + $(RPCGEN) online.x + $(RPCGEN) agent.x + gcc -MM $(CFLAGS) *.c + +agent.o: agent.c agent.h worker.h psxshm.h +agent_clnt.o: agent_clnt.c agent.h +agent_svc.o: agent_svc.c agent.h +agent_xdr.o: agent_xdr.c agent.h +ctrlctu.o: ctrlctu.c ctu.h worker.h psxshm.h +evt.o: evt.c evt.h hadtu.h subevt.h +evtbuild.o: evtbuild.c worker.h psxshm.h evt.h hadtu.h subevt.h \ + shmtrans.h hadtuqueue.h +hadtu.o: hadtu.c hadtu.h +hadtuqueue.o: hadtuqueue.c hadtu.h hadtuqueue.h +hldread.o: hldread.c evt.h hadtu.h subevt.h hldread.h +hwmdc.o: hwmdc.c param.h subevt.h hadtu.h hwsam.h hardware.h +hwrace.o: hwrace.c subevt.h hadtu.h param.h rc.h hwrace.h +hwrich.o: hwrich.c param.h subevt.h hadtu.h hwrace.h rc.h hardware.h +hwsam.o: hwsam.c sam_defs.h hwsam.h param.h +hwship.o: hwship.c param.h ipc_basis.h hwship.h +hwshow.o: hwshow.c param.h subevt.h hadtu.h hwship.h hardware.h +hwsoft.o: hwsoft.c subevt.h hadtu.h param.h hardware.h +latm.o: latm.c +memnet.o: memnet.c shmtrans.h psxshm.h hadtuqueue.h hadtu.h nettrans.h \ + worker.h +mman.o: mman.c +netmem.o: netmem.c worker.h psxshm.h nettrans.h hadtu.h shmtrans.h \ + hadtuqueue.h +nettrans.o: nettrans.c grmblfx.h latm.h hadtu.h pkt.h worker.h \ + psxshm.h nettrans.h +online.o: online.c evt.h hadtu.h subevt.h online.h +online_clnt.o: online_clnt.c online.h +online_svc.o: online_svc.c online.h +online_xdr.o: online_xdr.c online.h +param.o: param.c param.h +pkt.o: pkt.c pkt.h hadtu.h +psxshm.o: psxshm.c psxshm.h +rc.o: rc.c rc.h +readout.o: readout.c grmblfx.h hardware.h shmtrans.h psxshm.h \ + hadtuqueue.h hadtu.h worker.h +semaphore.o: semaphore.c semaphore.h +shmtrans.o: shmtrans.c grmblfx.h psxshm.h hadtuqueue.h hadtu.h \ + shmtrans.h +showevt.o: showevt.c hldread.h evt.h hadtu.h subevt.h +sniff.o: sniff.c online.h +subevt.o: subevt.c subevt.h hadtu.h +tclAppInit.o: tclAppInit.c \ + /usr/lib/gcc-lib/ppc-unknown-lynxos2.5/2.7-96q1/../../../../include/tcl.h +tcldaq.o: tcldaq.c worker.h psxshm.h agent.h +tkAppInit.o: tkAppInit.c \ + /usr/lib/gcc-lib/ppc-unknown-lynxos2.5/2.7-96q1/../../../../include/tk.h +worker.o: worker.c worker.h psxshm.h diff --git a/hadaq/agent.c b/hadaq/agent.c new file mode 100644 index 0000000..accc519 --- /dev/null +++ b/hadaq/agent.c @@ -0,0 +1,71 @@ +#include +#include "agent.h" +#include "worker.h" + +#define NWORKERS 16 +Worker *workers[NWORKERS]; /* inplicitly set to zero */ + +static int addWorker(Worker *worker) +{ + int i; + + for (i = 0; workers[i] != NULL; i++) { /* BUGBUG crash if workers full */ + } + workers[i] = worker; + + return i; +} + +static Worker *getWorker(int id) +{ + return workers[id]; +} + +static void removeWorker(int id) +{ + workers[id] = NULL; +} + +int *rpcworker_start_1(RpcWorker_startArgs * args, CLIENT * cl) +{ + static int retVal; + Worker *worker; + int i; + char **argv; + + /* The closing NULL in argv cannot be passed via rpc, we have to add it + here */ + + argv = malloc((args->argv.argv_len + 1) * sizeof(char *)); + + for (i = 0; i < args->argv.argv_len; i++) { + argv[i] = args->argv.argv_val[i]; + } + argv[i] = NULL; + + worker = Worker_start(args->name, argv); + + free(argv); + + retVal = addWorker(worker); + return &retVal; +} + +char **rpcworker_status_1(int *id, CLIENT * cl) +{ + static char *retVal; + + retVal = Worker_status(getWorker(*id)); + return &retVal; +} + +int *rpcworker_stop_1(int *id, CLIENT * cl) +{ + static int retVal; + + Worker_stop(getWorker(*id), 15); + + retVal = 0; + + return &retVal; +} diff --git a/hadaq/agent.x b/hadaq/agent.x new file mode 100644 index 0000000..2f498fe --- /dev/null +++ b/hadaq/agent.x @@ -0,0 +1,14 @@ +typedef string vstring<>; + +struct RpcWorker_startArgs { + string name<14>; + vstring argv<>; +}; + +program DAQAGENTPROG { + version DAQAGENTVERS { + int RpcWorker_start(RpcWorker_startArgs) = 1; + string RpcWorker_status(int) = 2; + int RpcWorker_stop(int) = 3; + } = 1; +} = 0x20000002; diff --git a/hadaq/cmds.tcl b/hadaq/cmds.tcl new file mode 100644 index 0000000..4e082dc --- /dev/null +++ b/hadaq/cmds.tcl @@ -0,0 +1,334 @@ +proc createAgent {agent} { + global agents + global agentList + + lappend agentList $agent + set agents($agent.name) $agent + set agents($agent.host) $agent + set agents($agent.status) down +} + +proc deleteAgent {agent} { + global agents + global agentList + + unset agents($agent.name) + unset agents($agent.host) + unset agents($agent.status) + set agentList [lreplace $agentList [lsearch $agentList $agent] [lsearch $agentList $agent]] +} + +proc catAgent {opts} { + global agents + global agentList + + set status "" + if {[lsearch $opts "-up"] != -1} { + set status up + } elseif {[lsearch $opts "-down"] != -1} { + set status down + } + set w "" + if {[info exists agentList]} { + foreach i $agentList { + if {$status == "" || $status == $agents($i.status)} { + lappend w $i + } + } + } + return $w +} + +proc chkAgent {agent} { + global agents + + if [catch {exec /usr/sbin/rpcinfo -t [agent list $agent host] 536870914}] { + set agents($agent.status) down + } else { + set agents($agent.status) up + } +} + +proc connectAgent {agent} { + global agents + + chkAgent $agent + if {"$agents($agent.status)" == "up"} { + set agents($agent.addr) [eval c_agent connect $agents($agent.host)] + } +} + +proc disconnectAgent {agent} { + global agents + + c_agent disconnect $agents($agent.addr) + unset agents($agent.addr) + set agents($agent.status) down +} + +proc listAgent {agent what } { + global agents + + if {$what == {}} { + set what {name host status} + } + foreach i $what { + catch {unset m} + if {[llength $what] != 1} { + lappend m "$i" + } + lappend m "$agents($agent.$i)" + lappend l "$m" + } + return $l +} + +proc agent {oper {agent {}} {args {}}} { + global agents + + if {"$oper" == "help"} { + puts {usage: agent [options]} + } elseif {"$oper" == "oper"} { + puts "create delete connect disconnect status oper help" + } elseif {"$oper" == "cat"} { + catAgent "$agent $args" + } elseif {"$oper" == "create"} { + createAgent $agent + } elseif {"$oper" == "connect"} { + if {"$agent" == "all"} { + while {[agent cat -down] != {}} { + connectAgent [lindex [agent cat -down] 0] + } + } else { + connectAgent $agent + } + } elseif {"$oper" == "disconnect"} { + if {"$agent" == "all"} { + while {[agent cat -up] != {}} { + disconnectAgent [lindex [agent cat -up] [expr [llength [agent cat -up]] - 1]] + } + } else { + disconnectAgent $agent + } + } elseif {"$oper" == "status"} { + return $agents($agent.status) + } elseif {"$oper" == "list"} { + listAgent $agent $args + } elseif {"$oper" == "delete"} { + deleteAgent $agent + } +} + +proc createWorker {worker opts} { + global workers + global workerList + + lappend workerList $worker + regexp {^([^:]*):([^:]*)$} $worker workers($worker.name) workers($worker.agent) workers($worker.file) + set workers($worker.file) daq_$workers($worker.file) + set workers($worker.opts) $opts + set workers($worker.addOpts) {} + set workers($worker.status) down +} + +proc addOptsWorker {worker opts} { + global workers + + set workers($worker.addOpts) $opts +} + +proc deleteWorker {worker} { + global workers + global workerList + + unset workers($worker.name) + unset workers($worker.agent) + unset workers($worker.file) + unset workers($worker.status) + unset workers($worker.opts) + unset workers($worker.addOpts) + set workerList [lreplace $workerList [lsearch $workerList $worker] [lsearch $workerList $worker]] +} + +proc catWorker {opts} { + global workers + global workerList + + set status "" + if {[lsearch $opts "-up"] != -1} { + set status up + } elseif {[lsearch $opts "-down"] != -1} { + set status down + } + set w "" + if {[info exists workerList]} { + foreach i $workerList { + if {$status == "" || $status == $workers($i.status)} { + lappend w $i + } + } + } + return $w +} + +proc listWorker {worker what } { + global workers + + if {$what == {}} { + set what {name agent file opts status} + } + foreach i $what { + catch {unset m} + if {[llength $what] != 1} { + lappend m "$i" + } + lappend m "$workers($worker.$i)" + lappend l "$m" + } + return $l +} + +proc startWorker {worker} { + global workers + + set opts "$workers($worker.opts) $workers($worker.addOpts)" + set workers($worker.addr) [eval c_worker start [agent list $workers($worker.agent) addr] $workers($worker.file) $opts] + set workers($worker.status) up +} + +proc stopWorker {worker} { + global workers + + c_worker stop [agent list $workers($worker.agent) addr] $workers($worker.addr) + unset workers($worker.addr) + set workers($worker.status) down +} + +proc worker {oper {worker {}} {args {}}} { + global workers + + if {"$oper" == "help"} { + puts {usage: worker [options]} + } elseif {"$oper" == "oper"} { + puts "create delete start stop status oper help" + } elseif {"$oper" == "cat"} { + catWorker "$worker $args" + } elseif {"$oper" == "create"} { + createWorker $worker $args + } elseif {"$oper" == "addopts"} { + addOptsWorker $worker $args + } elseif {"$oper" == "start"} { + if {"$worker" == "all"} { + while {[worker cat -down] != {}} { + startWorker [lindex [worker cat -down] 0] + } + } else { + startWorker $worker + } + } elseif {"$oper" == "stop"} { + if {"$worker" == "all"} { + while {[worker cat -up] != {}} { + stopWorker [lindex [worker cat -up] [expr [llength [worker cat -up]] - 1]] + } + } else { + stopWorker $worker + } + } elseif {"$oper" == "status"} { + if {[lsearch $args "-counter"] != -1 && $workers($worker.status) == "up"} { + set l [c_worker status [agent list $workers($worker.agent) addr] $workers($worker.addr)] + } else { + set l $workers($worker.status) + } + return $l + } elseif {"$oper" == "list"} { + listWorker $worker $args + } elseif {"$oper" == "delete"} { + deleteWorker $worker + } +} + +proc createGroup {group} { + global groups + global groupList + + lappend groupList $group + set groups($group.name) $group +} + +proc deleteGroup {group} { + global groups + global groupList + + unset groups($group.name) + set groupList [lreplace $groupList [lsearch $groupList $group] [lsearch $groupList $group]] +} + +proc catGroup {opts} { + global groups + global groupList + + return $groupList +} + +proc addGroup {group worker} { + global groups + + lappend groups($group.members) $worker +} + +proc removeGroup {group worker} { + global groups + + set groups($group.members) [lreplace $groups($group.members) [lsearch $groups($group.members) $worker] [lsearch $groups($group.members) $worker]] +} + +proc reverse {l} { + set x [expr [llength $l] - 1] + while {$x >= 0} { + lappend m [lindex $l $x] + set x [expr $x - 1] + } + return $m +} + +proc group {oper {group {}} {args {}}} { + global groups + + if {"$oper" == "oper"} { + puts "create delete add remove oper help" + } elseif {"$oper" == "cat"} { + catGroup "$group $args" + } elseif {"$oper" == "create"} { + createGroup $group + } elseif {"$oper" == "add"} { + addGroup $group $args + } elseif {"$oper" == "remove"} { + removeGroup $group $args + } elseif {"$oper" == "start"} { + foreach i $groups($group.members) { + worker start $i $args + } + } elseif {"$oper" == "stop"} { + foreach i [reverse $groups($group.members)] { + worker stop $i + } + } elseif {"$oper" == "status"} { + catch {unset l} + foreach i $groups($group.members) { + lappend l [list $i [worker status $i $args]] + } + return $l + } elseif {"$oper" == "list"} { + foreach i {name members} { + catch {unset m} + lappend m "$i" + lappend m "$groups($group.$i)" + lappend l "$m" + } + return $l + } elseif {"$oper" == "delete"} { + deleteGroup $group + } else { + puts {usage: group [options]} + } +} diff --git a/hadaq/ctrlctu.c b/hadaq/ctrlctu.c new file mode 100644 index 0000000..25bc6f0 --- /dev/null +++ b/hadaq/ctrlctu.c @@ -0,0 +1,117 @@ + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include "ctu.h" +#include "worker.h" + +static jmp_buf terminateJmp; + +void sigHandler(int sig) +{ + longjmp(terminateJmp, sig); +} + +static void usage(const char *progName) +{ + msglog(LOG_ERR, "Usage: %s start|stop|#trig\n", progName); + msglog_usage(); +} + +int main(int argc, char *argv[]) +{ + Ctu *ctu; + Worker *worker; + int isStandalone; + int priority; + ptrdiff_t offset; + int i; + unsigned long value; + struct pdparam_master paramS, *param = ¶mS; + int oper; + unsigned long *ctuEnabled; + + msglog_setlevel(argv[0], "info"); + + isStandalone = 1; + priority = 0; + while ((i = getopt(argc, argv, "ap:v:")) != -1) { + switch (i) { + case 'a': + isStandalone = 0; + break; + case 'p': + priority = atoi(optarg); + break; + case 'v': + if (msglog_setlevel(argv[0], optarg) != 1) { + usage(argv[0]); + goto bailOut0; + } + break; + default: + usage(argv[0]); + goto bailOut0; + break; + } + } + + if (NULL == (worker = Worker_init(argv[0], sigHandler, priority, isStandalone))) { + msglog(LOG_ERR, "connecting to agent: %s\n", strerror(errno)); + goto bailOut0; + } + if (NULL == (ctuEnabled = Worker_addStatistic(worker, "ctuEnabled"))) { + msglog(LOG_ERR, "addingStatistic: %s\n", strerror(errno)); + goto bailOut0; + } + param->iack = 1; + param->rdpref = 0; + param->wrpost = 0; + param->swap = 1; + + ctu = allocMem(sizeof(Ctu)); + if (-1 == conCtu(ctu, 0x44000000)) { + msglog(LOG_ERR, "Initializing Ctu: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + Ctu_softBusy(ctu, 1); + (*ctuEnabled) = 0; + Ctu_clear(ctu); + Ctu_wrDeadtime(ctu, 0x08); + Ctu_wrDelay(ctu, 0x08); + Ctu_inhibit(ctu, 1); + Ctu_maskTrig(ctu, 1); + Ctu_softBusy(ctu, 0); + (*ctuEnabled) = 1; + Ctu_softTrig(ctu, 0x10); + Ctu_maskTrig(ctu, 0); + msglog(LOG_DEBUG, "%s\n", Ctu_2charP(ctu)); + if (0 == setjmp(terminateJmp)) { + sleep(32767); + } + Ctu_maskTrig(ctu, 1); + Ctu_softTrig(ctu, 0x20); + msglog(LOG_DEBUG, "%s\n", Ctu_2charP(ctu)); + Ctu_softBusy(ctu, 1); + Ctu_maskTrig(ctu, 0); + Ctu_inhibit(ctu, 0); + (*ctuEnabled) = 0; + + desCtu(ctu); + Worker_fini(worker); + freeMem(ctu); + + exit(0); + + bailOut0: + exit(1); +} diff --git a/hadaq/ctu.h b/hadaq/ctu.h new file mode 100644 index 0000000..400eef2 --- /dev/null +++ b/hadaq/ctu.h @@ -0,0 +1,232 @@ +#ifndef CTU_H +#define CTU_H + +#include +#include +#include +#include +#include +#include + +#include + +#define STATUS1 0x00 +#define DEAD1 0x04 +#define CODE1 0x08 +#define TAG1 0x0c +#define STATUS2 0x10 +#define DEAD2 0x14 +#define CODE2 0x18 +#define TAG2 0x1c +#define TRIG1 0x20 +#define FIPO2 0x24 +#define MEM_DATA1 0x30 +#define MEM_DATA2 0x34 +#define MEM_RESET 0x38 +#define MAGIC 0x3c + +typedef struct CtuS { + volatile UInt1 *base; + UInt2 internalTrigNr; +} Ctu; + +static UInt1 Ctu_rdStatus(Ctu * my) +{ + return *(my->base + STATUS1); +} + +static UInt1 Ctu_rdDeadtime(Ctu * my) +{ + return *(my->base + DEAD1); +} + +static void Ctu_wrDelay(Ctu * my, UInt1 delay) +{ + *(my->base + FIPO2) = delay; +} + +static UInt1 Ctu_magicIsOk(Ctu * my) +{ + return *(my->base + MAGIC) == 0x51; +} + +static void Ctu_clear(Ctu *my) +{ + *(my->base + STATUS1) |= 0x01; + *(my->base + STATUS1) &= ~0x01; + *(my->base + STATUS2) |= 0x01; + *(my->base + STATUS2) &= ~0x01; +} + +static void Ctu_inhibit(Ctu *my, int v) +{ + if (v) { + *(my->base + STATUS1) |= 0x02; + *(my->base + STATUS2) |= 0x02; + } else { + *(my->base + STATUS1) &= ~0x02; + *(my->base + STATUS2) &= ~0x02; + } +} + +static void Ctu_maskBusy(Ctu *my, int v) +{ + if (v) { + *(my->base + STATUS1) |= 0x40; + } else { + *(my->base + STATUS1) &= ~0x40; + } +} + +static void Ctu_maskTrig(Ctu *my, int v) +{ + if (v) { + *(my->base + STATUS1) |= 0x08; + } else { + *(my->base + STATUS1) &= ~0x08; + } +} + +static void Ctu_lockBusy(Ctu *my, int v) +{ + if (v) { + *(my->base + STATUS1) |= 0x01; + } else { + *(my->base + STATUS1) &= ~0x01; + } +} + +static void Ctu_softBusy(Ctu *my, int v) +{ + if (v) { + *(my->base + STATUS1) |= 0x20; + } else { + *(my->base + STATUS1) &= ~0x20; + } +} + +static int Ctu_isBusy(Ctu *my) +{ + return (*(my->base + STATUS1) & 0x40) != 0; +} + +static int Ctu_isError(Ctu *my) +{ + return (*(my->base + STATUS1) & 0x80) != 0; +} + +static void Ctu_wrDeadtime(Ctu * my, UInt1 time) +{ + *(my->base + DEAD1) = time; +} + +static UInt1 Ctu_rdTrigCode(Ctu * my) +{ + return *(my->base + CODE1) & 0x0f; +} + +static UInt1 Ctu_rdTrigTag(Ctu * my) +{ + return *(my->base + TAG1); +} + +static int Ctu_fifoIsEmpty(Ctu * my) +{ + return (*(my->base + FIPO2) & 0x01) != 0; +} + +static void Ctu_popFifo(Ctu * my) +{ + *(my->base + FIPO2) = 0; +} + +static void Ctu_softTrig(Ctu *my, UInt1 trigType) { + struct timespec tS, *t = &tS; + t->tv_sec = 0; + t->tv_nsec = 1; + + *(my->base + TRIG1) = 0x80; + nanosleep(t, NULL); + *(my->base + TRIG1) = 0x80 | trigType; + nanosleep(t, NULL); + *(my->base + TRIG1) = 0x00; + nanosleep(t, NULL); +} + +static char *Ctu_2charP(Ctu * my) +{ + static char s[7 * 80]; + + sprintf(s, + "base: 0x%08x\n" + "status: 0x%02x\n" + "deadtime: 0x%02x\n" + "trigCode: 0x%01x\n" + "trigTag: 0x%02x\n" + "magicIsOk: %d\n", + my->base, + Ctu_rdStatus(my), + Ctu_rdDeadtime(my), + Ctu_rdTrigCode(my), + Ctu_rdTrigTag(my), + Ctu_magicIsOk(my) + ); + return s; +} + +static int Ctu_invariant(Ctu * my) +{ + return 1; +} + +static int conCtu(Ctu * my, unsigned long cardBase) +{ + struct pdparam_master paramS, *param = ¶mS; +unsigned char init_code1[] = {0, 1, 4, 4, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3}; + int i; + + assert(my != NULL); + + param->iack = 1; + param->rdpref = 0; + param->wrpost = 0; + param->swap = 2; + + + if ( + (volatile UInt1 *)-1 == (my->base = (volatile UInt1 *)find_controller( + cardBase, 0x10000UL, 0x09UL, 0x0000003cUL, 1UL, param + )) + ) { + return -1; + } + + *(my->base + STATUS1) = 0; + *(my->base + STATUS2) = 0; + for(i=0; i<64; ++i) + { + *(my->base + TAG1) = i; + *(my->base + CODE1) = init_code1[i]; + } + *(my->base + TAG1) = 0; + assert(Ctu_invariant(my)); + + return 0; +} + +static void desCtu(Ctu * my) +{ + assert(Ctu_invariant(my)); + + Ctu_inhibit(my, 0); + return_controller((unsigned long)my->base, 0x10000UL); +} + +#endif diff --git a/hadaq/evt.c b/hadaq/evt.c new file mode 100644 index 0000000..b46ed60 --- /dev/null +++ b/hadaq/evt.c @@ -0,0 +1,225 @@ +static char rcsId[] = "$Id: evt.c,v 6.1 1999-08-31 10:37:23 muench Exp $"; + +#define _ANSI_C_SOURCE +#include + +#include +#include +#include +#include +#include + +#include "evt.h" +#include "subevt.h" + +enum EvtIdx { + EvtIdx_size, + EvtIdx_decoding, + EvtIdx_id, + EvtIdx_seqNr, + EvtIdx_date, + EvtIdx_time, + EvtIdx_runNr, + EvtIdx_pad, + EvtIdx_data +}; + +size_t Evt_hdrLen(void) +{ + return EvtIdx_data; +} + +size_t Evt_hdrSize(void) +{ + return Evt_hdrLen() * sizeof(UInt4); +} + +size_t Evt_dataSize(const void *my) +{ + return Evt_size(my) - Evt_hdrSize(); +} + +void *Evt_data(const void *my) +{ + return (void *) ((char *) my + Evt_hdrSize()); +} + +UInt4 Evt_id(const void *my) +{ + return Evt_hdrValue(my, EvtIdx_id); +} + +void Evt_setId(void *my, UInt4 id) +{ + Evt_setHdrValue(my, EvtIdx_id, id); +} + +UInt4 Evt_seqNr(const void *my) +{ + return Evt_hdrValue(my, EvtIdx_seqNr); +} + +void Evt_setSeqNr(void *my, UInt4 seqNr) +{ + Evt_setHdrValue(my, EvtIdx_seqNr, seqNr); +} + +UInt4 Evt_date(const void *my) +{ + return Evt_hdrValue(my, EvtIdx_date); +} + +void Evt_setDate(void *my, UInt4 date) +{ + Evt_setHdrValue(my, EvtIdx_date, date); +} + +UInt4 Evt_time(const void *my) +{ + return Evt_hdrValue(my, EvtIdx_time); +} + +void Evt_setTime(void *my, UInt4 time) +{ + Evt_setHdrValue(my, EvtIdx_time, time); +} + +UInt4 Evt_runNr(const void *my) +{ + return Evt_hdrValue(my, EvtIdx_runNr); +} + +void Evt_setRunNr(void *my, UInt4 runNr) +{ + Evt_setHdrValue(my, EvtIdx_runNr, runNr); +} + +char *Evt_date2charP(const void *my) +{ + time_t tempo; + struct tm *gmTime; + static char buffer[80]; + + tempo = time(NULL); + gmTime = gmtime(&tempo); + gmTime->tm_year = (Evt_date(my) >> 16) & 0xff; + gmTime->tm_mon = (Evt_date(my) >> 8) & 0xff; + gmTime->tm_mday = (Evt_date(my) >> 0) & 0xff; + strftime(buffer, 80, "%Y-%m-%d", gmTime); + + return buffer; +} + +char *Evt_time2charP(const void *my) +{ + time_t tempo; + struct tm *gmTime; + static char buffer[80]; + + tempo = time(NULL); + gmTime = gmtime(&tempo); + gmTime->tm_hour = (Evt_time(my) >> 16) & 0xff; + gmTime->tm_min = (Evt_time(my) >> 8) & 0xff; + gmTime->tm_sec = (Evt_time(my) >> 0) & 0xff; + strftime(buffer, 80, "%H:%M:%S", gmTime); + + return buffer; +} + +char *Evt_2charP(const void *my) +{ + static char buf[2 * 132]; + + sprintf(buf, + "size: %08x\tdecoding: %08x\tid: %08x\tseqNr: %08x\n" + "date: %s\ttime: %s\trunNr: %d", + Evt_size(my), Evt_decoding(my), Evt_id(my), Evt_seqNr(my), + Evt_date2charP(my), Evt_time2charP(my), Evt_runNr(my) + ); + + return buf; +} + +void *newEvt(UInt4 decoding, UInt4 id, UInt4 runNr) +{ + void *my; + + my = allocMem(Evt_hdrSize()); + + Evt_setSize(my, Evt_hdrSize()); + Evt_setDecoding(my, decoding); + Evt_setId(my, id); + Evt_setRunNr(my, runNr); + + return my; +} + +void *getEvt(void *my) +{ + static UInt4 seqNr = 0; + time_t tempo; + struct tm *gmTime; + UInt4 dummy; + + Evt_setSeqNr(my, seqNr++); + + tempo = time(NULL); + gmTime = gmtime(&tempo); + + dummy = 0; + dummy |= gmTime->tm_year << 16; + dummy |= gmTime->tm_mon << 8; + dummy |= gmTime->tm_mday; + Evt_setDate(my, dummy); + + dummy = 0; + dummy |= gmTime->tm_hour << 16; + dummy |= gmTime->tm_min << 8; + dummy |= gmTime->tm_sec; + Evt_setTime(my, dummy); + + return my; +} + +void deleteEvt(void *my) +{ + freeMem(my); +} + +int Evt_write(void *my, FILE * file) +{ + return fwrite(my, 1, Evt_paddedSize(my), file); +} + +void *Evt_appendSubEvt(void *my, void *subEvt) +{ + /* BUGBUG in principal, aligned memory size must be allocated */ + my = reallocMem(my, Evt_paddedSize(my) + SubEvt_size(subEvt)); + memcpy(Evt_end(my), subEvt, SubEvt_size(subEvt)); + Evt_setSize(my, Evt_paddedSize(my) + SubEvt_size(subEvt)); + + return my; +} + +void *Evt_fget(FILE * file) +{ + static void *evt = NULL; + + if (evt != NULL) { + freeMem(evt); + } + evt = allocMem(Evt_hdrSize()); + + if (Evt_hdrSize() != fread(evt, 1, Evt_hdrSize(), file)) { + msglog(LOG_DEBUG, "%s:%d: %s\n", __FILE__, __LINE__, strerror(errno)); + return NULL; + } + evt = reallocMem(evt, Evt_paddedSize(evt)); + + /* BUGBUG quickhack for a "Evt_paddedDataSize" */ + if (Evt_paddedSize(evt) - Evt_hdrSize() != fread(Evt_data(evt), 1, Evt_paddedSize(evt) - Evt_hdrSize(), file)) { + msglog(LOG_ERR, "%s:%d: %s\n", __FILE__, __LINE__, strerror(errno)); + return NULL; + } + return evt; +} diff --git a/hadaq/evt.h b/hadaq/evt.h new file mode 100644 index 0000000..8202ce1 --- /dev/null +++ b/hadaq/evt.h @@ -0,0 +1,63 @@ +#ifndef EVT_H +#define EVT_H + +#include +#include +#include + +#include "hadtu.h" +#include "subevt.h" + +static const int evtBlockSize = 8 * 1024; + +enum EvtId { + EvtId_data, + EvtId_runStart +}; + +enum EvtDecoding { + EvtDecoding_default = 1, + EvtDecoding_64bitAligned = (0x03 << 16) | 0x0001 +}; + +#define Evt_hdr HadTu_hdr +#define Evt_isSwapped HadTu_isSwapped +#define Evt_hdrValue HadTu_hdrValue +#define Evt_setHdrValue HadTu_setHdrValue +#define Evt_decoding HadTu_decoding +#define Evt_setDecoding HadTu_setDecoding +#define Evt_alignment HadTu_alignment +#define Evt_size HadTu_size +#define Evt_setSize HadTu_setSize +#define Evt_paddedSize HadTu_paddedSize +#define Evt_begin HadTu_begin +#define Evt_end HadTu_end +#define Evt_next HadTu_next + +size_t Evt_hdrLen(void); +size_t Evt_hdrSize(void); +size_t Evt_dataSize(const void *my); +void *Evt_data(const void *my); +char *Evt_date2charP(const void *my); +char *Evt_time2charP(const void *my); +char *Evt_2charP(const void *my); + +UInt4 Evt_id(const void *my); +void Evt_setId(void *my, UInt4 id); +UInt4 Evt_seqNr(const void *my); +void Evt_setSeqNr(void *my, UInt4 seqNr); +UInt4 Evt_date(const void *my); +void Evt_setDate(void *my, UInt4 date); +UInt4 Evt_time(const void *my); +void Evt_setTime(void *my, UInt4 time); +UInt4 Evt_runNr(const void *my); +void Evt_setRunNr(void *my, UInt4 runNr); + +void *newEvt(UInt4 decoding, UInt4 id, UInt4 runNr); +void *getEvt(void *my); +void deleteEvt(void *my); +int Evt_write(void *my, FILE * file); +void *Evt_fget(FILE * file); +void *Evt_appendSubEvt(void *my, void *subEvt); + +#endif diff --git a/hadaq/evtbuild.c b/hadaq/evtbuild.c new file mode 100644 index 0000000..fa52723 --- /dev/null +++ b/hadaq/evtbuild.c @@ -0,0 +1,375 @@ +static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/evtbuild.c,v 6.1 1999-08-31 10:37:23 muench Exp $"; + +#define _XOPEN_SOURCE +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "worker.h" +#include "evt.h" +#include "subevt.h" +#include "shmtrans.h" + +static jmp_buf terminateJmp; + +void sigHandler(int sig) +{ + longjmp(terminateJmp, sig); +} + +static void *appendFile(void *my, const char *path) +{ + void *subEvt; + char *dataBuf; + FILE *file; + size_t fileSize; + + if (NULL == (file = fopen(path, "r"))) { + msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + return my; + } + subEvt = newSubEvt(SubEvtDecoding_text, SubEvtId_slow, 0); + + if (NULL == (dataBuf = malloc(strlen(path + 2)))) { + msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + return my; + } + sprintf(dataBuf, "#%s\n", path); + subEvt = SubEvt_appendData(subEvt, dataBuf, strlen(dataBuf)); + free(dataBuf); + + fseek(file, 0, SEEK_END); + fileSize = ftell(file); + fseek(file, 0, SEEK_SET); + if (NULL == (dataBuf = malloc(fileSize))) { + msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + return my; + } + fread(dataBuf, 1, fileSize, file); + + subEvt = SubEvt_appendData(subEvt, dataBuf, fileSize); + my = Evt_appendSubEvt(my, subEvt); + + deleteSubEvt(subEvt); + free(dataBuf); + fclose(file); + + return my; +} + +/* BUGBUG Tape handling needs complete new implementation */ +static FILE *openTape(const char *outPath) +{ + FILE *outFile; + int fd[2]; + char path[_POSIX_PATH_MAX]; + + strcpy(path, "of="); + strcat(path, outPath); + + if (0 > pipe(fd)) { + msglog(LOG_DEBUG, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + return NULL; + } + switch (fork()) { + case -1: + msglog(LOG_DEBUG, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + return NULL; + break; + case 0: + if (-1 == close(0)) { + msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + exit(EXIT_FAILURE); + } + if (0 != dup(fd[0])) { + msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + exit(EXIT_FAILURE); + } + if (-1 == close(fd[0])) { + msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + exit(EXIT_FAILURE); + } + if (-1 == close(fd[1])) { + msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + exit(EXIT_FAILURE); + } + if (-1 == execlp("dd", "dd", "ibs=1024k", "obs=8192", path, NULL)) { + msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + exit(EXIT_FAILURE); + } + break; + default: + outFile = fdopen(fd[1], "wb"); + if (-1 == close(fd[0])) { + msglog(LOG_DEBUG, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + return NULL; + } + break; + } + return outFile; +} + +static void usage(const char *progName) +{ + msglog(LOG_ERR, "Usage: %s -s nrOfSubEvts [...] [-r runNr]\n", progName); + msglog(LOG_ERR, "Usage: [-m nrOfMsgs]\n"); + msglog(LOG_ERR, "Usage: [-f slowCtrlFile ...] [-o outPath] [-d null|tape|file]\n"); + msglog(LOG_ERR, "Usage: [-a (agent)] [-p priority]\n"); + msglog_usage(); +} + +/* BUGBUG bailOut not proper yet */ +int main(int argc, char *argv[]) +{ + int i; + ShmTrans **shmTrans; + HadTuQueue **hadTuQueue; + Worker *worker; + int isStandalone; + int nrOfMsgs; + void *evt; + char *outPath; + char *outDev; + int priority; + FILE *outFile; + void *subEvt; + UInt4 nrOfSubEvts = 0; + UInt4 runNr; + char **slowCtrlFiles; + int slowCtrlFileCnt; + size_t queueSize; + + int scanWasSuccessful; + int currNrOfSubEvts; + UInt4 currTrigNr; + + unsigned long *evtsDiscarded; + unsigned long *evtsComplete; + + msglog_setlevel(argv[0], "info"); + isStandalone = 1; + nrOfMsgs = 0; + slowCtrlFiles = NULL; + slowCtrlFileCnt = 0; + outPath = "-"; + outDev = "null"; + priority = 0; + runNr = time(NULL); + queueSize = 100 * 1024; + + while ((i = getopt(argc, argv, "am:f:r:s:o:d:p:v:")) != -1) { + switch (i) { + case 'a': + isStandalone = 0; + break; + case 'm': + nrOfMsgs = atoi(optarg); + break; + case 'f': + slowCtrlFiles = realloc(slowCtrlFiles, sizeof(char *) * (slowCtrlFileCnt + 1)); + + slowCtrlFiles[slowCtrlFileCnt++] = optarg; + break; + case 'r': + runNr = atoi(optarg); + break; + case 's': + nrOfSubEvts = atoi(optarg); + break; + case 'o': + outPath = optarg; + break; + case 'd': + outDev = optarg; + break; + case 'p': + priority = atoi(optarg); + break; + case 'v': + if (msglog_setlevel(argv[0], optarg) != 1) { + usage(argv[0]); + exit(EXIT_FAILURE); + } + break; + default: + usage(argv[0]); + exit(EXIT_FAILURE); + break; + } + } + + if (nrOfSubEvts == 0) { + msglog(LOG_ERR, "missing nrOfSubEvts\n"); + usage(argv[0]); + exit(EXIT_FAILURE); + } + if (nrOfMsgs == 0) { + msglog(LOG_NOTICE, "nrOfMsgs not set, assuming readout is local\n"); + } + if (NULL == (worker = Worker_initBegin(argv[0], sigHandler, priority, isStandalone))) { + msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + exit(EXIT_FAILURE); + } + if (strcmp(outDev, "null") == 0) { + outFile = NULL; + } else if (strcmp(outDev, "file") == 0) { + if (strcmp(outPath, "-") == 0) { + outFile = stdout; + } else { + if (NULL == (outFile = fopen(outPath, "wb"))) { + msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + exit(EXIT_FAILURE); + } + } + } else if (strcmp(outDev, "tape") == 0) { + if (NULL == (outFile = openTape(outPath))) { + msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + exit(EXIT_FAILURE); + } + } else { + msglog(LOG_ERR, "unknown outputDev \"%s\"\n", outDev); + usage(argv[0]); + exit(EXIT_FAILURE); + } + + if (-1 == initOnline()) { + msglog(LOG_ERR, "unable to initialize online service\n"); + exit(EXIT_FAILURE); + } + if (nrOfMsgs == 0) { + /* + no '-m' option was on command line, we assume that the readout task + (daq_readout) is running on the same node and communicates directly + via shared memory */ + shmTrans = allocMem(sizeof(ShmTrans *)); + hadTuQueue = allocMem(sizeof(HadTuQueue *)); + + shmTrans[0] = ShmTrans_create("subevtqueue", 2 * queueSize); + hadTuQueue[0] = NULL; + nrOfMsgs = 1; + } else { + shmTrans = allocMem(nrOfMsgs * sizeof(ShmTrans *)); + hadTuQueue = allocMem(nrOfMsgs * sizeof(HadTuQueue *)); + + for (i = 0; i < nrOfMsgs; i++) { + char buf[_POSIX_PATH_MAX]; + + sprintf(buf, "netqueue%d", i); + shmTrans[i] = ShmTrans_create(buf, 2 * queueSize); + hadTuQueue[i] = NULL; + } + } + + evtsDiscarded = Worker_addStatistic(worker, "evtsDiscarded"); + evtsComplete = Worker_addStatistic(worker, "evtsComplete"); + Worker_initEnd(worker); + + evt = newEvt(EvtDecoding_64bitAligned, EvtId_runStart, runNr); + for (i = 0; i < slowCtrlFileCnt; i++) { + evt = appendFile(evt, slowCtrlFiles[i]); + } + if (outFile != NULL) { + Evt_write(getEvt(evt), outFile); + } + deleteEvt(evt); + + currTrigNr = 0; + while (setjmp(terminateJmp) == 0) { + int tryNext; + + Worker_dump(worker, 1); + + i = 0; + tryNext = 0; + evt = newEvt(EvtDecoding_64bitAligned, EvtId_data, runNr); + currNrOfSubEvts = 0; + while (i < nrOfMsgs) { + if (hadTuQueue[i] == NULL) { + void *storage; + + storage = ShmTrans_recv(shmTrans[i]); + hadTuQueue[i] = allocMem(HadTuQueue_sizeOf()); + conHadTuQueue_voidP(hadTuQueue[i], storage); + } + if (NULL != (subEvt = HadTuQueue_front(hadTuQueue[i]))) { +#ifndef NDEBUG + msglog(LOG_DEBUG, "hadTuQueue[%d]: %p = subEvt: %s\n", i, subEvt, SubEvt_2charP(subEvt)); +#endif + if (i == 0 && currNrOfSubEvts == 0) { + currTrigNr = SubEvt_trigNr(subEvt); + } + if (SubEvt_id(subEvt) == SubEvtId_trigCode) { + /* BUGBUG, this is indeed no header word */ + Evt_setId(evt, SubEvt_hdrValue(subEvt, 4)); + } + if (SubEvt_trigNr(subEvt) == currTrigNr) { + evt = Evt_appendSubEvt(evt, subEvt); + HadTuQueue_pop(hadTuQueue[i]); + currNrOfSubEvts++; + } else if (SubEvt_trigNr(subEvt) < currTrigNr) { + HadTuQueue_pop(hadTuQueue[i]); + /* BUGBUG subevt discarded, not in statistic */ + } else { + tryNext = 1; + } + } + if (HadTuQueue_empty(hadTuQueue[i])) { + desHadTuQueue(hadTuQueue[i]); + freeMem(hadTuQueue[i]); + hadTuQueue[i] = NULL; + ShmTrans_free(shmTrans[i]); + } + if (tryNext) { + i++; + tryNext = 0; + } + } + if (currNrOfSubEvts == nrOfSubEvts) { + evt = getEvt(evt); /* BUGBUG differnce newEvt <> getEvt not + necessary any more */ + if (outFile != NULL) { + Evt_write(evt, outFile); + } + Evt_online(evt); + (*evtsComplete)++; + } else { + (*evtsDiscarded)++; + } + deleteEvt(evt); + } + Worker_dump(worker, 0); + + evt = newEvt(EvtDecoding_64bitAligned, EvtId_runStart, runNr); + for (i = 0; i < slowCtrlFileCnt; i++) { + evt = appendFile(evt, slowCtrlFiles[i]); + } + if (outFile != NULL) { + Evt_write(getEvt(evt), outFile); + } + deleteEvt(evt); + + free(slowCtrlFiles); + + if (outFile != NULL) { + if (-1 == fclose(outFile)) { + msglog(LOG_NOTICE, "%s, line %d:\n", __FILE__, __LINE__, strerror(errno)); + } + } + for (i = 0; i < nrOfMsgs; i++) { + ShmTrans_remove(shmTrans[i]); + } + Worker_fini(worker); + + exit(EXIT_SUCCESS); +} diff --git a/hadaq/grmblfx.h b/hadaq/grmblfx.h new file mode 100644 index 0000000..ff0fb3d --- /dev/null +++ b/hadaq/grmblfx.h @@ -0,0 +1,3 @@ +#if defined(__osf__) && defined(_POSIX_C_SOURCE) +#define ushort unsigned short +#endif diff --git a/hadaq/hadaq.tcl b/hadaq/hadaq.tcl new file mode 100644 index 0000000..19d6470 --- /dev/null +++ b/hadaq/hadaq.tcl @@ -0,0 +1,527 @@ +#!/usr/local/bin/dpwish -f +source cmds.tcl +source ht98.tcl + +set runInfo(name) {} +set runInfo(user) {} +set runInfo(outputType) null +set runInfo(output) {} +set runInfo(comment) {} + +proc writeFile {name cont} { + set f [open $name w] + foreach line $cont { + puts $f $line + } + close $f +} + +proc updateViewFile {top name} { + .$top.txt configure -state normal + .$top.txt delete 1.0 end + set f [open $name r] + while {[gets $f line] >= 0} { + .$top.txt insert end "$line\n" + } + close $f + .$top.txt see end + .$top.txt configure -state disabled +} + +proc pollViewFile {top name} { + global mtime + + if {[winfo exists .$top]} { + if {[file mtime $name] > $mtime($name)} { + updateViewFile $top $name + } + set mtime($name) [file mtime $name] + after 1000 pollViewFile $top $name + } +} + +proc viewFile {top title name} { + global mtime + + toplevel .$top + wm title .$top "$title" + wm iconname .$top "$title" + + text .$top.txt -state disabled -yscrollcommand ".$top.scroll set" + scrollbar .$top.scroll -command ".$top.txt yview" + pack .$top.txt -side left -fill both -expand 1 + pack .$top.scroll -side right -fill y + + set mtime($name) 0 + pollViewFile $top $name +} + +proc writeRunInfo {} { + global runInfo + + lappend l [list set runInfo(name) $runInfo(name)] + lappend l [list set runInfo(user) $runInfo(user)] + lappend l [list set runInfo(output) $runInfo(output)] + lappend l [list set runInfo(comment) $runInfo(comment)] + writeFile runinfo.tcl $l +} + +proc distrFile {name} { + set f [open $name r] + while {[gets $f line] >= 0} { + lappend l "$line" + } + foreach agent [agent cat] { +# dp_RPC [agent list $agent addr] writeFile $name $l + } +} + +proc updateRunButtons {} { + if [isDown [group status run]] { + .mbar.file.menu entryconfigure 0 -state normal + .mbar.file.menu entryconfigure 1 -state disabled + } else { + .mbar.file.menu entryconfigure 0 -state disabled + .mbar.file.menu entryconfigure 1 -state normal + } +} + +proc outputTypeCmd {} { + global runInfo + + if {"$runInfo(outputType)" == "null"} { + .startRunDlg.top.output.ent configure -state normal + set runInfo(output) /dev/null + .startRunDlg.top.output.ent delete 0 end + .startRunDlg.top.output.ent insert 0 $runInfo(output) + .startRunDlg.top.output.ent configure -state disabled + } elseif {"$runInfo(outputType)" == "tape"} { + .startRunDlg.top.output.ent configure -state normal + set runInfo(output) /dev/nrmt0h + .startRunDlg.top.output.ent delete 0 end + .startRunDlg.top.output.ent insert 0 $runInfo(output) + .startRunDlg.top.output.ent configure -state disabled + } elseif {"$runInfo(outputType)" == "file"} { + .startRunDlg.top.output.ent configure -state normal + set runInfo(output) {} + .startRunDlg.top.output.ent delete 0 end + .startRunDlg.top.output.ent insert 0 $runInfo(output) + } +} + +proc startRunDlg {} { + global runInfo + global dlgButton + + toplevel .startRunDlg + wm title .startRunDlg "Start Run" + wm iconname .startRunDlg "Start Run" + frame .startRunDlg.top -relief raised -bd 1 + pack .startRunDlg.top -side top -fill both + frame .startRunDlg.bottom -relief raised -bd 1 + pack .startRunDlg.bottom -side bottom -fill both + + frame .startRunDlg.top.name + pack .startRunDlg.top.name -side top + label .startRunDlg.top.name.lbl -text "Run Name:" -width 20 -anchor ne + entry .startRunDlg.top.name.ent -width 20 + .startRunDlg.top.name.ent insert 0 $runInfo(name) + pack .startRunDlg.top.name.lbl .startRunDlg.top.name.ent -side left + + frame .startRunDlg.top.user + pack .startRunDlg.top.user -side top + label .startRunDlg.top.user.lbl -text "Started by:" -width 20 -anchor ne + entry .startRunDlg.top.user.ent -width 20 + .startRunDlg.top.user.ent insert 0 $runInfo(user) + pack .startRunDlg.top.user.lbl .startRunDlg.top.user.ent -side left + + frame .startRunDlg.top.output + pack .startRunDlg.top.output -side top + frame .startRunDlg.top.output.frm + label .startRunDlg.top.output.frm.lbl -text "Output to:" -width 20 -anchor ne + frame .startRunDlg.top.output.frm.b + entry .startRunDlg.top.output.ent -width 20 + outputTypeCmd + pack .startRunDlg.top.output.frm .startRunDlg.top.output.ent -side left + pack .startRunDlg.top.output.frm.lbl .startRunDlg.top.output.frm.b -side left + radiobutton .startRunDlg.top.output.frm.b.null -text Null -variable runInfo(outputType) -value null -command outputTypeCmd + radiobutton .startRunDlg.top.output.frm.b.tape -text Tape -variable runInfo(outputType) -value tape -command outputTypeCmd + radiobutton .startRunDlg.top.output.frm.b.file -text File -variable runInfo(outputType) -value file -command outputTypeCmd + pack .startRunDlg.top.output.frm.b.null .startRunDlg.top.output.frm.b.tape .startRunDlg.top.output.frm.b.file -side top + + frame .startRunDlg.top.comment + pack .startRunDlg.top.comment -side top + label .startRunDlg.top.comment.lbl -text "Comment:" -width 20 -anchor ne + text .startRunDlg.top.comment.ent -width 20 -height 5 + .startRunDlg.top.comment.ent insert 1.0 "$runInfo(comment)" + pack .startRunDlg.top.comment.lbl .startRunDlg.top.comment.ent -side left + + set dlgButton "cancel" + button .startRunDlg.bottom.ok -text "OK" -command {set dlgButton "ok"} + pack .startRunDlg.bottom.ok -side left + button .startRunDlg.bottom.cancel -text "Cancel" -command {set dlgButton "cancel"} + pack .startRunDlg.bottom.cancel -side right + + grab set .startRunDlg + tkwait variable dlgButton + if {"$dlgButton" == "ok"} { + set runInfo(name) [.startRunDlg.top.name.ent get] + set runInfo(user) [.startRunDlg.top.user.ent get] + set runInfo(output) [.startRunDlg.top.output.ent get] + set runInfo(comment) [.startRunDlg.top.comment.ent get 1.0 end] + } + destroy .startRunDlg + return $dlgButton +} + +proc stopRunDlg {} { + global runInfo + global dlgButton + + toplevel .stopRunDlg + wm title .stopRunDlg "Stop Run" + wm iconname .stopRunDlg "Stop Run" + frame .stopRunDlg.top -relief raised -bd 1 + pack .stopRunDlg.top -side top -fill both + frame .stopRunDlg.bottom -relief raised -bd 1 + pack .stopRunDlg.bottom -side bottom -fill both + + frame .stopRunDlg.top.user + pack .stopRunDlg.top.user -side top + label .stopRunDlg.top.user.lbl -text "Stopped by:" -width 20 -anchor ne + entry .stopRunDlg.top.user.ent -width 20 + .stopRunDlg.top.user.ent insert 0 $runInfo(user) + pack .stopRunDlg.top.user.lbl .stopRunDlg.top.user.ent -side left + + frame .stopRunDlg.top.comment + pack .stopRunDlg.top.comment -side top + label .stopRunDlg.top.comment.lbl -text "Comment:" -width 20 -anchor ne + text .stopRunDlg.top.comment.ent -width 20 -height 5 + .stopRunDlg.top.comment.ent insert 1.0 "$runInfo(comment)" + pack .stopRunDlg.top.comment.lbl .stopRunDlg.top.comment.ent -side left + + set dlgButton "cancel" + button .stopRunDlg.bottom.ok -text "OK" -command {set dlgButton "ok"} + pack .stopRunDlg.bottom.ok -side left + button .stopRunDlg.bottom.cancel -text "Cancel" -command {set dlgButton "cancel"} + pack .stopRunDlg.bottom.cancel -side right + + grab set .stopRunDlg + tkwait variable dlgButton + if {"$dlgButton" == "ok"} { + set runInfo(user) [.stopRunDlg.top.user.ent get] + set runInfo(comment) [.stopRunDlg.top.comment.ent get 1.0 end] + } + destroy .stopRunDlg + return $dlgButton +} + +proc startRunCmd {} { + global runInfo + global tapeInfo + + foreach worker [worker cat] { + if {[string first evtbuild $worker] != -1} { + set evtbuildWorker $worker + } + } + + if {[startRunDlg] == "ok"} { + writeRunInfo +# distrFile slowctrl.tcl + worker addopts $evtbuildWorker -o $runInfo(output) -d $runInfo(outputType) + if {$runInfo(outputType) == "tape"} { + set tapeInfo(hdr1) [format "%-11s ULTRIX00010001000100 98342 99366 000000DECULTRIX0000 " $runInfo(name)] + set tapeInfo(hdr2) "F0819208192 M 00 " + set f [open /tmp/ansitape.tmp w] + puts -nonewline $f "$tapeInfo(vol)HDR1$tapeInfo(hdr1)HDR2$tapeInfo(hdr2)" + close $f + set tapeInfo(vol) {} + exec sh -c "dd if=/tmp/ansitape.tmp bs=80 of=$runInfo(output) >/dev/null 2>&1" + } + group start run + } + updateRunButtons +} + +proc stopRunCmd {} { + global runInfo + global tapeInfo + + if {[stopRunDlg] == "ok"} { + group stop run + if {$runInfo(outputType) == "tape"} { + set f [open /tmp/ansitape.tmp w] + puts -nonewline $f "EOF1$tapeInfo(hdr1)EOF2tapeInfo(hdr2)" + close $f + set tapeInfo(vol) {} + exec sh -c "dd if=/tmp/ansitape.tmp bs=80 of=$runInfo(output) >/dev/null 2>&1" + } + } + updateRunButtons +} + +proc viewStat {top title statList} { + toplevel .$top + wm title .$top "$title" + wm iconname .$top "$title" + + foreach worker $statList { + set name [lindex $worker 0] + + frame .$top.$name + pack .$top.$name -side top + label .$top.$name.lbl -text $name + text .$top.$name.txt -width 35 -height 7 + pack .$top.$name.lbl .$top.$name.txt -side top + } +} + +proc updateStat {top countList} { + foreach worker $countList { + set name [lindex $worker 0] + set pairs [lindex $worker 1] + + .$top.$name.txt configure -state normal + .$top.$name.txt delete 1.0 end + foreach pair $pairs { + set p0 [lindex $pair 0] + set p1 [lindex $pair 1] + + if {$p1 != "down"} { + .$top.$name.txt insert end [format "%19s:%14d\n" $p0 $p1] + } + } + .$top.$name.txt configure -state disabled + } +} + +proc isDown {statList} { + foreach pair $statList { + set p0 [lindex $pair 0] + set p1 [lindex $pair 1] + + if {$p1 == "down"} { + return 1 + } + } + return 0 +} + +proc updateRunStat {} { + if {![isDown [group status run]]} { + updateStat viewRunStat [group status run -counter] + } +} + +proc pollRunStat {} { + if {[catch updateRunStat] == 0} { + after 5000 pollRunStat + } +} + +proc viewRunCmd {} { + viewStat viewRunStat "Run Status" [group status run] + pollRunStat +} + +proc updateAcquisitionButtons {} { + if [isDown [group status acquisition]] { + .mbar.options.menu entryconfigure 0 -state normal + .mbar.options.menu entryconfigure 1 -state disabled + } else { + .mbar.options.menu entryconfigure 0 -state disabled + .mbar.options.menu entryconfigure 1 -state normal + } +} + +proc startAcquisitionCmd {} { + group start acquisition + updateAcquisitionButtons +} + +proc stopAcquisitionCmd {} { + group stop acquisition + updateAcquisitionButtons +} + +proc updateAcquisitionStat {} { + if {![isDown [group status acquisition]]} { + updateStat viewAcquisitionStat [group status acquisition -counter] + } +} + +proc pollAcquisitionStat {} { + if {[catch updateAcquisitionStat] == 0} { + after 5000 pollAcquisitionStat + } +} + +proc viewAcquisitionCmd {} { + viewStat viewAcquisitionStat "Acquisition Status" [group status acquisition] + pollAcquisitionStat +} + +proc viewErrorlogCmd {} { + viewFile viewErrorLog "Error Log" hadaq.log +} + +proc viewEventCmd {} { + + foreach worker [worker cat] { + if {[string first evtbuild $worker] != -1} { + set evtbuildAgent [worker list $worker agent] + } + } + set f [open daq_anal.out w] + puts $f "Waiting for event" + close $f + after 1000 + viewFile viewEvt "View Event" daq_anal.out + exec sh -c "daq_sniff -h [agent list $evtbuildAgent host] | daq_anal -n 1" daq_anal.out 2>/dev/null & +} + +if {$tk_version < 4.0} { + set tearoff {} +} else { + set tearoff {-tearoff 0} +} + +proc loadTapeDlg {} { + global runInfo + global dlgButton + + toplevel .loadTapeDlg + wm title .loadTapeDlg "Load Tape" + wm iconname .loadTapeDlg "Load Tape" + frame .loadTapeDlg.top -relief raised -bd 1 + pack .loadTapeDlg.top -side top -fill both + frame .loadTapeDlg.bottom -relief raised -bd 1 + pack .loadTapeDlg.bottom -side bottom -fill both + + label .loadTapeDlg.top.lbl -text "Insert Tape" + + checkbutton .loadTapeDlg.top.overWr -text "Initialize Tape" -variable overwriteTape + pack .loadTapeDlg.top.lbl .loadTapeDlg.top.overWr -side top + + set dlgButton "cancel" + button .loadTapeDlg.bottom.ok -text "OK" -command {set dlgButton "ok"} + pack .loadTapeDlg.bottom.ok -side left + button .loadTapeDlg.bottom.cancel -text "Cancel" -command {set dlgButton "cancel"} + pack .loadTapeDlg.bottom.cancel -side right + grab set .loadTapeDlg + tkwait variable dlgButton + destroy .loadTapeDlg + return $dlgButton +} + +proc loadTapeCmd {} { + global overwriteTape + global tapeInfo + + set overwriteTape 0 + if {[loadTapeDlg] == "ok"} { + set c [lindex [. config -cursor] 4] + . config -cursor clock + update + while 1 { + if {[catch {exec mt online}] == 0} { + break + } + after 1000 + } + if {$overwriteTape} { + set tapeInfo(vol) "VOL1ULTRIX HADES 3" + exec mt rewind + } else { + exec mt seod + exec mt bsf 1 + } + . config -cursor $c + update + } +} + +proc ejectTapeCmd {} { + set c [lindex [. config -cursor] 4] + . config -cursor clock + update + exec mt offline + . config -cursor $c + update +} + +wm title . hadaq +frame .mbar -relief raised -bd 1 + +menubutton .mbar.file -text File -menu .mbar.file.menu +menubutton .mbar.view -text View -menu .mbar.view.menu +menubutton .mbar.options -text Options -menu .mbar.options.menu +menubutton .mbar.help -text Help -menu .mbar.help.menu +pack .mbar.file .mbar.view .mbar.options -side left +pack .mbar.help -side right + +eval menu .mbar.file.menu $tearoff +.mbar.file.menu add command -label "Start Run" -command startRunCmd +.mbar.file.menu add command -label "Stop Run" -command stopRunCmd +.mbar.file.menu add separator +.mbar.file.menu add command -label "Load Tape" -command loadTapeCmd +.mbar.file.menu add command -label "Eject Tape" -command ejectTapeCmd +.mbar.file.menu add separator +.mbar.file.menu add command -label Exit -command {exit} + +eval menu .mbar.view.menu $tearoff +.mbar.view.menu add command -label "Acquisition" -command viewAcquisitionCmd +.mbar.view.menu add command -label "Run" -command viewRunCmd +.mbar.view.menu add command -label "Tape" -command viewTapeCmd -state disabled +.mbar.view.menu add separator +.mbar.view.menu add command -label "Errorlog" -command viewErrorlogCmd +.mbar.view.menu add separator +.mbar.view.menu add command -label "Event" -command viewEventCmd + +eval menu .mbar.options.menu $tearoff +.mbar.options.menu add command -label "Start Acquisition" -command startAcquisitionCmd +.mbar.options.menu add command -label "Stop Acquisition" -command stopAcquisitionCmd + +eval menu .mbar.help.menu $tearoff +.mbar.help.menu add command -label "About" -command aboutCmd -state disabled + +frame .map +pack .mbar .map -side top -fill x + +proc updateMap {} { + set statusColor(up) darkGreen + set statusColor(down) red + + foreach agent [agent cat] { + .map.$agent configure -background $statusColor([agent status $agent]) + } + update +} + +proc pollMap {} { + foreach agent [agent cat] { + chkAgent $agent + } + updateMap + + after 5000 pollMap +} + +proc mkMap {} { + foreach agent [agent cat] { + label .map.$agent -text $agent + pack .map.$agent -side left -expand 1 -fill x + } +} + +mkMap + +foreach agent [agent cat] { + agent connect $agent +} + +pollMap + +updateRunButtons +updateAcquisitionButtons diff --git a/hadaq/hadaq_init.tcl b/hadaq/hadaq_init.tcl new file mode 100644 index 0000000..d89dd16 --- /dev/null +++ b/hadaq/hadaq_init.tcl @@ -0,0 +1,35 @@ +#!/usr/local/bin/tclsh -f +source cmds.tcl +source ht98.tcl + +foreach i [agent cat] { + set host [agent list $i host] + set user muench + set dir hadaq/hadaq-0.5 + + puts $host + if {[string match "gast8" $host] || [string match "gast7" $host]} { + set psCmd {ps -ax | awk '{ print $1, $NF }'} + } else { + set psCmd {export UNIX95=XPG4; ps -e -o pid -o comm} + } + + if {[lindex $argv 0] == "stop" || [lindex $argv 0] == "restart"} { + set f [open "|rsh $host -l $user \"$psCmd\"" r] + while {[gets $f line] >= 0} { + set cmd [lindex $line 1] + if {![string match {*_manage} $cmd] && [string match {daq_*} $cmd] || [string match {./daq_*} $cmd]} { + puts $line + set pid [lindex $line 0] + catch {eval exec "rsh $host -l $user sh -c {'kill $pid'}"} + } + } + close $f + } + + if {[lindex $argv 0] == "start" || [lindex $argv 0] == "restart"} { + catch {exec mv hadaq.log hadaq.log.old} + eval exec "rsh $host -l $user sh -c {'cd $dir; ./daq_agent'}" >&hadaq.log & + exec cat hadaq.log + } +} diff --git a/hadaq/hadtu.c b/hadaq/hadtu.c new file mode 100644 index 0000000..53112e3 --- /dev/null +++ b/hadaq/hadtu.c @@ -0,0 +1,21 @@ +static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/hadtu.c,v 6.1 1999-08-31 10:37:23 muench Stab $"; + +#define _ANSI_C_SOURCE +#include + +#include +#include + +#include + +#include "hadtu.h" + +char *HadTu_2charP(const void *my) +{ + static char buf[80]; + + sprintf(buf, "size: 0x%08x\tdecoding: 0x%08x", + HadTu_size(my), HadTu_decoding(my)); + + return buf; +} diff --git a/hadaq/hadtu.h b/hadaq/hadtu.h new file mode 100644 index 0000000..e78f02f --- /dev/null +++ b/hadaq/hadtu.h @@ -0,0 +1,154 @@ +#ifndef HADTU_H +#define HADTU_H + +#include +#include + +enum HadTu_Decoding { + HadTu_queueDecoding = 3 << 16 | 99 +}; + +static UInt4 *HadTu_hdr(const void *my); +static size_t HadTu_hdrLen(void); +static size_t HadTu_hdrSize(void); +static int HadTu_isSwapped(const void *my); +static UInt4 HadTu_hdrValue(const void *my, unsigned idx); +static void HadTu_setHdrValue(const void *my, unsigned idx, UInt4 value); +static UInt4 HadTu_decoding(const void *my); +static void HadTu_setDecoding(void *my, UInt4 decoding); +static unsigned HadTu_alignment(const void *my); +static UInt4 HadTu_size(const void *my); +static void HadTu_setSize(void *my, UInt4 size); +static size_t HadTu_paddedSize(const void *my); +static void *HadTu_begin(const void *my); +static void *HadTu_end(const void *my); +static size_t HadTu_dataSize(const void *my); +static void *HadTu_data(const void *my); +static void *HadTu_next(const void *my, const void *hadTu); +char *HadTu_2charP(const void *my); + +enum HadTuIdx { + HadTuIdx_size, + HadTuIdx_decoding, + HadTuIdx_data +}; + +static UInt4 *HadTu_hdr(const void *my) +{ + return (UInt4 *) my; +} + +static size_t HadTu_hdrLen(void) +{ + return HadTuIdx_data; +} + +static size_t HadTu_hdrSize(void) +{ + return HadTu_hdrLen() * sizeof(UInt4); +} + +static int HadTu_isSwapped(const void *my) +{ + UInt4 *hdr = HadTu_hdr(my); + + return hdr[HadTuIdx_decoding] > 0xffffff; +} + +static UInt4 HadTu_hdrValue(const void *my, unsigned idx) +{ + UInt4 *hdr = HadTu_hdr(my); + + if (HadTu_isSwapped(my)) { + UInt4 tmp0; + UInt4 tmp1; + + tmp0 = hdr[idx]; + ((char *) &tmp1)[0] = ((char *) &tmp0)[3]; + ((char *) &tmp1)[1] = ((char *) &tmp0)[2]; + ((char *) &tmp1)[2] = ((char *) &tmp0)[1]; + ((char *) &tmp1)[3] = ((char *) &tmp0)[0]; + return tmp1; + } else { + return hdr[idx]; + } +} + +static void HadTu_setHdrValue(const void *my, unsigned idx, UInt4 value) +{ + UInt4 *hdr = HadTu_hdr(my); + + hdr[idx] = value; +} + +static UInt4 HadTu_decoding(const void *my) +{ + return HadTu_hdrValue(my, HadTuIdx_decoding); +} + +static void HadTu_setDecoding(void *my, UInt4 decoding) +{ + HadTu_setHdrValue(my, HadTuIdx_decoding, decoding); +} + +static unsigned HadTu_alignment(const void *my) +{ + return 1 << (HadTu_decoding(my) >> 16 & 0xff); +} + +static UInt4 HadTu_size(const void *my) +{ + return HadTu_hdrValue(my, HadTuIdx_size); +} + +static void HadTu_setSize(void *my, UInt4 size) +{ + HadTu_setHdrValue(my, HadTuIdx_size, size); +} + +static size_t HadTu_paddedSize(const void *my) +{ + UInt4 size; + UInt4 alignment; + + size = HadTu_size(my); + alignment = HadTu_alignment(my); + return (size & (alignment - 1)) + ? (size & ~(alignment - 1)) + alignment : size; +} + +static void *HadTu_begin(const void *my) +{ + return (void *) my; +} + +static void *HadTu_end(const void *my) +{ + return (void *) ((char *) my + HadTu_paddedSize(my)); +} + +static size_t HadTu_dataSize(const void *my) +{ + return HadTu_size(my) - HadTu_hdrSize(); +} + +static void *HadTu_data(const void *my) +{ + return (void *) ((char *) my + HadTu_hdrSize()); +} + +static void *HadTu_next(const void *my, const void *hadTu) +{ + UInt4 size; + UInt4 alignment; + size_t paddedSize; + + size = HadTu_size(hadTu); + alignment = HadTu_alignment(my); + paddedSize = (size & (alignment - 1)) + ? (size & ~(alignment - 1)) + alignment : size; + + return (void *) ((char *) hadTu + paddedSize); +} + +#endif diff --git a/hadaq/hadtuqueue.c b/hadaq/hadtuqueue.c new file mode 100644 index 0000000..f986fa7 --- /dev/null +++ b/hadaq/hadtuqueue.c @@ -0,0 +1,138 @@ +static char rcsId[] = "$Id: hadtuqueue.c,v 6.1 1999-08-31 10:37:23 muench Stab $"; + +#define _ANSI_C_SOURCE +#include + +#include + +#include "hadtu.h" + +struct HadTuQueueS { + void *hadTu; + void *run; + size_t maxSize; +}; + +#include "hadtuqueue.h" + +int HadTuQueue_invariant(const HadTuQueue *my) +{ + return ( + my->maxSize > HadTu_hdrSize() + && my->run >= HadTu_data(my->hadTu) + && my->run <= HadTu_end(my->hadTu) + && HadTu_size(my->hadTu) == HadTu_paddedSize(my->hadTu) + ); +} + +void conHadTuQueue(HadTuQueue *my, void *mem, size_t maxSize) +{ + my->hadTu = mem; + HadTu_setSize(my->hadTu, HadTu_hdrSize()); + HadTu_setDecoding(my->hadTu, HadTu_queueDecoding); + + my->run = HadTu_data(my->hadTu); + + /* truncate to aligned size */ + my->maxSize = (maxSize / HadTu_alignment(my->hadTu)) * HadTu_alignment(my->hadTu); + + assert(HadTuQueue_invariant(my)); +} + +void conHadTuQueue_voidP(HadTuQueue *my, void *mem) +{ + my->hadTu = mem; + my->run = HadTu_data(my->hadTu); + my->maxSize = HadTu_size(my->hadTu); + + assert(HadTuQueue_invariant(my)); +} + +void desHadTuQueue(HadTuQueue *my) +{ + assert(HadTuQueue_invariant(my)); +} + +size_t HadTuQueue_sizeOf(void) +{ + return sizeof(HadTuQueue); +} + +void HadTuQueue_cntl(HadTuQueue *my, int flag) +{ + assert(HadTuQueue_invariant(my)); + assert(flag == HadTuQueueProt_read || flag == HadTuQueueProt_write); + + switch (flag) { + case HadTuQueueProt_read: + my->run = HadTu_data(my->hadTu); + break; + case HadTuQueueProt_write: + my->run = HadTu_data(my->hadTu); + HadTu_setSize(my->hadTu, HadTu_hdrSize()); + break; + } + assert(HadTuQueue_invariant(my)); +} + +void HadTuQueue_clear(HadTuQueue *my) +{ + assert(HadTuQueue_invariant(my)); + my->run = HadTu_data(my->hadTu); + HadTu_setSize(my->hadTu, HadTu_hdrSize()); + assert(HadTuQueue_invariant(my)); +} + +int HadTuQueue_empty(const HadTuQueue *my) +{ + assert(HadTuQueue_invariant(my)); + return HadTu_size(my->hadTu) == (char *) my->run - (char *) my->hadTu; +} + +void *HadTuQueue_alloc(const HadTuQueue *my, size_t size) +{ + void *retVal; + + assert(HadTuQueue_invariant(my)); + assert(size + HadTu_hdrSize() <= my->maxSize); + if (HadTu_size(my->hadTu) + size > my->maxSize) { + retVal = NULL; + } else { + retVal = my->run; + } + return retVal; +} + +void HadTuQueue_push(HadTuQueue *my) +{ + assert(HadTuQueue_invariant(my)); + my->run = HadTu_next(my->hadTu, my->run); + HadTu_setSize(my->hadTu, (char *) my->run - (char *) my->hadTu); + assert(HadTuQueue_invariant(my)); +} + +void *HadTuQueue_2voidP(const HadTuQueue *my) +{ + assert(HadTuQueue_invariant(my)); + return HadTu_hdr(my->hadTu); +} + +void *HadTuQueue_front(const HadTuQueue *my) +{ + void *retVal; + + assert(HadTuQueue_invariant(my)); + if (HadTuQueue_empty(my)) { + retVal = NULL; + } else { + retVal = my->run; + } + return retVal; +} + +void HadTuQueue_pop(HadTuQueue *my) +{ + assert(HadTuQueue_invariant(my)); + my->run = HadTu_next(my->hadTu, my->run); + assert(HadTuQueue_invariant(my)); +} diff --git a/hadaq/hadtuqueue.h b/hadaq/hadtuqueue.h new file mode 100644 index 0000000..0ab4282 --- /dev/null +++ b/hadaq/hadtuqueue.h @@ -0,0 +1,30 @@ + +#ifndef HADTUQUEUE_H +#define HADTUQUEUE_H + +#include +#include "hadtu.h" + +typedef struct HadTuQueueS HadTuQueue; + +typedef enum HadTuQueueProtE { + HadTuQueueProt_read, + HadTuQueueProt_write +} HadTuQueueProt; + +void conHadTuQueue(HadTuQueue *my, void *mem, size_t size); +void conHadTuQueue_voidP(HadTuQueue *my, void *mem); +void desHadTuQueue(HadTuQueue *my); +size_t HadTuQueue_sizeOf(void); +void HadTuQueue_cntl(HadTuQueue *my, int flag); +void HadTuQueue_clear(HadTuQueue *my); +int HadTuQueue_invariant(const HadTuQueue *my); + +int HadTuQueue_empty(const HadTuQueue *my); +void *HadTuQueue_alloc(const HadTuQueue *my, size_t size); +void HadTuQueue_push(HadTuQueue *my); +void *HadTuQueue_2voidP(const HadTuQueue *my); +void *HadTuQueue_front(const HadTuQueue *my); +void HadTuQueue_pop(HadTuQueue *my); + +#endif diff --git a/hadaq/hardware.h b/hadaq/hardware.h new file mode 100644 index 0000000..07eeb13 --- /dev/null +++ b/hadaq/hardware.h @@ -0,0 +1,13 @@ +#ifndef HARDWARE_H +#define HARDWARE_H + +typedef struct HardwareS Hardware; + +Hardware *newHardware(void); +void deleteHardware(Hardware * my); +int Hardware_inSpill(const Hardware * my); +size_t Hardware_maxSubEvtSize(const Hardware * my); +void Hardware_waitForTrigger(const Hardware * my, void *subEvt); +void Hardware_readout(const Hardware * my, void *subEvt); + +#endif diff --git a/hadaq/hldread.c b/hadaq/hldread.c new file mode 100644 index 0000000..a063faf --- /dev/null +++ b/hadaq/hldread.c @@ -0,0 +1,151 @@ +static char rcsId[] = "$Id: hldread.c,v 6.1 1999-08-31 10:37:23 muench Stab $"; + +#define _POSIX_C_SOURCE 199309L +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "evt.h" +#include "hldread.h" + +static unsigned long processedEvts = 0; +static unsigned int timeout = 0; + +static int excludeAnal = 0; + +static void showProcessedEvts(unsigned long processedEvts) +{ + static unsigned long keepProcessedEvts = 0; + int level; + char *notice; + + if (processedEvts > keepProcessedEvts) { + level = LOG_INFO; + notice = ""; + } else { + level = LOG_NOTICE; + notice = ", \ano new events arrived"; + } + msglog(level, "%5u events processed %-30s\r", processedEvts, notice); +} + +static void atexit0(void) +{ + if (!excludeAnal) + stopAnalysis(); + msglog(LOG_INFO, "%5u events processed %-30s\n", processedEvts, ""); +} + +void sigHandler(int sig) +{ + exit(128 + sig); +} + +void alarmHandler(int x) +{ + signal(SIGALRM, alarmHandler); + alarm(timeout); + showProcessedEvts(processedEvts); +} + +void main(int argc, char *argv[]) +{ + int i = 0; + FILE *file = NULL; + void *evt; + unsigned long readEvts = 0; + unsigned long fEvts = 0; + unsigned long nEvts = ULONG_MAX; + unsigned long echoRate = ULONG_MAX; + char **analArgv = malloc(sizeof(char *)); + int analArgc = 1; /* Filename is in analArgv[0] */ + + msglog_setlevel(argv[0], "info"); + while ((i = getopt(argc, argv, "n:f:e:t:xo:v:")) != -1) { + switch (i) { + case 'f': + fEvts = atol(optarg); + break; + case 'n': + nEvts = atol(optarg); + break; + case 'e': + echoRate = atol(optarg); + break; + case 't': + timeout = atoi(optarg); + break; + case 'x': + excludeAnal = 1; + break; + case 'o': + analArgv = realloc(analArgv, sizeof(char *) * (analArgc + 1)); + + analArgv[analArgc++] = optarg; + break; + case 'v': + if (msglog_setlevel(argv[0], optarg) == 1) { + break; + } /* FALLTHROUGH to default */ + default: + msglog( + LOG_ERR, + "Usage: %s -f firstEvent -n numEvents -e echoRate\n", + argv[0] + ); + msglog_usage(); + msglog( + LOG_ERR, + "-t timeout -o analArgs -x (excludeAnal) [fileName]\n" + ); + exit(EXIT_FAILURE); + break; + } /* switch (i ... */ + } /* while ((i ... */ + if (argv[optind] == NULL) { + file = stdin; + analArgv[0] = "-"; + } else { + file = fopen(argv[optind], "r"); + analArgv[0] = argv[optind]; + } + if (file == NULL) { + msglog(LOG_ERR, "Opening input file: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + if (!excludeAnal) { + startAnalysis(analArgc, analArgv); + } + atexit(atexit0); + + signal(SIGINT, sigHandler); + signal(SIGTERM, sigHandler); + + signal(SIGALRM, alarmHandler); + alarm(timeout); + + while ((evt = Evt_fget(file)) != NULL && processedEvts < nEvts) { + readEvts++; + if (readEvts >= fEvts) { + if (!excludeAnal) + analyseEvt(evt); + processedEvts++; + if (processedEvts == 1) { + msglog(LOG_INFO, "First event processed %-30s\r", ""); + } else if (processedEvts % echoRate == 0) { + alarm(timeout); + showProcessedEvts(processedEvts); + } + } + } + exit(EXIT_SUCCESS); +} diff --git a/hadaq/hldread.h b/hadaq/hldread.h new file mode 100644 index 0000000..c3ca816 --- /dev/null +++ b/hadaq/hldread.h @@ -0,0 +1,10 @@ +#ifndef HLDREAD_H +#define HLDREAD_H + +#include "evt.h" + +int startAnalysis(int argc, char **argv); +int analyseEvt(void *evt); +int stopAnalysis(void); + +#endif diff --git a/hadaq/ht98.tcl b/hadaq/ht98.tcl new file mode 100644 index 0000000..6ad7ebd --- /dev/null +++ b/hadaq/ht98.tcl @@ -0,0 +1,14 @@ +agent create acheron +agent create gast8 +worker create acheron:evtbuild -a -p -2 -s 3 -m 1 -f runinfo.tcl +worker create acheron:netmem -a -p -1 -m 1 +worker create gast8:memnet -a -p -1 -o 0:50 -w 68000 +worker create gast8:readout -a -p -2 +worker create gast8:ctrlctu -a +group create acquisition +group create run +group add acquisition gast8:memnet +group add acquisition gast8:readout +group add acquisition gast8:ctrlctu +group add run acheron:evtbuild +group add run acheron:netmem diff --git a/hadaq/hwmdc.c b/hadaq/hwmdc.c new file mode 100644 index 0000000..a07d8fd --- /dev/null +++ b/hadaq/hwmdc.c @@ -0,0 +1,84 @@ + +#define _POSIX_C_SOURCE 199309L +#include +#include + +#include "param.h" +#include "subevt.h" +#include "hwsam.h" + +struct HardwareS { + size_t maxSubEvtSize; + void *specific; +}; + +#include "hardware.h" + +size_t Hardware_maxSubEvtSize(const Hardware *my) +{ + return my->maxSubEvtSize; +} + +int Hardware_inSpill(const Hardware *my) +{ + return 0; +} + +Hardware *newHardware(void) +{ + Hardware *my; + Param paramS, *param = ¶mS; + HwSam *sam; + int i; + + if (0 > conParam(param, "param.tcl")) { + msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno)); + return NULL; + } + my = allocMem(sizeof(Hardware)); + my->specific = allocMem(sizeof(sam)); + + my->maxSubEvtSize = SubEvt_hdrSize(); + + sam = allocMem(sizeof(HwSam)); + if (0 > conHwSam(sam, "sam", param)) { + msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno)); + return NULL; + } + (HwSam *) my->specific = sam; + + + desParam(param); + return my; +} + +void deleteHardware(Hardware *my) +{ + HwSam *sam = (HwSam *) my->specific; + + desHwSam(sam); + freeMem(sam); + + freeMem(my); +} + +void Hardware_waitForTrigger(const Hardware *my, void *subEvt) +{ + HwSam *sam = (HwSam *) my->specific; + + while (HwSam_isBusy(sam) || HwSam_isEmpty(sam)) { +#if 1 + struct timespec tS, *t = &tS; + t->tv_sec = 0; + t->tv_nsec = 020000000; + nanosleep(t, NULL); +#endif + } +} + +void Hardware_readout(const Hardware *my, void *subEvt) +{ + HwSam *sam = (HwSam *) my->specific; + + HwSam_readSubEvt(sam, subEvt); +} diff --git a/hadaq/hwrace.c b/hadaq/hwrace.c new file mode 100644 index 0000000..d030242 --- /dev/null +++ b/hadaq/hwrace.c @@ -0,0 +1,146 @@ +static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/Attic/hwrace.c,v 6.1 1999-08-31 10:37:23 muench Exp $"; + +#define _POSIX_C_SOURCE 199309L +#include + +#include +#include +#include +#include + +#include +#include + + +#include "subevt.h" +#include "param.h" +#include "rc.h" +#include "hwrace.h" + +#define RCPAGESIZE 256 + +static int bankRequested(HwRace *my) +{ + return Rc_readPages(my->rc) >> 14 & 1; +} + +static int bankConfirmed(HwRace *my) +{ + return Rc_readPages(my->rc) >> 15 & 1; +} + +static int endOfData(HwRace *my) +{ + return (Rc_readPages(my->rc) & 0x1ff) * RCPAGESIZE; +} + +static void standbyMode(HwRace *my) +{ + Rc_clrStop(my->rc); + Rc_clrReset(my->rc); + Rc_setReset(my->rc); +} + +static void acquireMode(HwRace *my) +{ + Rc_ClrCtrs(my->rc); + Rc_writeStatusid(my->rc, 0x55); + Rc_setMemfull(my->rc, 0x1f4); + Rc_writeSedec_high(my->rc, 0x0002); + Rc_writeSedec_low(my->rc, 0x0001); + Rc_writeSeid_high(my->rc, 0x0000); + Rc_writeSeid_low(my->rc, 113); + Rc_setMsel(my->rc); + /* Rc_writeMskreg(my->rc, 0xff); */ + Rc_clrMsel(my->rc); + Rc_setStop(my->rc); +} + +int conHwRace(HwRace *my, const char *name, const Param *param) +{ + unsigned long cardBase; + int i; + + assert(my != NULL); + + strcpy(my->name, name); + + cardBase = Param_getVal(param, my->name, "cardbase"); + my->rc = allocMem(sizeof(Rc)); + + if (0 > conRc(my->rc, "rc", cardBase)) { + msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno)); + return -1; + } + my->lbma = allocMem(sizeof(LBma)); + + if (0 > conLBma(my->lbma, cardBase + 0x100000, 512 * 1024, 0x09)) { + msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno)); + return -1; + } + my->buf = LBma_getPtrL(my->lbma, 0); + + standbyMode(my); + acquireMode(my); + return 0; +} + +void desHwRace(HwRace *my) +{ + desLBma(my->lbma); + freeMem(my->lbma); + + standbyMode(my); + desRc(my->rc); + freeMem(my->rc); +} + +void HwRace_requestBuffer(HwRace *my) +{ + my->currAddr = 0; + Rc_setSwrq(my->rc); + Rc_clrSwrq(my->rc); +} + +int HwRace_isBusy(HwRace *my) +{ + return bankRequested(my) != bankConfirmed(my); +} + +int HwRace_isEmpty(HwRace *my) +{ + return my->currAddr >= endOfData(my); +} + +int HwRace_readSubEvt(HwRace *my, void *subEvt) +{ + UInt4 *data = (UInt4 *) subEvt; + int firstAddr; + int size; + + if (my->currAddr == 0) { + size = endOfData(my) - my->currAddr; + if (0 > LBma_read(my->lbma, 0, 0, size)) { + msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno)); + } + } + size = *(my->buf + my->currAddr / 4); + + /* copy one sub evt from RC to memory */ + memcpy(data, my->buf + my->currAddr / 4, size); + my->currAddr += size; + data += size / 4; + + /* normal extension of trigger tag */ + if (SubEvt_trigNr(subEvt) < (my->trigNr & 0xff)) { + my->trigNr += 0x100; + } + my->trigNr = (my->trigNr & 0xffffff00) | (SubEvt_trigNr(subEvt) & 0x000000ff); + SubEvt_setTrigNr(subEvt, my->trigNr); + + /* align currAddr to next page */ + if ((my->currAddr & 0xff) != 0) { + my->currAddr = (my->currAddr / RCPAGESIZE + 1) * RCPAGESIZE; + } + return 0; +} diff --git a/hadaq/hwrace.h b/hadaq/hwrace.h new file mode 100644 index 0000000..ae7de41 --- /dev/null +++ b/hadaq/hwrace.h @@ -0,0 +1,27 @@ +#ifndef HwRace_H +#define HwRace_H + +#include +#include "rc.h" + +#include "param.h" + +typedef struct HwRaceS { + char name[16]; + Rc *rc; + LBma *lbma; + LVme_L *buf; + int currAddr; + int trigNr; +} HwRace; + + +int conHwRace(HwRace *my, const char *name, const Param *param); +void desHwRace(HwRace *my); + +void HwRace_requestBuffer(HwRace *my); +int HwRace_isBusy(HwRace *my); +int HwRace_isEmpty(HwRace *my); +int HwRace_readSubEvt(HwRace *my, void *subEvt); + +#endif diff --git a/hadaq/hwrich.c b/hadaq/hwrich.c new file mode 100644 index 0000000..e62273a --- /dev/null +++ b/hadaq/hwrich.c @@ -0,0 +1,92 @@ +static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/Attic/hwrich.c,v 6.1 1999-08-31 10:37:24 muench Exp $"; + +#define _POSIX_C_SOURCE 199309L +#include + +#include +#include +#include +#include + +#include "param.h" +#include "subevt.h" +#include "hwrace.h" + +struct HardwareS { + size_t maxSubEvtSize; + void *specific; +}; + +#include "hardware.h" + +size_t Hardware_maxSubEvtSize(const Hardware *my) +{ + return my->maxSubEvtSize; +} + +int Hardware_inSpill(const Hardware *my) +{ + return 0; +} + +Hardware *newHardware(void) +{ + Hardware *my; + Param paramS, *param = ¶mS; + HwRace *race; + int i; + + if (0 > conParam(param, "param.tcl")) { + msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno)); + return NULL; + } + my = allocMem(sizeof(Hardware)); + my->specific = allocMem(sizeof(race)); + + my->maxSubEvtSize = SubEvt_hdrSize() + (2564 * sizeof(UInt4)); + + race = allocMem(sizeof(HwRace)); + if (0 > conHwRace(race, "race", param)) { + msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno)); + return NULL; + } + (HwRace *) my->specific = race; + + + desParam(param); + return my; +} + +void deleteHardware(Hardware *my) +{ + HwRace *race = (HwRace *) my->specific; + + desHwRace(race); + freeMem(race); + + freeMem(my); +} + +void Hardware_waitForTrigger(const Hardware *my, void *subEvt) +{ + HwRace *race = (HwRace *) my->specific; + + if (HwRace_isEmpty(race)) { + HwRace_requestBuffer(race); + while (HwRace_isBusy(race)) { +#if 1 + struct timespec tS, *t = &tS; + t->tv_sec = 0; + t->tv_nsec = 020000000; + nanosleep(t, NULL); +#endif + } + } +} + +void Hardware_readout(const Hardware *my, void *subEvt) +{ + HwRace *race = (HwRace *) my->specific; + + HwRace_readSubEvt(race, subEvt); +} diff --git a/hadaq/hwsam.c b/hadaq/hwsam.c new file mode 100644 index 0000000..5d147c2 --- /dev/null +++ b/hadaq/hwsam.c @@ -0,0 +1,111 @@ + +#include +#include + +#include +#include + +#include "param.h" + +#include "sam_defs.h" +#include "hwsam.h" + +#define BUFSIZE 0x1000 + +static int bankRequested(HwSam *my) +{ + return LVme_getBitL(my->lvme, CRR, 0); +} + +static int bankConfirmed(HwSam *my) +{ + return LVme_getBitL(my->lvme, VMSR, 0); +} + +static int endOfData(HwSam *my) +{ + int i; + + i = BUFSIZE * bankRequested(my); + return i + LVme_getL(my->lvme, i); +} + +static void standbyMode(HwSam *my) +{ + LVme_clrBitL(my->lvme, KSR, 0); + do { + LVme_setL(my->lvme, CRR, 0); + } while (LVme_getL(my->lvme, CRR) != 0); +} + +static void acquireMode(HwSam *my) +{ + LVme_setBitL(my->lvme, KSR, 0); +} + +int conHwSam(HwSam *my, const char *name, const Param *param) +{ + unsigned long cardBase; + int i; + + assert(my != NULL); + + strcpy(my->name, name); + + cardBase = Param_getVal(param, my->name, "cardbase"); + my->lvme = allocMem(sizeof(LVme)); + if (0 > conLVme(my->lvme, 0x4c000000, 0x04000000L, 0x09, 0x01000004, 4)) { + msglog(LOG_ERR, "HwSam on %p not found\n", cardBase); + return -1; + } + standbyMode(my); + acquireMode(my); + return 0; +} + +void desHwSam(HwSam *my) +{ + standbyMode(my); + desLVme(my->lvme); +} + +void HwSam_requestBuffer(HwSam *my) +{ + int i; + + i = bankRequested(my) == 1 ? 0 : 1; + do { + if (i == 1) { + LVme_setBitL(my->lvme, CRR, 0); + } else { + LVme_clrBitL(my->lvme, CRR, 0); + } + } while (LVme_getBitL(my->lvme, CRR) != i); + + my->currAddr = BUFSIZE * bankRequested(my) + 8; +} + +int HwSam_isBusy(HwSam *my) +{ + return bankRequested(my) != bankConfirmed(my); +} + +int HwSam_isEmpty(HwSam *my) +{ + return my->currAddr >= endOfData(my); +} + +void *HwSam_nextSubEvt(HwSam *my, void *subEvt) +{ + UInt4 *data = (UInt4 *) subEvt; + int firstAddr; + int size; + + size = LVme_getL(my->lvme, my->currAddr); + + /* copy one sub evt from RC to memory */ + for (firstAddr = my->currAddr; my->currAddr - firstAddr < size; my->currAddr += 4) { + *data++ = LVme_getL(my->lvme, my->currAddr); + } + return 0; +} diff --git a/hadaq/hwsam.h b/hadaq/hwsam.h new file mode 100644 index 0000000..ad7533a --- /dev/null +++ b/hadaq/hwsam.h @@ -0,0 +1,24 @@ +#ifndef HwSam_H +#define HwSam_H + +#include + +#include "param.h" + +typedef struct HwSamS { + char name[16]; + LVme *lvme; + int bufSize; + int currAddr; +} HwSam; + + +int conHwSam(HwSam *my, const char *name, const Param *param); +void desHwSam(HwSam *my); + +void HwSam_requestBuffer(HwSam *my); +int HwSam_isBusy(HwSam *my); +int HwSam_isEmpty(HwSam *my); +void *HwSam_nextSubEvt(HwSam *my, void *subEvt); + +#endif diff --git a/hadaq/hwship.c b/hadaq/hwship.c new file mode 100644 index 0000000..664708f --- /dev/null +++ b/hadaq/hwship.c @@ -0,0 +1,169 @@ + +#include +#include + +#include +#include +#include + +#include "param.h" + +#include "ipc_basis.h" +#include "hwship.h" + +#define SHIP_SUBEVTSIZE (4 * 2 * 386) + +static int bankRequested(HwShip *my) +{ + UInt2 val; + + val = LVme_tstBitW(my->lvme, LVL2_STAT_READ, 6); + return val; +} + +static int bankConfirmed(HwShip *my) +{ + UInt2 val; + + val = LVme_tstBitW(my->lvme, LVL2_STAT_READ, 8); + return val; +} + +static int endOfData(HwShip *my) +{ + return ((LVme_getL(my->lvme, LVL2_OFFSET) & 0x7f) + 1) * SHIP_SUBEVTSIZE + LVL2_OFFSET; +} + +static void standbyMode(HwShip *my) +{ + LVme_setW(my->lvme, ID_CTR_ACCESS_ON, 0); + LVme_setW(my->lvme, ID_CTR_STANDBY_MODE, 0); + LVme_setW(my->lvme, ID_CTR_SW_TO_LUT12, 0); + LVme_setW(my->lvme, LUT_CTR_STANDBY_MODE, 0); + LVme_setW(my->lvme, ID_CTR_SW_TO_LUT34, 0); + LVme_setW(my->lvme, LUT_CTR_STANDBY_MODE, 0); + LVme_setW(my->lvme, ID_CTR_ACCESS_OFF, 0); + LVme_setW(my->lvme, PEDAS_ACCESS_ON, 0); + LVme_setW(my->lvme, PEDAS_STANDBY_MODE, 0); + LVme_setW(my->lvme, PEDAS_ACCESS_OFF, 0); + LVme_setW(my->lvme, RC1_ACCESS_ON, 0); + LVme_setW(my->lvme, RC1_STANDBY_MODE, 0); + LVme_setW(my->lvme, RC1_ACCESS_OFF, 0); + LVme_setW(my->lvme, LVL2_ACCESS_ON, 0); + LVme_setW(my->lvme, LVL2_STANDBY_MODE, 0); + LVme_setW(my->lvme, LVL2_ACCESS_OFF, 0); + LVme_setW(my->lvme, RC3_ACCESS_ON, 0); + LVme_setW(my->lvme, RC3_STANDBY_MODE, 0); + LVme_setW(my->lvme, RC3_ACCESS_OFF, 0); + LVme_setW(my->lvme, ADDON_ACCESS_ON, 0); + LVme_setW(my->lvme, ADDON_STANDBY_MODE, 0); + LVme_setW(my->lvme, ADDON_ACCESS_OFF, 0); +} + +static void acquireMode(HwShip *my) +{ + LVme_setW(my->lvme, ID_CTR_ACCESS_ON, 0); + LVme_setW(my->lvme, ID_CTR_STANDBY_MODE, 0); + LVme_setW(my->lvme, ID_CTR_SW_TO_LUT12, 0); + LVme_setW(my->lvme, LUT_CTR_SHOWER_MODE, 0); + LVme_setW(my->lvme, ID_CTR_SW_TO_LUT34, 0); + LVme_setW(my->lvme, LUT_CTR_SHOWER_MODE, 0); + LVme_setW(my->lvme, ID_CTR_ACCESS_OFF, 0); + LVme_setW(my->lvme, RC1_ACCESS_ON, 0); + LVme_setW(my->lvme, RC1_SHOWER_MODE, 0); + LVme_setW(my->lvme, RC1_ACCESS_OFF, 0); + LVme_setW(my->lvme, PEDAS_ACCESS_ON, 0); + LVme_setW(my->lvme, PEDAS_SHOWER_MODE, 0); + LVme_setW(my->lvme, PEDAS_ACCESS_OFF, 0); + LVme_setW(my->lvme, LVL2_ACCESS_ON, 0); + LVme_setW(my->lvme, LVL2_SHOWER_MODE, 0); + LVme_setW(my->lvme, LVL2_STAT_WRITE, 0); + LVme_setW(my->lvme, LVL2_ACCESS_OFF, 0); + LVme_setW(my->lvme, RC3_ACCESS_ON, 0); + LVme_setW(my->lvme, RC3_SHOWER_MODE, 0); + LVme_setW(my->lvme, RC3_ACCESS_OFF, 0); + LVme_setW(my->lvme, ADDON_ACCESS_ON, 0); + LVme_setW(my->lvme, ADDON_SHOWER_MODE, 0); + LVme_setW(my->lvme, ADDON_ACCESS_OFF, 0); + LVme_setW(my->lvme, LVL2_ACCESS_ON, 0); +} + +int conHwShip(HwShip *my, const char *name, const Param *param) +{ + unsigned long cardBase; + int i; + + assert(my != NULL); + + strcpy(my->name, name); + + cardBase = Param_getVal(param, my->name, "cardbase"); + my->lvme = allocMem(sizeof(LVme)); + if (0 > conLVme(my->lvme, cardBase, 0x400000UL, 0x39UL, 0, 0)) { + msglog(LOG_ERR, "HwShip on %p not found\n", cardBase); + return -1; + } + standbyMode(my); + acquireMode(my); + return 0; +} + +void desHwShip(HwShip *my) +{ + standbyMode(my); + desLVme(my->lvme); +} + +void HwShip_requestBuffer(HwShip *my) +{ + int i; + + msglog(LOG_DEBUG, "%s:%d:%x\n", __FILE__, __LINE__, LVme_getW(my->lvme, LVL2_STAT_READ)); + while ((LVme_getW(my->lvme, LVL2_STAT_READ) >> 9 & 0x7f) < 2) { + } + msglog(LOG_DEBUG, "%s:%d:%x\n", __FILE__, __LINE__, LVme_getW(my->lvme, LVL2_STAT_READ)); + i = bankRequested(my) == 1 ? 0 : 1; + msglog(LOG_DEBUG, "%s:%d:%x\n", __FILE__, __LINE__, i); + LVme_setW(my->lvme, LVL2_STAT_WRITE, i << 1); + + my->currAddr = 0x18 + LVL2_OFFSET; +} + +int HwShip_isBusy(HwShip *my) +{ + msglog(LOG_DEBUG, "%s:%d:%x\n", __FILE__, __LINE__, LVme_getW(my->lvme, LVL2_STAT_READ)); + return bankRequested(my) != bankConfirmed(my); +} + +int HwShip_isEmpty(HwShip *my) +{ + return my->currAddr >= endOfData(my); +} + +int HwShip_readSubEvt(HwShip *my, void *subEvt) +{ + UInt4 *data = (UInt4 *) subEvt; + static UInt1 trigTag; + int firstAddr; + int size; + + size = SHIP_SUBEVTSIZE; + + if ((trigTag + 2) != (LVme_getL(my->lvme, my->currAddr) & 0xff)) { + msglog(LOG_ERR, "0x%08x != 0x%08x\n", trigTag + 2, LVme_getL(my->lvme, my->currAddr)); + } + trigTag = LVme_getL(my->lvme, my->currAddr); + + if (LVme_getL(my->lvme, my->currAddr) & 0xff != LVme_getL(my->lvme, my->currAddr + 4 * 388) & 0xff) { + msglog(LOG_ERR, "0x%08x != 0x%08x\n", LVme_getL(my->lvme, my->currAddr), LVme_getL(my->lvme, my->currAddr + 4 * 388)); + } + *data++ = size + 16; + *data++ = 0x00020001; + *data++ = 456; + *data++ = LVme_getL(my->lvme, my->currAddr); + /* copy one sub evt from RC to memory */ + for (firstAddr = my->currAddr; my->currAddr - firstAddr < size; my->currAddr += 4) { + *data++ = LVme_getL(my->lvme, my->currAddr); + } + return 0; +} diff --git a/hadaq/hwship.h b/hadaq/hwship.h new file mode 100644 index 0000000..68a10b0 --- /dev/null +++ b/hadaq/hwship.h @@ -0,0 +1,23 @@ +#ifndef HwShip_H +#define HwShip_H + +#include + +#include "param.h" + +typedef struct HwShipS { + char name[16]; + LVme *lvme; + int currAddr; +} HwShip; + + +int conHwShip(HwShip *my, const char *name, const Param *param); +void desHwShip(HwShip *my); + +void HwShip_requestBuffer(HwShip *my); +int HwShip_isBusy(HwShip *my); +int HwShip_isEmpty(HwShip *my); +int HwShip_readSubEvt(HwShip *my, void *subEvt); + +#endif diff --git a/hadaq/hwshow.c b/hadaq/hwshow.c new file mode 100644 index 0000000..6c9fc7c --- /dev/null +++ b/hadaq/hwshow.c @@ -0,0 +1,90 @@ + +#define _POSIX_C_SOURCE 199309L +#include +#include + +#include "param.h" +#include "subevt.h" +#include "hwship.h" + +struct HardwareS { + size_t maxSubEvtSize; + void *specific; +}; + +#include "hardware.h" + +size_t Hardware_maxSubEvtSize(const Hardware *my) +{ + return my->maxSubEvtSize; +} + +int Hardware_inSpill(const Hardware *my) +{ + return 0; +} + +Hardware *newHardware(void) +{ + Hardware *my; + Param paramS, *param = ¶mS; + HwShip *ship; + int i; + + if (0 > conParam(param, "param.tcl")) { + msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno)); + return NULL; + } + my = allocMem(sizeof(Hardware)); + my->specific = allocMem(sizeof(ship)); + + my->maxSubEvtSize = SubEvt_hdrSize(); + + ship = allocMem(sizeof(HwShip)); + if (0 > conHwShip(ship, "ship", param)) { + msglog(LOG_DEBUG, "%s:%d:%s\n", __FILE__, __LINE__, strerror(errno)); + return NULL; + } + (HwShip *) my->specific = ship; + + + desParam(param); + return my; +} + +void deleteHardware(Hardware *my) +{ + HwShip *ship = (HwShip *) my->specific; + + desHwShip(ship); + freeMem(ship); + + freeMem(my); +} + +void Hardware_waitForTrigger(const Hardware *my, void *subEvt) +{ + HwShip *ship = (HwShip *) my->specific; + + if (HwShip_isEmpty(ship)) { + msglog(LOG_DEBUG, "switchRequest\n"); + HwShip_requestBuffer(ship); + while (HwShip_isBusy(ship)) { +#if 0 + struct timespec tS, *t = &tS; + t->tv_sec = 0; + t->tv_nsec = 020000000; + nanosleep(t, NULL); +#endif + } + msglog(LOG_DEBUG, "switchComplete\n"); + } +} + +void Hardware_readout(const Hardware *my, void *subEvt) +{ + HwShip *ship = (HwShip *) my->specific; + + HwShip_readSubEvt(ship, subEvt); + msglog(LOG_DEBUG, "subEvt read\n"); +} diff --git a/hadaq/hwsoft.c b/hadaq/hwsoft.c new file mode 100644 index 0000000..59ffce7 --- /dev/null +++ b/hadaq/hwsoft.c @@ -0,0 +1,79 @@ + +#define _POSIX_C_SOURCE 199309L +#include + +#include + +#include "subevt.h" +#include "param.h" + +struct HardwareS { + size_t maxSubEvtSize; +}; + +#include "hardware.h" + +size_t Hardware_maxSubEvtSize(const Hardware *my) +{ + return my->maxSubEvtSize; +} + +#include + +int Hardware_inSpill(const Hardware *my) +{ + return 0; +} + +Hardware *newHardware(void) +{ + Hardware *my; + Param *param; + + my = allocMem(sizeof(Hardware)); + my->maxSubEvtSize = SubEvt_hdrSize() + 401 * sizeof(UInt4); + + param = allocMem(sizeof(Param)); + conParam(param, "param.tcl"); + printf("%d\n", Param_getVal(param, "soft", "size")); + desParam(param); + return my; +} + +void deleteHardware(Hardware *my) +{ + freeMem(my); +} + +void Hardware_waitForTrigger(const Hardware *my, void *subEvt) +{ + struct timespec tS, *t = &tS; + static UInt4 trigNr = 0; + + SubEvt_setSize(subEvt, SubEvt_hdrSize()); + SubEvt_setDecoding(subEvt, SubEvtDecoding_32bitData); + SubEvt_setId(subEvt, SubEvtId_test1); + SubEvt_setTrigNr(subEvt, trigNr++); + + t->tv_sec = 0; + t->tv_nsec = 100000000; + nanosleep(t, NULL); +} + +void Hardware_readout(const Hardware *my, void *subEvt) +{ + UInt4 *data = SubEvt_data(subEvt); + UInt4 *first = data; + + *data++ = 0x55aa00FF; + *data++ = 0x55aa00FF; + *data++ = 0x55aa00FF; +#if 0 + data += (int) ((100.0 * rand()) / RAND_MAX); + data += (int) ((100.0 * rand()) / RAND_MAX); + data += (int) ((100.0 * rand()) / RAND_MAX); + data += (int) ((100.0 * rand()) / RAND_MAX); +#endif + + SubEvt_setSize(subEvt, SubEvt_size(subEvt) + sizeof(UInt4) * (data - first)); +} diff --git a/hadaq/ipc_basis.h b/hadaq/ipc_basis.h new file mode 100644 index 0000000..af9964a --- /dev/null +++ b/hadaq/ipc_basis.h @@ -0,0 +1,177 @@ +/* ------------------------------------------------------------ + - Header File for the Image Processing Card (Basis-Module) - + ------------------------------------------------------------ + + Date: 20/01/1999 Author: Markus Petri + + Remarks: + + ~ + ~ + ~ +*/ +#if !defined(IPC_BASIS) +#define IPC_BASIS + +#define BASIS_ADRESSE 0xffc00000 +#define BASIS_ADDR 0x00000000 +#define IPC_BASIS_ADR 0x00c00000 +#define LVL2_OFFSET 0x60000 +#define LUT5_OFFSET 0x40000 + +#define RC3_ACCESS_OFF 0x04022 +#define RC3_ACCESS_ON 0x04020 +#define RC3_FIFO_RESET 0x04008 +#define RC3_SHOWER_MODE 0x04006 +#define RC3_TEST_MODE 0x04004 +#define RC3_CONF_MODE 0x04002 +#define RC3_STANDBY_MODE 0x04000 + +#define ADDON_ACCESS_OFF 0x02012 +#define ADDON_ACCESS_ON 0x02010 +#define ADDON_FIFO_RESET 0x02108 +#define ADDON_SHOWER_MODE 0x02106 +#define ADDON_TEST_MODE 0x02104 +#define ADDON_CONF_MODE 0x02102 +#define ADDON_STANDBY_MODE 0x02100 + +#define LVL2_ACCESS_OFF 0x0101e +#define LVL2_ACCESS_ON 0x0101c +#define LVL2_STAT_READ 0x0100c +#define LVL2_STAT_WRITE 0x0100a +#define LVL2_VME_RCLK 0x01008 +#define LVL2_SHOWER_MODE 0x01006 +#define LVL2_TEST_MODE 0x01004 +#define LVL2_CONF_MODE 0x01002 +#define LVL2_STANDBY_MODE 0x01000 + +#define PEDAS_ACCESS_OFF 0x00e02 +#define PEDAS_ACCESS_ON 0x00e00 +#define PEDAS_FIFO_RESET 0x00c08 +#define PEDAS_SHOWER_MODE 0x00c06 +#define PEDAS_TEST_MODE 0x00c04 +#define PEDAS_CONF_MODE 0x00c02 +#define PEDAS_STANDBY_MODE 0x00c00 + +#define RC1_ACCESS_OFF 0x00a12 +#define RC1_ACCESS_ON 0x00a10 +#define RC1_FIFO_RCLK 0x00a0c +#define RC1_VME_LVL2 0x00a0a +#define RC1_FIFO_RESET 0x00a08 +#define RC1_SHOWER_MODE 0x00a06 +#define RC1_TEST_MODE 0x00a04 +#define RC1_CONF_MODE 0x00a02 +#define RC1_STANDBY_MODE 0x00a00 + +#define ALT3456_CONF_ON 0x0081c +#define ALT3456_CONF_OFF 0x0081a +#define ALT3456_CONF_REG 0x00818 + +#define ALT12_CONF_ON 0x00816 +#define ALT12_CONF_OFF 0x00814 +#define ALT12_CONF_REG 0x00812 + +#define RESET_ADDON 0x00806 +#define RESET_LVL1 0x00804 +#define RESET_PEDAS 0x00802 +#define RESET_LUTS 0x00800 + +#define ID_CTR_ACCESS_ON 0x00600 +#define ID_CTR_ACCESS_OFF 0x00200 + +#define ID_CTR_SHOWER_MODE 0x000c0 +#define ID_CTR_TEST_MODE 0x000a0 +#define ID_CTR_CONF_MODE 0x00080 +#define ID_CTR_STANDBY_MODE 0x00060 +#define ID_CTR_SW_TO_LUT12 0x00040 +#define ID_CTR_SW_TO_LUT34 0x00020 + +#define LUT_CTR_STANDBY_MODE 0x00000 +#define LUT_CTR_CONF_MODE 0x00002 +#define LUT_CTR_TEST_MODE 0x00004 +#define LUT_CTR_SHOWER_MODE 0x00006 +#define LUT_CTR_REG_ADDR_A 0x00008 +#define LUT_CTR_REG_ADDR_B 0x0000a +#define LUT_CTR_REG_DATA 0x0000c +#define LUT1_WE 0x0000e /* bzw. LUT3_WE */ +#define LUT2_WE 0x00010 /* bzw. LUT4_WE */ +#define LUT12_WE 0x00012 /* bzw. LUT34_WE */ +#define LUT1234_READ 0x00014 + +/* -- Operational Modes of the Image Processing Card -- + +These codes/flags are just used by the controlling C-software + + - NORMAL_MODE : all address lines are exclusively decoded by the + VME-Controller. + + - LUT_CONF_MODE : A9-A1 address lines are map to the ID-Controller + and are used to control the ID-Controller and the + Look up Table #1 through #4 + + - xxxxxxxxx : +*/ + +#define STANDBY_MODE 0x0 +#define CONF_MODE 0x1 +#define TEST_MODE 0x2 +#define SHOWER_MODE 0x3 +#define LUT_CONF_MODE 0x4 +#define LUT_TEST_MODE 0x5 +#define LUT_STANDBY_MODE 0x6 +#define RESET 0x7 +#define NO_MODE_CHG 0x77 + +#define TEST_VECTOR_SIZE 100000 +#define LUT5_SIZE 524287 +#define LUT1234_SIZE 131071 +#define LVL2_SIZE 65536 +#define EVENT_SIZE 388 +#define NUM_RB_FIFOS 2 +#define NUM_COLS_RB_FIFO 8 + +#define FILENAME_LENGTH 30 +#define CONF_VECTOR_SIZE 750000 +#define COL_WIDTH 3 +#define COLS_ALT3456 91 +#define COLS_ALT12 60 + +#define ALTERA_3456 1 +#define ALTERA_12 0 + +#define TDAT_RANDOM 1 +#define TDAT_ZERO 2 + +#define INTACTIVE 1 +#define BATCH 0 + +#define SRAM_A 0 +#define SRAM_B 1 +#define SRAM_OLD 2 + +#define POS 1 +#define NEG 0 + +#define SRAM_ACCESS 0 +#define BUFF_ACCESS 1 + +#define D_LAYS 3 +#define D_ROWS 32 +#define D_COLS 16 +#endif + + + + + + + + + + + + + + + + diff --git a/hadaq/memnet.c b/hadaq/memnet.c new file mode 100644 index 0000000..912ea37 --- /dev/null +++ b/hadaq/memnet.c @@ -0,0 +1,125 @@ +static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/memnet.c,v 6.1 1999-08-31 10:37:24 muench Exp $"; + +#define _XOPEN_SOURCE +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "shmtrans.h" +#include "nettrans.h" + +#include "worker.h" + +static jmp_buf terminateJmp; + +void sigHandler(int sig) +{ + longjmp(terminateJmp, sig); +} + +static int min(int a, int b) +{ + return a < b ? a : b; +} + +static void usage(const char *progName) +{ + msglog(LOG_ERR, "Usage: %s -o outPath -w bandwidth\n", progName); + msglog(LOG_ERR, "Usage: [-p priority]\n"); + msglog_usage(); +} + +int main(int argc, char *argv[]) +{ + int i; + int priority; + char *outPath; + int bandWidth; + int isStandalone; + Worker *worker; + NetTrans *netTrans; + ShmTrans *shmTrans; + size_t queueSize = 100 * 1024; + int exitStat; + + msglog_setlevel(argv[0], "info"); + outPath = "-"; + bandWidth = -1; + priority = 0; + isStandalone = 1; + while ((i = getopt(argc, argv, "aw:o:p:v:")) != -1) { + switch (i) { + case 'a': + isStandalone = 0; + break; + case 'w': + bandWidth = atoi(optarg); + break; + case 'o': + outPath = optarg; + break; + case 'p': + priority = atoi(optarg); + break; + case 'v': + if (msglog_setlevel(argv[0], optarg) == 1) { + break; + } /* FALLTHROUGH to default */ + default: + usage(argv[0]); + exit(EXIT_FAILURE); + break; + } + } + if (strcmp(outPath, "-") == 0 || bandWidth == -1) { + usage(argv[0]); + exit(EXIT_FAILURE); + } + if (NULL == (worker = Worker_initBegin(argv[0], sigHandler, priority, isStandalone))) { + msglog(LOG_ERR, "initializing working process: %s\n"), strerror(errno); + exitStat = EXIT_FAILURE; + goto bailOut0; + } + if (NULL == (shmTrans = ShmTrans_create("subevtqueue", 2 * queueSize))) { + msglog(LOG_ERR, + "creating shared memory \"subevtqueue\": %s\n"), strerror(errno); + exitStat = EXIT_FAILURE; + goto bailOut1; + } + if (NULL == (netTrans = NetTrans_open(outPath, bandWidth, worker))) { + msglog(LOG_ERR, + "opening network transport %s: %s\n", outPath, strerror(errno)); + exitStat = EXIT_FAILURE; + goto bailOut2; + } + Worker_initEnd(worker); + + while (setjmp(terminateJmp) == 0) { + void *hadTuQueue; + + Worker_dump(worker, 1); + + hadTuQueue = ShmTrans_recv(shmTrans); + NetTrans_send(netTrans, hadTuQueue); + ShmTrans_free(shmTrans); + } + exitStat = EXIT_SUCCESS; + + bailOut3: + NetTrans_close(netTrans); + bailOut2: + ShmTrans_remove(shmTrans); + bailOut1: + Worker_fini(worker); + bailOut0: + exit(exitStat); +} diff --git a/hadaq/mman.c b/hadaq/mman.c new file mode 100644 index 0000000..eb4f9b8 --- /dev/null +++ b/hadaq/mman.c @@ -0,0 +1,127 @@ + +#define _XOPEN_SOURCE +#include + +#ifndef _POSIX_SHARED_MEMORY_OBJECTS +static char *rcsId = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/Attic/mman.c,v 6.1 1999-08-31 10:37:24 muench Stab $"; + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mman.h" + +static int ourShmFlg; +static size_t ourShmLen; +static char ourShmPath[_POSIX_PATH_MAX]; + +static char *name2Path(char *path, const char *name) +{ + char *prefix; + + if (NULL == (prefix = getenv("OUR_MMAN_PREFIX"))) { + prefix = ""; + } + if (strlen(prefix) + strlen(name) + 1 > _POSIX_PATH_MAX) { + errno = ENAMETOOLONG; + path = NULL; + } else { + strcpy(path, prefix); + strcat(path, name); + } + return path; +} + +int MMAN_shm_open(const char *name, int oflags, mode_t mode) +{ + int fd; + + if (NULL == name2Path(ourShmPath, name)) { + return -1; + } + if (0 > (fd = open(ourShmPath, oflags, mode))) { + return -1; + } + ourShmFlg = mode; /* BUGBUG This depends on ipc modes having + the same semantics as file modes */ + if ((oflags & O_CREAT) != 0) { + ourShmFlg |= IPC_CREAT; + } + if ((oflags & O_EXCL) != 0) { + ourShmFlg |= IPC_EXCL; + } + return fd; +} + +int MMAN_ftruncate(int fd, off_t size) +{ + key_t key; + + if ((key_t) - 1 == (key = ftok(ourShmPath, 'A'))) { + return -1; + } + if (0 > shmget(key, size, ourShmFlg)) { + return -1; + } + return 0; +} + +void *MMAN_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off) +{ + void *p; + int shmflg; + int shmid; + key_t key; + + if ((key_t) - 1 == (key = ftok(ourShmPath, 'A'))) { + return MAP_FAILED; + } + if (0 > (shmid = shmget(key, len, 0))) { + return MAP_FAILED; + } + shmflg = 0; + if ((flags & MAP_SHARED) == 0) { + shmflg |= IPC_PRIVATE; + } + if ((prot & PROT_WRITE) == 0) { + shmflg |= SHM_RDONLY; + } + if ((void *) -1 == (p = shmat(shmid, addr, shmflg))) { + return MAP_FAILED; + } + return p; +} + +int MMAN_munmap(void *addr, size_t len) +{ + ourShmLen = len; + return shmdt(addr); +} + +int MMAN_shm_unlink(const char *name) +{ + int retVal; + int shmid; + key_t key; + + retVal = 0; + if (NULL == name2Path(ourShmPath, name) + || (key_t) - 1 == (key = ftok(ourShmPath, 'A')) + || 0 > (shmid = shmget(key, ourShmLen, 0)) + || 0 > shmctl(shmid, IPC_RMID, NULL) + ) { + retVal = -1; + } + if (0 > unlink(ourShmPath)) { + retVal = -1; + } + return retVal; +} + +#endif diff --git a/hadaq/mman.h b/hadaq/mman.h new file mode 100644 index 0000000..1ad6ef8 --- /dev/null +++ b/hadaq/mman.h @@ -0,0 +1,42 @@ +#ifndef OUR_MMAN_H +#define OUR_MMAN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* redefine function names to prevent name clashes */ +/* BUGBUG makes ftruncate,mmap,munmap unusable for anything else */ +/* BUGBUG shm_open must be called directly before ftruncate */ +/* for the same shm */ +/* BUGBUG shm_open must be called directly before ftruncate */ +/* ftruncate directly before mmap for the same shm */ +/* BUGBUG munmap must be called directly before shm_unlink */ +/* for the same shm */ +#define shm_open MMAN_shm_open +#define ftruncate MMAN_ftruncate +#define mmap MMAN_mmap +#define munmap MMAN_munmap +#define shm_unlink MMAN_shm_unlink + +#define MAP_FAILED ((void *)-1) +#define PROT_READ 4 /* BUGBUG this three must correspond to the */ +#define PROT_WRITE 2 /* file access modes of the */ +#define PROT_EXEC 1 /* operating system */ +#define MAP_SHARED 4 + + int MMAN_shm_open(const char *name, int oflags, mode_t mode); + int MMAN_ftruncate(int fd, off_t size); + void *MMAN_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off); + int MMAN_munmap(void *addr, size_t len); + int MMAN_shm_unlink(const char *name); + +#ifdef __cplusplus +} + +#endif +#endif diff --git a/hadaq/netmem.c b/hadaq/netmem.c new file mode 100644 index 0000000..48b7b35 --- /dev/null +++ b/hadaq/netmem.c @@ -0,0 +1,130 @@ +static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/netmem.c,v 6.1 1999-08-31 10:37:24 muench Exp $"; + +#define _XOPEN_SOURCE +#include + +#include +#include +#include +#include +#include + +#include + +#include "worker.h" +#include "nettrans.h" +#include "shmtrans.h" + +static jmp_buf terminateJmp; + +void sigHandler(int sig) +{ + longjmp(terminateJmp, sig); +} + +static void usage(const char *progName) +{ + msglog(LOG_ERR, "Usage: %s -m nrOfMsgs [-p priority]\n", progName); + msglog_usage(); +} + +int main(int argc, char *argv[]) +{ + int i; + Worker *worker; + NetTrans **netTrans; + ShmTrans **shmTrans; + void **hadTu; + size_t *hadTuSize; + int priority; + int isStandalone; + int nrOfMsgs; + size_t queueSize; + + msglog_setlevel(argv[0], "info"); + priority = 0; + isStandalone = 1; + nrOfMsgs = 0; + queueSize = 100 * 1024; + + while ((i = getopt(argc, argv, "am:p:v:")) != -1) { + switch (i) { + case 'a': + isStandalone = 0; + break; + case 'm': + nrOfMsgs = atoi(optarg); + break; + case 'p': + priority = atoi(optarg); + break; + case 'v': + if (msglog_setlevel(argv[0], optarg) == 1) { + break; + } /* FALLTHROUGH to default */ + default: + usage(argv[0]); + exit(EXIT_FAILURE); + break; + } + } + if (nrOfMsgs == 0) { + msglog(LOG_ERR, "missing nrOfMsgs\n"); + usage(argv[0]); + exit(EXIT_FAILURE); + } + netTrans = allocMem(nrOfMsgs * sizeof(NetTrans *)); + shmTrans = allocMem(nrOfMsgs * sizeof(ShmTrans *)); + hadTu = allocMem(nrOfMsgs * sizeof(void *)); + hadTuSize = allocMem(nrOfMsgs * sizeof(size_t)); + + if (NULL == (worker = Worker_initBegin(argv[0], sigHandler, priority, isStandalone))) { + msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, strerror(errno)); + exit(EXIT_FAILURE); + } + for (i = 0; i < nrOfMsgs; i++) { + char buf[80]; + + sprintf(buf, "0:%d", i + 50); + netTrans[i] = NetTrans_create(buf, 0, worker); + + sprintf(buf, "netqueue%d", i); + shmTrans[i] = ShmTrans_open(buf, 2 * queueSize); + + hadTu[i] = NULL; + hadTuSize[i] = queueSize - HadTu_hdrSize(); + } + Worker_initEnd(worker); + + if (setjmp(terminateJmp) == 0) { + while (1) { + long msgsCompleted; + + Worker_dump(worker, 1); + + for (i = 0; i < nrOfMsgs; i++) { + if (hadTu[i] == NULL) { + ShmTrans_requestSpace(shmTrans[i]); + hadTu[i] = ShmTrans_tryAlloc(shmTrans[i], hadTuSize[i]); + } + } + + msgsCompleted = NetTrans_multiRecv(netTrans, hadTu, hadTuSize, nrOfMsgs); + + for (i = 0; i < nrOfMsgs; i++) { + if ((msgsCompleted & (1 << i)) != 0) { + ShmTrans_send(shmTrans[i]); + hadTu[i] = NULL; + } + } + } + } + Worker_dump(worker, 0); + + for (i = 0; i < nrOfMsgs; i++) { + ShmTrans_remove(shmTrans[i]); + NetTrans_remove(netTrans[i]); + } + Worker_fini(worker); + exit(EXIT_SUCCESS); +} diff --git a/hadaq/nettrans.c b/hadaq/nettrans.c new file mode 100644 index 0000000..0a0e1b0 --- /dev/null +++ b/hadaq/nettrans.c @@ -0,0 +1,300 @@ +static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/nettrans.c,v 6.1 1999-08-31 10:37:24 muench Exp $"; + +#define _XOPEN_SOURCE_EXTENDED +#include +#include "grmblfx.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "latm.h" + +#include "hadtu.h" +#include "pkt.h" + +#include "worker.h" +#include "nettrans.h" + +static int min(int a, int b) +{ + return a < b ? a : b; +} + +NetTrans *NetTrans_create(const char *name, size_t bandwidth, Worker *worker) +{ + NetTrans *my; + char *vpi; + char *vci; + LAtmAttr lAtmAttrS, *lAtmAttr = &lAtmAttrS; + char buf[80]; + + my = allocMem(sizeof(NetTrans)); + + strcpy(buf, name); + + if (NULL == (vpi = strtok(buf, ":"))) { + return NULL; + } + if (NULL == (vci = strtok(NULL, ":"))) { + return NULL; + } + lAtmAttr->aal = 5; + lAtmAttr->vpi = atoi(vpi); + lAtmAttr->vci = atoi(vci); + lAtmAttr->peakBandwidth = bandwidth; + + msglog(LOG_DEBUG, "aal: %d; vpi: %d; vci: %d; bandwidth: %d\n", + lAtmAttr->aal, lAtmAttr->vpi, lAtmAttr->vci, lAtmAttr->peakBandwidth); + + if (0 > (my->fd = lAtmOpen("/dev/fa0", O_RDONLY))) { + return NULL; + } + if (0 > lAtmBind(my->fd, lAtmAttr)) { + lAtmClose(my->fd); + return NULL; + } + my->mtuSize = 8192; + + my->pkt = allocMem(my->mtuSize); + my->seqNr = 0; + my->offset = 0; + + my->pktsSent = NULL; + my->msgsSent = NULL; + my->bytesSent = NULL; + sprintf(buf, "%s_%s", name, "pktsReceived"); + my->pktsReceived = Worker_addStatistic(worker, buf); + sprintf(buf, "%s_%s", name, "pktsDiscarded"); + my->pktsDiscarded = Worker_addStatistic(worker, buf); + sprintf(buf, "%s_%s", name, "msgsDiscarded"); + my->msgsDiscarded = Worker_addStatistic(worker, buf); + sprintf(buf, "%s_%s", name, "msgsReceived"); + my->msgsReceived = Worker_addStatistic(worker, buf); + + return my; +} + +NetTrans *NetTrans_open(const char *name, size_t bandwidth, Worker *worker) +{ + NetTrans *my; + char *vpi; + char *vci; + LAtmAttr lAtmAttrS, *lAtmAttr = &lAtmAttrS; + char buf[80]; + + my = allocMem(sizeof(NetTrans)); + + strcpy(buf, name); + + if (NULL == (vpi = strtok(buf, ":"))) { + return NULL; + } + if (NULL == (vci = strtok(NULL, ":"))) { + return NULL; + } + lAtmAttr->aal = 5; + lAtmAttr->vpi = atoi(vpi); + lAtmAttr->vci = atoi(vci); + lAtmAttr->peakBandwidth = bandwidth; + + msglog(LOG_DEBUG, "aal: %d; vpi: %d; vci: %d; bandwidth: %d\n", + lAtmAttr->aal, lAtmAttr->vpi, lAtmAttr->vci, lAtmAttr->peakBandwidth); + + if (0 > (my->fd = lAtmOpen("/dev/fa0", O_WRONLY))) { + return NULL; + } + if (0 > lAtmConnect(my->fd, lAtmAttr)) { + lAtmClose(my->fd); + return NULL; + } + my->mtuSize = 8192; + + my->pkt = allocMem(my->mtuSize); + my->seqNr = 0; + my->offset = 0; + + sprintf(buf, "%s_%s", name, "pktsSent"); + my->pktsSent = Worker_addStatistic(worker, buf); + sprintf(buf, "%s_%s", name, "msgsSent"); + my->msgsSent = Worker_addStatistic(worker, buf); + sprintf(buf, "%s_%s", name, "bytesSent"); + my->bytesSent = Worker_addStatistic(worker, buf); + my->pktsReceived = NULL; + my->pktsDiscarded = NULL; + my->msgsDiscarded = NULL; + my->msgsReceived = NULL; + + return my; +} + +void NetTrans_close(NetTrans *my) +{ + freeMem(my->pkt); + lAtmClose(my->fd); + freeMem(my); +} + +void NetTrans_remove(NetTrans *my) +{ + NetTrans_close(my); +} + +int NetTrans_send(NetTrans *my, void *hadTu) +{ + int i; + int msgIsComplete; + + Pkt_setDecoding(my->pkt, PktDecoding_default); + Pkt_setId(my->pkt, PktId_bom); + + i = 0; + msgIsComplete = 0; + do { + size_t payload; + + payload = min(my->mtuSize - Pkt_hdrSize(), HadTu_size(hadTu) - i); + + memcpy(Pkt_data(my->pkt), (char *) hadTu + i, payload); + Pkt_setSize(my->pkt, payload + Pkt_hdrSize()); + + i += payload; + if (i == HadTu_size(hadTu)) { + Pkt_setId(my->pkt, Pkt_id(my->pkt) | PktId_eom); + msgIsComplete = 1; + (*my->msgsSent)++; + } + Pkt_setSeqNr(my->pkt, my->seqNr++); + + if (Pkt_size(my->pkt) != lAtmSend(my->fd, my->pkt, Pkt_size(my->pkt))) { + return -1; + } + (*my->pktsSent)++; + (*my->bytesSent) += Pkt_size(my->pkt); + Pkt_setId(my->pkt, Pkt_id(my->pkt) & ~PktId_bom); + } while (!msgIsComplete); + return 0; +} + +static int assembleMsg(NetTrans *my, void *hadTu, size_t size) +{ + int retVal; + int i; + int pktIsOk; + int n; + void *pkt; + UInt4 pktHdrSize; + UInt4 pktSize; + UInt4 pktId; + UInt4 pktSeqNr; + + /* BUGBUG quickhack for flushing the input data. Properly in one of */ + /* the parent functions this should be handled, but this would need */ + /* better sunc. between nettrans & shmtrans */ + if (hadTu == NULL) { + if (0 > (n = lAtmRecv(my->fd, my->pkt, my->mtuSize))) { + abort(); + } + my->offset = 0; + (*my->pktsDiscarded)++; + return 0; + } + /* for in situ assembly of the pkts we receive the data "a little bit in + front of the beginning", save that data, and copy it back. CAUTION: + Pkt_hdrSize() bytes in front of hadTu must be accessible! */ + pktHdrSize = Pkt_hdrSize(); + pkt = (char *) hadTu + my->offset - pktHdrSize; + memcpy(my->pkt, pkt, pktHdrSize); + + if (0 > (n = lAtmRecv(my->fd, pkt, my->mtuSize))) { + memcpy(pkt, my->pkt, pktHdrSize); + abort(); + } + if (n != Pkt_size(pkt)) { + memcpy(pkt, my->pkt, pktHdrSize); + abort(); + } + (*my->pktsReceived)++; + pktSize = n; + pktId = Pkt_id(pkt); + pktSeqNr = Pkt_seqNr(pkt); + memcpy(pkt, my->pkt, pktHdrSize); + + if ((pktId & PktId_bom) != 0) { /* start of new msg */ + if (my->offset != 0) { + (*my->msgsDiscarded)++; + (*my->pktsDiscarded)++; + my->offset = 0; + pktIsOk = 0; + } else { + my->seqNr = pktSeqNr; + pktIsOk = 1; + } + } else { + if (my->seqNr != pktSeqNr) { + (*my->pktsDiscarded)++; + my->offset = 0; + pktIsOk = 0; + } else { + pktIsOk = 1; + } + } + if (pktIsOk) { + my->seqNr++; + + if ((pktId & PktId_eom) == 0) { + my->offset += pktSize - pktHdrSize;; + retVal = 0; + } else { + (*my->msgsReceived)++; + my->offset = 0; + retVal = 1; + } + } else { + retVal = 0; + } + return retVal; +} + +void NetTrans_recv(NetTrans *my, void *hadTu, size_t size) +{ + while (!assembleMsg(my, hadTu, size)) { + } +} + +unsigned long NetTrans_multiRecv(NetTrans *my[], void *hadTu[], size_t size[], int nrOfMsgs) +{ + int i; + unsigned long msgIsComplete; + fd_set fdSetS, *fdSet = &fdSetS; + + assert((1L << (nrOfMsgs - 1)) != 0); /* is long long enough for result */ + + msgIsComplete = 0; + + do { + FD_ZERO(fdSet); + for (i = 0; i < nrOfMsgs; i++) { + FD_SET(my[i]->fd, fdSet); + } + if (0 > (getdtablesize(), fdSet, NULL, NULL, NULL)) { + abort(); + } + for (i = 0; i < nrOfMsgs; i++) { + if (FD_ISSET(my[i]->fd, fdSet)) { + if (assembleMsg(my[i], hadTu[i], size[i])) { + msgIsComplete |= 1 << i; + } + } + } + } while (0 && msgIsComplete == 0); + + return msgIsComplete; +} diff --git a/hadaq/nettrans.h b/hadaq/nettrans.h new file mode 100644 index 0000000..30eb0b6 --- /dev/null +++ b/hadaq/nettrans.h @@ -0,0 +1,34 @@ +#ifndef NETTRANS_H +#define NETTRANS_H + +#include + +#include "worker.h" +#include "hadtu.h" + +typedef struct NetTransS { + char name[512]; + int fd; + size_t mtuSize; + UInt4 *pkt; + UInt4 seqNr; + size_t offset; + unsigned long *pktsSent; + unsigned long *msgsSent; + unsigned long *bytesSent; + unsigned long *pktsReceived; + unsigned long *pktsDiscarded; + unsigned long *msgsDiscarded; + unsigned long *msgsReceived; +} NetTrans; + +NetTrans *NetTrans_create(const char *name, size_t bandwidth, Worker * worker); +NetTrans *NetTrans_open(const char *name, size_t bandwidth, Worker * worker); +void NetTrans_close(NetTrans *my); +void NetTrans_remove(NetTrans *my); + +int NetTrans_send(NetTrans *my, void *hadTu); +void NetTrans_recv(NetTrans *my, void *hadTu, size_t size); +unsigned long NetTrans_multiRecv(NetTrans *my[], void *hadTu[], size_t size[], int nrOfMsgs); + +#endif diff --git a/hadaq/online.c b/hadaq/online.c new file mode 100644 index 0000000..9d31318 --- /dev/null +++ b/hadaq/online.c @@ -0,0 +1,73 @@ + +#define _GNU_SOURCE + +#include +#include +#include + +#include + +#include "evt.h" +#include "online.h" + +static void *ourEvt; + +extern void daqprog_1(); + +static struct timeval timeout = +{0, 0}; + +initOnline() +{ + register SVCXPRT *transp; + + (void) pmap_unset(DAQPROG, DAQVERS); + + transp = svctcp_create(RPC_ANYSOCK, 0, 0); + if (transp == NULL) { + fprintf(stderr, "cannot create tcp service."); + exit(1); + } + if (!svc_register(transp, DAQPROG, DAQVERS, daqprog_1, IPPROTO_TCP)) { + fprintf(stderr, "unable to register (DAQPROG, DAQVERS, tcp)."); + exit(1); + } + return 0; +} + +void Evt_online(void *evt) +{ + fd_set readfdset; + static int tsize = 0; + + if (tsize == 0) { + tsize = getdtablesize(); + } + readfdset = svc_fdset; + + switch (select(tsize, &readfdset, (fd_set *) NULL, (fd_set *) NULL, &timeout)) { + case -1: + if (errno != EBADF) { + perror("select"); + return; + } + break; + case 0: + break; + default: + ourEvt = evt; + svc_getreqset(&readfdset); + break; + } + return; +} + +rpcevt *onlineevt_1(void *dummy, CLIENT * cl) +{ + static rpcevt result; + + result.rpcevt_len = Evt_paddedSize(ourEvt); + result.rpcevt_val = (char *) ourEvt; + + return &result; +} diff --git a/hadaq/online.x b/hadaq/online.x new file mode 100644 index 0000000..b2ddc1c --- /dev/null +++ b/hadaq/online.x @@ -0,0 +1,6 @@ +typedef opaque rpcevt<>; +program DAQPROG { + version DAQVERS { + rpcevt ONLINEEVT(void) = 1; + } = 1; +} = 0x20000001; diff --git a/hadaq/param.c b/hadaq/param.c new file mode 100644 index 0000000..fb5c27c --- /dev/null +++ b/hadaq/param.c @@ -0,0 +1,64 @@ +static char rcsId[] = "$Id: param.c,v 6.1 1999-08-31 10:37:24 muench Exp $"; + +#include + +#include +#include + +#include + +#include "param.h" + +int conParam(Param *my, const char *fileName) +{ + int i; + FILE *f; + char buf[132 + 1]; + + if (NULL == (f = fopen(fileName, "r"))) { + msglog(LOG_ERR, "opening param file: %s\n", strerror(errno)); + return -1; + } + for ( + i = 0; + i < PARAM_MAXNVALS + && NULL != fgets(buf, 132, f); + i++ + ) { + if (buf[0] != '#') { + sscanf(buf, "set%s%d", &my->name[i], &my->val[i]); + } + } + if (i == PARAM_MAXNVALS) { + msglog(LOG_WARNING, + "More than %d Parameter in file, ignoring the rest\n", PARAM_MAXNVALS); + } + fclose(f); +} + +void desParam(Param *my) +{ +} + +long Param_getVal(const Param *my, const char *name, const char *idx) +{ + int i; + int val; + char fullName[PARAM_MAXNAMELEN]; + + sprintf(fullName, "%s(%s)", name, idx); + for ( + i = 0; + i < PARAM_MAXNVALS + && strcmp(my->name[i], fullName) != 0; + i++ + ) { + } + if (i == PARAM_MAXNVALS) { + val = 0; + msglog(LOG_WARNING, "Parameter %s not found, defaulting to 0\n", fullName); + } else { + val = my->val[i]; + } + return val; +} diff --git a/hadaq/param.h b/hadaq/param.h new file mode 100644 index 0000000..bf78cf6 --- /dev/null +++ b/hadaq/param.h @@ -0,0 +1,17 @@ +#ifndef PARAM_H +#define PARAM_H + +#define PARAM_MAXNVALS 1024 +#define PARAM_MAXNAMELEN 32 + +typedef struct ParamS { + int nVals; + char name[PARAM_MAXNVALS][PARAM_MAXNAMELEN]; + long val[PARAM_MAXNVALS]; +} Param; + +int conParam(Param *my, const char *fileName); +void desParam(Param *my); +long Param_getVal(const Param *my, const char *name, const char *idx); + +#endif diff --git a/hadaq/param.tcl b/hadaq/param.tcl new file mode 100644 index 0000000..60fd674 --- /dev/null +++ b/hadaq/param.tcl @@ -0,0 +1,162 @@ +set soft(size) 1024 + +set dtu0(cardbase) 1148190720 ;# 0x44700000 +set dtu0(deadtime) 10 + +set tdc3(cardbase) 3992977408 ;# 0xee000000 +set tdc0(threshold00) 0 +set tdc0(threshold01) 0 +set tdc0(threshold02) 0 +set tdc0(threshold03) 0 +set tdc0(threshold04) 0 +set tdc0(threshold05) 0 +set tdc0(threshold06) 0 +set tdc0(threshold07) 0 +set tdc0(threshold08) 0 +set tdc0(threshold09) 0 +set tdc0(threshold10) 0 +set tdc0(threshold11) 0 +set tdc0(threshold12) 0 +set tdc0(threshold13) 0 +set tdc0(threshold14) 0 +set tdc0(threshold15) 0 +set tdc0(threshold16) 0 +set tdc0(threshold17) 0 +set tdc0(threshold18) 0 +set tdc0(threshold19) 0 +set tdc0(threshold20) 0 +set tdc0(threshold21) 0 +set tdc0(threshold22) 0 +set tdc0(threshold23) 0 +set tdc0(threshold24) 0 +set tdc0(threshold25) 0 +set tdc0(threshold26) 0 +set tdc0(threshold27) 0 +set tdc0(threshold28) 0 +set tdc0(threshold29) 0 +set tdc0(threshold30) 0 +set tdc0(threshold31) 0 +set tdc0(range) 255 +set tdc0(voltage) 254 +set tdc0(offset) 0 + +set tdc0(cardbase) 3993108480 ;# 0xee000000 +set tdc1(threshold00) 0 +set tdc1(threshold01) 0 +set tdc1(threshold02) 0 +set tdc1(threshold03) 0 +set tdc1(threshold04) 0 +set tdc1(threshold05) 0 +set tdc1(threshold06) 0 +set tdc1(threshold07) 0 +set tdc1(threshold08) 0 +set tdc1(threshold09) 0 +set tdc1(threshold10) 0 +set tdc1(threshold11) 0 +set tdc1(threshold12) 0 +set tdc1(threshold13) 0 +set tdc1(threshold14) 0 +set tdc1(threshold15) 0 +set tdc1(threshold16) 0 +set tdc1(threshold17) 0 +set tdc1(threshold18) 0 +set tdc1(threshold19) 0 +set tdc1(threshold20) 0 +set tdc1(threshold21) 0 +set tdc1(threshold22) 0 +set tdc1(threshold23) 0 +set tdc1(threshold24) 0 +set tdc1(threshold25) 0 +set tdc1(threshold26) 0 +set tdc1(threshold27) 0 +set tdc1(threshold28) 0 +set tdc1(threshold29) 0 +set tdc1(threshold30) 0 +set tdc1(threshold31) 0 +set tdc1(range) 255 +set tdc1(voltage) 254 +set tdc1(offset) 0 + +set tdc1(cardbase) 3993239552 ;# 0xee000000 +set tdc2(threshold00) 0 +set tdc2(threshold01) 0 +set tdc2(threshold02) 0 +set tdc2(threshold03) 0 +set tdc2(threshold04) 0 +set tdc2(threshold05) 0 +set tdc2(threshold06) 0 +set tdc2(threshold07) 0 +set tdc2(threshold08) 0 +set tdc2(threshold09) 0 +set tdc2(threshold10) 0 +set tdc2(threshold11) 0 +set tdc2(threshold12) 0 +set tdc2(threshold13) 0 +set tdc2(threshold14) 0 +set tdc2(threshold15) 0 +set tdc2(threshold16) 0 +set tdc2(threshold17) 0 +set tdc2(threshold18) 0 +set tdc2(threshold19) 0 +set tdc2(threshold20) 0 +set tdc2(threshold21) 0 +set tdc2(threshold22) 0 +set tdc2(threshold23) 0 +set tdc2(threshold24) 0 +set tdc2(threshold25) 0 +set tdc2(threshold26) 0 +set tdc2(threshold27) 0 +set tdc2(threshold28) 0 +set tdc2(threshold29) 0 +set tdc2(threshold30) 0 +set tdc2(threshold31) 0 +set tdc2(range) 255 +set tdc2(voltage) 254 +set tdc2(offset) 0 + +set tdc2(cardbase) 3993370624 ;# 0xee000000 +set tdc3(threshold00) 0 +set tdc3(threshold01) 0 +set tdc3(threshold02) 0 +set tdc3(threshold03) 0 +set tdc3(threshold04) 0 +set tdc3(threshold05) 0 +set tdc3(threshold06) 0 +set tdc3(threshold07) 0 +set tdc3(threshold08) 0 +set tdc3(threshold09) 0 +set tdc3(threshold10) 0 +set tdc3(threshold11) 0 +set tdc3(threshold12) 0 +set tdc3(threshold13) 0 +set tdc3(threshold14) 0 +set tdc3(threshold15) 0 +set tdc3(threshold16) 0 +set tdc3(threshold17) 0 +set tdc3(threshold18) 0 +set tdc3(threshold19) 0 +set tdc3(threshold20) 0 +set tdc3(threshold21) 0 +set tdc3(threshold22) 0 +set tdc3(threshold23) 0 +set tdc3(threshold24) 0 +set tdc3(threshold25) 0 +set tdc3(threshold26) 0 +set tdc3(threshold27) 0 +set tdc3(threshold28) 0 +set tdc3(threshold29) 0 +set tdc3(threshold30) 0 +set tdc3(threshold31) 0 +set tdc3(range) 255 +set tdc3(voltage) 254 +set tdc3(offset) 0 + +set tdc4(cardbase) 2097408 ;# 0x200100 +set tdc4(lowThreshold) 1 +set tdc4(highThreshold) 198 +set tdc4(range) 192 ;# 0 = 90ns, 224 = 770ns + +set adc0(cardbase) 0 ;# 0 +set adc0(lowThreshold) 8 +set adc0(highThreshold) 198 +set adc0(delay) 0 diff --git a/hadaq/pkt.c b/hadaq/pkt.c new file mode 100644 index 0000000..d680a0f --- /dev/null +++ b/hadaq/pkt.c @@ -0,0 +1,48 @@ +static char rcsId[] = "$Id: pkt.c,v 6.1 1999-08-31 10:37:24 muench Stab $"; + +#include +#include +#include +#include +#include + +#include "pkt.h" + +char *Pkt_2charP(const void *my) +{ + static char buf[132]; + + sprintf(buf, "size: 0x%08x\tdecoding: 0x%08x\tid: 0x%08x\tseqNr: 0x%08x", + Pkt_size(my), Pkt_decoding(my), Pkt_id(my), Pkt_seqNr(my)); + + return buf; +} + +void *newPkt(UInt4 decoding, UInt4 id, UInt4 seqNr) +{ + void *my; + + my = allocMem(Pkt_hdrSize()); + + Pkt_setSize(my, Pkt_hdrSize()); + Pkt_setDecoding(my, decoding); + Pkt_setId(my, id); + Pkt_setSeqNr(my, seqNr); + + return my; +} + +void deletePkt(void *my) +{ + freeMem(my); +} + +void *Pkt_appendData(void *my, const void *data, size_t size) +{ + + my = reallocMem(my, Pkt_paddedSize(my) + size); + memcpy(Pkt_end(my), data, size); + Pkt_setSize(my, Pkt_paddedSize(my) + size); + + return my; +} diff --git a/hadaq/pkt.h b/hadaq/pkt.h new file mode 100644 index 0000000..fe58506 --- /dev/null +++ b/hadaq/pkt.h @@ -0,0 +1,95 @@ +#ifndef PKT_H +#define PKT_H + +#include + +#include "hadtu.h" + +enum PktId { + PktId_bom = 1, + PktId_eom = 2 +}; + +enum PktDecoding { + PktDecoding_default = 98 +}; + +#define Pkt_hdr HadTu_hdr +#define Pkt_isSwapped HadTu_isSwapped +#define Pkt_hdrValue HadTu_hdrValue +#define Pkt_setHdrValue HadTu_setHdrValue +#define Pkt_decoding HadTu_decoding +#define Pkt_setDecoding HadTu_setDecoding +#define Pkt_alignment HadTu_alignment +#define Pkt_size HadTu_size +#define Pkt_setSize HadTu_setSize +#define Pkt_paddedSize HadTu_paddedSize +#define Pkt_begin HadTu_begin +#define Pkt_end HadTu_end +#define Pkt_next HadTu_next + +static size_t Pkt_hdrLen(void); +static size_t Pkt_hdrSize(void); +static size_t Pkt_dataSize(const void *my); +static void *Pkt_data(const void *my); + +static UInt4 Pkt_id(const void *my); +static void Pkt_setId(void *my, UInt4 id); +static UInt4 Pkt_seqNr(const void *my); +static void Pkt_setSeqNr(void *my, UInt4 seqNr); + +char *Pkt_2charP(const void *my); + +void *newPkt(UInt4 decoding, UInt4 id, UInt4 seqNr); +void deletePkt(void *my); +void *Pkt_appendData(void *my, const void *data, size_t size); + +static enum PktIdx { + PktIdx_size, + PktIdx_decoding, + PktIdx_id, + PktIdx_seqNr, + PktIdx_data +}; + +static size_t Pkt_hdrLen(void) +{ + return PktIdx_data; +} + +static size_t Pkt_hdrSize(void) +{ + return Pkt_hdrLen() * sizeof(UInt4); +} + +static size_t Pkt_dataSize(const void *my) +{ + return Pkt_size(my) - Pkt_hdrSize(); +} + +static void *Pkt_data(const void *my) +{ + return (void *) ((char *) my + Pkt_hdrSize()); +} + +static UInt4 Pkt_id(const void *my) +{ + return Pkt_hdrValue(my, PktIdx_id); +} + +static void Pkt_setId(void *my, UInt4 id) +{ + Pkt_setHdrValue(my, PktIdx_id, id); +} + +static UInt4 Pkt_seqNr(const void *my) +{ + return Pkt_hdrValue(my, PktIdx_seqNr); +} + +static void Pkt_setSeqNr(void *my, UInt4 seqNr) +{ + Pkt_setHdrValue(my, PktIdx_seqNr, seqNr); +} + +#endif diff --git a/hadaq/psxshm.c b/hadaq/psxshm.c new file mode 100644 index 0000000..7a26221 --- /dev/null +++ b/hadaq/psxshm.c @@ -0,0 +1,74 @@ +static char rcsId[] = "$Id: psxshm.c,v 6.1 1999-08-31 10:37:24 muench Stab $"; + +#define _POSIX_C_SOURCE 199309L +#include + +#include +#include +#include +#ifdef _POSIX_SHARED_MEMORY_OBJECTS +#include +#else +#include "mman.h" +#endif + +#include "psxshm.h" + +PsxShm *PsxShm_open(const char *name, int oflag, mode_t mode, off_t size) +{ + PsxShm *my; + + if (NULL == (my = malloc(sizeof(PsxShm)))) { + goto cleanup0; + } + if (0 > (my->fd = shm_open(name, oflag, mode))) { + goto cleanup1; + } + my->size = size; + if ((oflag & O_CREAT) != 0) { + if (0 > ftruncate(my->fd, my->size)) { + goto cleanup2; + } + } + if ((void *) MAP_FAILED == (my->addr = mmap(0, my->size, PROT_READ | PROT_WRITE, MAP_SHARED, my->fd, 0L))) { + goto cleanup2; + } + return my; + +/* cleanup allocated resources and report error */ + cleanup2: + { + int e = errno; + + close(my->fd); + if ((oflag & O_CREAT) != 0) { /* let's assume we have created it */ + shm_unlink(name); + } + errno = e; + } + cleanup1: + free(my); + cleanup0: + return NULL; +} + +int PsxShm_close(PsxShm *my) +{ + int ret; + + if ( + 0 > munmap(my->addr, my->size) + || 0 > close(my->fd) + ) { + ret = -1; + } else { + ret = 0; + } + free(my); + return ret; +} + +int PsxShm_unlink(const char *name) +{ + return shm_unlink(name); +} diff --git a/hadaq/psxshm.h b/hadaq/psxshm.h new file mode 100644 index 0000000..c5877c7 --- /dev/null +++ b/hadaq/psxshm.h @@ -0,0 +1,16 @@ +#ifndef PSXSHM_H +#define PSXSHM_H + +#include + +typedef struct PsxShmS { + int fd; + void *addr; + off_t size; +} PsxShm; + +PsxShm *PsxShm_open(const char *name, int oflag, mode_t mode, off_t size); +int PsxShm_close(PsxShm * my); +int PsxShm_unlink(const char *name); + +#endif diff --git a/hadaq/rc.c b/hadaq/rc.c new file mode 100644 index 0000000..ce50503 --- /dev/null +++ b/hadaq/rc.c @@ -0,0 +1,37 @@ + +#include +#include +#include + +#include "rc.h" + +int Rc_invariant(Rc *my) +{ + int retVal; + int i; + + retVal = 1; + if (my->lvme == NULL) { + retVal = 0; + } + return retVal; +} + +int conRc(Rc *my, const char *name, unsigned long vmeBase) +{ + if (NULL == (my->lvme = malloc(sizeof(LVme)))) { + perror("malloc"); + exit(EXIT_FAILURE); + } + if (0 > conLVme(my->lvme, vmeBase, Rc_addrSpace, 0x09, 0, 0)) { + free(my->lvme); + return -1; + } + return 0; +} + +void desRc(Rc *my) +{ + desLVme(my->lvme); + free(my->lvme); +} diff --git a/hadaq/rc.h b/hadaq/rc.h new file mode 100644 index 0000000..03653c1 --- /dev/null +++ b/hadaq/rc.h @@ -0,0 +1,644 @@ +#ifndef RC_H +#define RC_H + +#include +#include + +typedef struct RcS { + LVme *lvme; +} Rc; + +/********************************** + * INTERFACE2 Xilinx part * + * based on ver10rev1, 07.05.1999 * + **********************************/ + +enum Rc_regions { + memRegion = 0x100000, + busRegion = 0x200000, + regRegion = 0x300000, + xcRegion = 0x400000, + dprRegion = 0x500000 +}; + +static const size_t Rc_addrSpace = 0x600000; + +/* Offsets for INTERFACE2 registers */ +static const ptrdiff_t ctrlReg = regRegion + 0x000; +static const ptrdiff_t ctrlPad = regRegion + 0x002; +static const ptrdiff_t trgReg = regRegion + 0x004; +static const ptrdiff_t trgPad = regRegion + 0x006; +static const ptrdiff_t trgCtr = regRegion + 0x008; +static const ptrdiff_t prdoutCtr = regRegion + 0x00a; +static const ptrdiff_t ardoutCtr = regRegion + 0x00c; +static const ptrdiff_t adelCtr = regRegion + 0x00e; +static const ptrdiff_t lcdReg = regRegion + 0x010; +static const ptrdiff_t lcdPad = regRegion + 0x012; + +/* CTRL register definitions */ +static unsigned short Rc_getCtrlReg(Rc * my) { return LVme_getW(my->lvme, ctrlReg); } +static unsigned short Rc_getCtrlPad(Rc * my) { return LVme_getW(my->lvme, ctrlPad); } + +static void Rc_setReset(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 6); } +static void Rc_clrReset(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 6); } +static int Rc_getReset(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 6); } +static int Rc_padReset(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 6); } + +static void Rc_setMwr(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 7); } +static void Rc_clrMwr(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 7); } +static int Rc_getMwr(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 7); } +static int Rc_padMwr(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 7); } + +static void Rc_setMsel(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 8); } +static void Rc_clrMsel(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 8); } +static int Rc_getMsel(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 8); } +static int Rc_padMsel(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 8); } + +static void Rc_setEvtend(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 9); } +static void Rc_clrEvtend(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 9); } +static int Rc_getEvtend(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 9); } +static int Rc_padEvtend(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 9); } + +static void Rc_setEvtbeg(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 10); } +static void Rc_clrEvtbeg(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 10); } +static int Rc_getEvtbeg(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 10); } +static int Rc_padEvtbeg(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 10); } + +static void Rc_setSysclk(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 11); } +static void Rc_clrSysclk(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 11); } +static int Rc_getSysclk(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 11); } +static int Rc_padSysclk(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 11); } + +static void Rc_Cycle(Rc * my) +{ + if(Rc_getSysclk(my)) + { + Rc_clrSysclk(my); + Rc_setSysclk(my); + } + else + { + Rc_setSysclk(my); + Rc_clrSysclk(my); + } +} + +static void Rc_setSwrq(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 12); } +static void Rc_clrSwrq(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 12); } +static int Rc_getSwrq(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 12); } +static int Rc_padSwrq(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 12); } + +static void Rc_setStop(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 13); } +static void Rc_clrStop(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 13); } +static int Rc_getStop(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 13); } +static int Rc_padStop(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 13); } + +/* Magic numbers */ +static const int PRDOUT = 0x00; /* Pattern readout (daisy chain) */ +static const int PDEL = 0x01; /* Pattern delete (buslike) */ +static const int ARDOUT = 0x02; /* Analog readout (daisy chain) */ +static const int ADEL = 0x03; /* Analog delete (buslike) */ +static const int RFIFO = 0x04; /* Reset FIFO (buslike) */ +static const int RDAISY = 0x05; /* Reset daisy chain (buslike) */ +static const int WCFG = 0x06; /* Write configuration (daisy chain) */ +static const int RCFG = 0x07; /* Read configuration (daisy chain) */ +static const int NOP = 0x0F; /* No OPeration - do nothing */ + +static void Rc_setFc(Rc * my, int fc) +{ + unsigned short savedCtrlReg; + savedCtrlReg = LVme_getW(my->lvme, ctrlReg); + savedCtrlReg = ( savedCtrlReg & 0xFFF0 ) | ( fc & 0x000F ); + LVme_setW(my->lvme, ctrlReg, savedCtrlReg); +} + +static int Rc_getFc(Rc * my) +{ + return LVme_getW(my->lvme, ctrlReg) & 0x000f; +} + +static void Rc_setError(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 4); } +static void Rc_clrError(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 4); } +static int Rc_getError(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 4); } +static int Rc_padError(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 4); } + +static void Rc_setRcbsy(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 5); } +static void Rc_clrRcbsy(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 5); } +static int Rc_getRcbsy(Rc * my) { return LVme_tstBitW(my->lvme, ctrlReg, 5); } +static int Rc_padRcbsy(Rc * my) { return LVme_tstBitW(my->lvme, ctrlPad, 5); } + +/* TRG register definitions */ +static unsigned short Rc_getTrgReg(Rc * my) { return LVme_getW(my->lvme, trgReg); } +static unsigned short Rc_getTrgPad(Rc * my) { return LVme_getW(my->lvme, trgPad); } + +static void Rc_setStrb0(Rc * my) { LVme_setBitW(my->lvme, trgReg, 0); } +static void Rc_clrStrb0(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 0); } +static int Rc_getStrb0(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 0); } +static int Rc_padStrb0(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 0); } + +static void Rc_setStrb1(Rc * my) { LVme_setBitW(my->lvme, trgReg, 1); } +static void Rc_clrStrb1(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 1); } +static int Rc_getStrb1(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 1); } +static int Rc_padStrb1(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 1); } + +static void Rc_setStrb2(Rc * my) { LVme_setBitW(my->lvme, trgReg, 2); } +static void Rc_clrStrb2(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 2); } +static int Rc_getStrb2(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 2); } +static int Rc_padStrb2(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 2); } + +static void Rc_setStrb3(Rc * my) { LVme_setBitW(my->lvme, trgReg, 3); } +static void Rc_clrStrb3(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 3); } +static int Rc_getStrb3(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 3); } +static int Rc_padStrb3(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 3); } + +static void Rc_setStrb4(Rc * my) { LVme_setBitW(my->lvme, trgReg, 4); } +static void Rc_clrStrb4(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 4); } +static int Rc_getStrb4(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 4); } +static int Rc_padStrb4(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 4); } + +static void Rc_setStrb5(Rc * my) { LVme_setBitW(my->lvme, trgReg, 5); } +static void Rc_clrStrb5(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 5); } +static int Rc_getStrb5(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 5); } +static int Rc_padStrb5(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 5); } + +static void Rc_setStrb6(Rc * my) { LVme_setBitW(my->lvme, trgReg, 6); } +static void Rc_clrStrb6(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 6); } +static int Rc_getStrb6(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 6); } +static int Rc_padStrb6(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 6); } + +static void Rc_setStrb7(Rc * my) { LVme_setBitW(my->lvme, trgReg, 7); } +static void Rc_clrStrb7(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 7); } +static int Rc_getStrb7(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 7); } +static int Rc_padStrb7(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 7); } + +/* Range for port: 0...7; other values are dangerous and no checking for the correct value is done ! */ +static void Rc_setStrbPort(Rc * my, int port) { LVme_setBitW(my->lvme, trgReg, port & 0x07); } +static void Rc_clrStrbPort(Rc * my, int port) { LVme_clrBitW(my->lvme, trgReg, port & 0x07); } +static int Rc_getStrbPort(Rc * my, int port) { return LVme_tstBitW(my->lvme, trgReg, port & 0x07); } +static int Rc_padStrbPort(Rc * my, int port) { return LVme_tstBitW(my->lvme, trgPad, port & 0x07); } + +static void Rc_StrobePort(Rc * my, int port) +{ + Rc_clrStrbPort(my, port); + Rc_setStrbPort(my, port); +} + +static void Rc_setDecision(Rc * my) { LVme_setBitW(my->lvme, trgReg, 8); } +static void Rc_clrDecision(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 8); } +static int Rc_getDecision(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 8); } +static int Rc_padDecision(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 8); } + +static void Rc_setArdout(Rc * my) { LVme_setBitW(my->lvme, trgReg, 9); } +static void Rc_clrArdout(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 9); } +static int Rc_getArdout(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 9); } +static int Rc_padArdout(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 9); } + +static void Rc_setPrdout(Rc * my) { LVme_setBitW(my->lvme, trgReg, 10); } +static void Rc_clrPrdout(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 10); } +static int Rc_getPrdout(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 10); } +static int Rc_padPrdout(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 10); } + +static void Rc_setBegrun(Rc * my) { LVme_setBitW(my->lvme, trgReg, 11); } +static void Rc_clrBegrun(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 11); } +static int Rc_getBegrun(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 11); } +static int Rc_padBegrun(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 11); } + +static void Rc_setTagclk(Rc * my) { LVme_setBitW(my->lvme, trgReg, 12); } +static void Rc_clrTagclk(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 12); } +static int Rc_getTagclk(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 12); } +static int Rc_padTagclk(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 12); } + +static void Rc_setTagdata(Rc * my) { LVme_setBitW(my->lvme, trgReg, 13); } +static void Rc_clrTagdata(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 13); } +static int Rc_getTagdata(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 13); } +static int Rc_padTagdata(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 13); } + +static void Rc_setTbsy(Rc * my) { LVme_setBitW(my->lvme, trgReg, 14); } +static void Rc_clrTbsy(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 14); } +static int Rc_getTbsy(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 14); } +static int Rc_padTbsy(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 14); } + +static void Rc_setTrg(Rc * my) { LVme_setBitW(my->lvme, trgReg, 15); } +static void Rc_clrTrg(Rc * my) { LVme_clrBitW(my->lvme, trgReg, 15); } +static int Rc_getTrg(Rc * my) { return LVme_tstBitW(my->lvme, trgReg, 15); } +static int Rc_padTrg(Rc * my) { return LVme_tstBitW(my->lvme, trgPad, 15); } + +static void Rc_TriggerPort(Rc * my) +{ + Rc_clrTrg(my); + Rc_setTrg(my); +} + +/* Status counter access */ +static unsigned short Rc_getTrgCtr(Rc * my) { return LVme_getW(my->lvme, trgCtr); } +static unsigned short Rc_getPrdoutCtr(Rc * my) { return LVme_getW(my->lvme, prdoutCtr); } +static unsigned short Rc_getArdoutCtr(Rc * my) { return LVme_getW(my->lvme, ardoutCtr); } +static unsigned short Rc_getAdelCtr(Rc * my) { return LVme_getW(my->lvme, adelCtr); } + +static void Rc_setRctr(Rc * my) { LVme_setBitW(my->lvme, ctrlReg, 15); } +static void Rc_clrRctr(Rc * my) { LVme_clrBitW(my->lvme, ctrlReg, 15); } + +static void Rc_ClrCtrs(Rc * my) +{ + Rc_setRctr(my); + Rc_clrRctr(my); +} + +/* LCD register definitions */ + +/* Magic numbers */ +static const int CLR_DISPLAY = 0x01; /* clears display, sets cursor home, unshifts */ +static const int CRSR_HOME = 0x02; /* sets cursor home, unshifts */ +static const int CRSR_LEFT = 0x10; /* move cursor one char left */ +static const int CRSR_RIGHT = 0x14; /* move cursor one char right */ +static const int DISP_LEFT = 0x18; /* shifts whole display one char left */ +static const int DISP_RIGHT = 0x1c; /* shifts whole display one char right */ +static const int CRSR_ON = 0x0a; /* display cursor */ +static const int BLINK_ON = 0x09; /* blinks cursor */ +static const int DISP_ON = 0x0c; /* set display on */ +static const int DISP_CTRL = 0x08; /* magic byte for CRSR_ON, BLINK_ON, DISP_ON */ + +/* Do not use this function alone */ +static int Rc_readInstrLCD(Rc * my) +{ + LVme_setW(my->lvme, lcdReg, 0x01FF); + LVme_setBitW(my->lvme, lcdReg, 10); + LVme_clrBitW(my->lvme, lcdReg, 10); + return LVme_getW(my->lvme, lcdPad); +} +static void Rc_waitBusyLCD(Rc * my) +{ + while((Rc_readInstrLCD(my) & 0x80) >> 7) + { + /* Delay loop -> something useful to put in here ? */ + } +} +static void Rc_writeDataLCD(Rc * my, int data) +{ + unsigned short realData = 0x0000; + realData = 0x0200 | data; + Rc_waitBusyLCD(my); + LVme_setW(my->lvme, lcdReg, realData); + LVme_setBitW(my->lvme, lcdReg, 10); + LVme_clrBitW(my->lvme, lcdReg, 10); +} +static void Rc_writeInstrLCD(Rc * my, int instr) +{ + unsigned short realInstr = 0x0000; + realInstr = 0x0000 | instr; + Rc_waitBusyLCD(my); + LVme_setW(my->lvme, lcdReg, realInstr); + LVme_setBitW(my->lvme, lcdReg, 10); + LVme_clrBitW(my->lvme, lcdReg, 10); +} +static void Rc_initLCD(Rc * my) +{ + /* Function Set: 8bit, 2lines, 5x7 font */ + LVme_setW(my->lvme, lcdReg, 0x0038); + LVme_setBitW(my->lvme, lcdReg, 10); + LVme_clrBitW(my->lvme, lcdReg, 10); + /* Wait more than 4.1ms */ + usleep(5000); + /* Display ON/OFF control */ + Rc_writeInstrLCD(my, 0x0e); + /* Entry mode set */ + Rc_writeInstrLCD(my, 0x06); +} + +/********************************* + * MEMORY2 Xilinx part * + * based on ver16rev1 07.05.1999 * + *********************************/ + +/* Offsets for MEMORY2 registers */ +static const ptrdiff_t statusid = regRegion + 0x100; +static const ptrdiff_t bugreg = regRegion + 0x102; +static const ptrdiff_t memreg = regRegion + 0x104; +static const ptrdiff_t pages = regRegion + 0x106; +static const ptrdiff_t sedec_high = regRegion + 0x108; +static const ptrdiff_t sedec_low = regRegion + 0x10a; +static const ptrdiff_t seid_high = regRegion + 0x10c; +static const ptrdiff_t seid_low = regRegion + 0x10e; + +/* STATUSID register */ +static unsigned int Rc_readStatusid(Rc * my) +{ + int realId; + realId = 0x00FF & LVme_getW(my->lvme, statusid); + return realId; +} +static void Rc_writeStatusid(Rc * my, unsigned char value) +{ + unsigned short savedStatusId; + savedStatusId = LVme_getW(my->lvme, statusid); /* StatusID Register retten */ + savedStatusId = ( savedStatusId & 0xFF00 ) | ( value & 0x00FF ); /* Neue ID auf low byte einblenden */ + LVme_setW(my->lvme, statusid, savedStatusId); /* neues Register zurueckschreiben */ +} +static unsigned short Rc_getStatusID(Rc * my) +{ + return LVme_getW(my->lvme, statusid); +} + +static void Rc_setIrqR(Rc * my) { LVme_setBitW(my->lvme, statusid, 15); } +static void Rc_clrIrqR(Rc * my) { LVme_clrBitW(my->lvme, statusid, 15); } +static int Rc_getIrqR(Rc * my) { return LVme_tstBitW(my->lvme, statusid, 15); } +static void Rc_setIrqS(Rc * my) { LVme_setBitW(my->lvme, statusid, 14); } +static void Rc_clrIrqS(Rc * my) { LVme_clrBitW(my->lvme, statusid, 14); } +static int Rc_getIrqS(Rc * my) { return LVme_tstBitW(my->lvme, statusid, 14); } + +static void Rc_IrqRon(Rc * my) +{ + Rc_setIrqR(my); +} +static void Rc_IrqRoff(Rc * my) +{ + Rc_clrIrqR(my); +} +static void Rc_IrqSon(Rc * my) +{ + Rc_setIrqS(my); +} +static void Rc_IrqSoff(Rc * my) +{ + Rc_clrIrqS(my); +} + +/* BUG register */ +static unsigned short Rc_getBug(Rc * my) +{ + return LVme_getW(my->lvme, bugreg); +} + +/* MEMREG register */ +/* Do not use this function alone */ +static unsigned short Rc_readMemreg(Rc * my) +{ + return LVme_getW(my->lvme, memreg); +} +/* Do not use this function alone */ +static void Rc_writeMemreg(Rc * my, unsigned short value) +{ + LVme_setW(my->lvme, memreg, value); +} +static void Rc_setMemfull(Rc * my, unsigned short pages) +{ + unsigned short realMemreg = 0x0000; + pages = pages & 0x07FF; /* PAGES auf untere 11 bits begrenzen */ + if(pages == 0x0000) + { + pages++; /* PAGES muss groesser 1 sein (RCBSY) */ + } + realMemreg = Rc_readMemreg(my); /* Altes Memreg retten */ + realMemreg = realMemreg & 0xF800 ; /* Alte PAGES loeschen */ + realMemreg = realMemreg | pages ; /* Neue PAGES einblenden */ + Rc_writeMemreg(my, realMemreg); /* Memreg zurueckschreiben */ +} + +/* PAGES register */ +/* Do not use this function alone */ +static unsigned short Rc_readPages(Rc * my) +{ + return LVme_getW(my->lvme, pages); +} +static void Rc_waitSwitchcomplete(Rc * my) +{ + unsigned short realPages = 0x0000; + realPages = Rc_readPages(my); /* Altes Register retten */ + realPages = realPages & 0xc000; /* oberste zwei Bits anschauen */ + while((realPages != 0x0000) || (realPages != 0xc000)) /* Schleife, bis beide Bits gleich */ + { + realPages = (Rc_readPages(my) & 0xc000); /* immer wieder reingucken */ + } +} +static int Rc_testMemfull(Rc * my) +{ + unsigned short realPages = 0x0000; + realPages = Rc_readPages(my); + realPages = (realPages & 0x2000) >> 13; + return realPages; +} + +/* SEDEC_HIGH register */ +static unsigned short Rc_readSedec_high(Rc * my) +{ + return LVme_getW(my->lvme, sedec_high); +} +static void Rc_writeSedec_high(Rc * my, unsigned short value) +{ + LVme_setW(my->lvme, sedec_high, value); +} + +/* SEDEC_LOW register */ +static unsigned short Rc_readSedec_low(Rc * my) +{ + return LVme_getW(my->lvme, sedec_low); +} +static void Rc_writeSedec_low(Rc * my, unsigned short value) +{ + LVme_setW(my->lvme, sedec_low, value); +} + +/* SEID_HIGH register */ +static unsigned short Rc_readSeid_high(Rc * my) +{ + return LVme_getW(my->lvme, seid_high); +} +static void Rc_writeSeid_high(Rc * my, unsigned short value) +{ + LVme_setW(my->lvme, seid_high, value); +} + +/* SEID_LOW register */ +static unsigned short Rc_readSeid_low(Rc * my) +{ + return LVme_getW(my->lvme, seid_low); +} +static void Rc_writeSeid_low(Rc * my, unsigned short value) +{ + LVme_setW(my->lvme, seid_low, value); +} + +/*********************** + * TIMING2 Xilinx part * + * based on verXrevY * + ***********************/ + +/* Keep in mind: TIMING2 is a 2nd class Xilinx -> busRegion */ + +/* Offsets for TIMING2 registers */ +static const ptrdiff_t evtgReg = busRegion + 0x100; +static const ptrdiff_t errReg = busRegion + 0x102; +static const ptrdiff_t mskReg = busRegion + 0x104; + +/* EVTG-Register read/write (16bit wide) */ +static unsigned short Rc_readEvtgreg(Rc * my) +{ + return LVme_getW(my->lvme, evtgReg); +} +static void Rc_writeEvtgreg(Rc * my, unsigned short value) +{ + LVme_setW(my->lvme, evtgReg, value); +} + +/* ERR-Register read; write resets register to zero (8bit wide) */ +static int Rc_readErrreg(Rc * my) +{ + return LVme_getW(my->lvme, errReg); +} +static void Rc_writeErrreg(Rc * my, int value) +{ + unsigned short realValue = 0x0000; + realValue = 0x0000 | value; + LVme_setW(my->lvme, errReg, realValue); +} + +/* MSK-Register read/write (8bit wide) */ +static int Rc_readMskreg(Rc * my) +{ + return LVme_getW(my->lvme, mskReg); +} +static void Rc_writeMskreg(Rc * my, int value) +{ + unsigned short realValue = 0x0000; + realValue = 0x0000 | value; + LVme_setW(my->lvme, mskReg, realValue); +} + +/**************** + * Port XC part * + ****************/ + +static const ptrdiff_t Pstatus = busRegion + 0x002; +static const ptrdiff_t Pcontrol = busRegion + 0x008; +static const ptrdiff_t portOffset = 0x020; + +static unsigned short Rc_getPstat(Rc * my, int port) +{ + port = port & 0x07; + return LVme_getW(my->lvme, (port * portOffset + Pstatus)); +} +static unsigned short Rc_getPctrl(Rc * my, int port) +{ + port = port & 0x07; + return LVme_getW(my->lvme, (port * portOffset + Pcontrol)); +} + + +/*************** + * Memory part * + * * + ***************/ + +static unsigned long Rc_readMem(Rc * my, unsigned long offsetValue) +{ + return LVme_getL(my->lvme, memRegion + offsetValue); +} +static void Rc_writeMem(Rc * my, unsigned long offsetValue, unsigned long value) +{ + LVme_setL(my->lvme, memRegion + offsetValue, value); +} + +static void Rc_clearMem(Rc * my) +{ + long i; + const long RC_MEMSIZE = 0x80000; + const long CLEARVALUE = 0x00000000; + for(i = 0; i < RC_MEMSIZE; i = i + 0x04) + { + Rc_writeMem(my, i, CLEARVALUE); + } +} +static long Rc_testMem(Rc * my) +{ + long i; + const long RC_MEMSIZE = 0x80000; + const long CLEARVALUE = 0x00000000; + unsigned long different = 0x00000000; + unsigned long memValue = 0x00000000; + for(i = 0; i < RC_MEMSIZE; i = i + 0x04) + { + memValue = Rc_readMem(my, i); + if(memValue != CLEARVALUE) + { + different++; + printf("A: 0x%08x: 0x%08x\n", i, memValue); + } + } + return different; +} + + +/*********************** + * Dualported RAM part * + * * + ***********************/ + +static unsigned short Rc_readDpr(Rc * my, unsigned long offsetValue) +{ + unsigned long realValue = 0x00000000; + realValue = LVme_getL(my->lvme, dprRegion + offsetValue); + realValue = 0x0000FFFF & realValue; + return realValue; +} +static void Rc_writeDpr(Rc * my, unsigned long offsetValue, unsigned short value) +{ + unsigned long realValue; + realValue = 0x0000FFFF & value; + LVme_setL(my->lvme, dprRegion + offsetValue, realValue); +} +static void Rc_clearDpr(Rc * my) +{ + unsigned short i; + const unsigned short DPRSIZE = 0x8000; + const unsigned short CLEARVALUE = 0x0000; + for(i = 0; i < DPRSIZE; i = i + 0x04) + { + if (i % 256 == 0) + { + printf("."); + } + Rc_writeDpr(my, i, CLEARVALUE); + } + printf("\n"); +} +static unsigned short Rc_testDpr(Rc * my) +{ + unsigned short i; + const unsigned short DPRSIZE = 0x8000; + const unsigned short CLEARVALUE = 0x0000; + unsigned short different = 0x0000; + unsigned short memValue = 0x0000; + for(i = 0; i < DPRSIZE; i = i + 0x04) + { + memValue = Rc_readDpr(my, i); + if(memValue != CLEARVALUE) + { + different++; + printf(" -> A: 0x%08x: 0x%04x\n", i, memValue); + } + } + return different; +} + +/************************ + * Internal DB bus part * + * * + ************************/ + +static void Rc_writeDB(Rc * my, ptrdiff_t offset, unsigned short data) +{ + LVme_setW(my->lvme, busRegion + offset, data); +} +static unsigned short Rc_readDB(Rc * my, ptrdiff_t offset) +{ + return LVme_getW(my->lvme, busRegion + offset); +} + +int Rc_invariant(Rc *my); +int conRc(Rc *my, const char *name, unsigned long vmeBase); +void desRc(Rc *my); + + + +/* This is a comment */ +#endif diff --git a/hadaq/readout.c b/hadaq/readout.c new file mode 100644 index 0000000..8893ad7 --- /dev/null +++ b/hadaq/readout.c @@ -0,0 +1,137 @@ +static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/readout.c,v 6.1 1999-08-31 10:37:25 muench Exp $"; + +#define _POSIX_C_SOURCE 199309L +#include +#include "grmblfx.h" + +#include +#include +#include +#include +#include + +#include + +#include "hardware.h" +#include "shmtrans.h" +#include "hadtuqueue.h" +#include "worker.h" + +static jmp_buf terminateJmp; + +void sigHandler(int sig) +{ + longjmp(terminateJmp, sig); +} + +static void usage(const char *progName) +{ + msglog(LOG_ERR, "Usage: %s [-a (agentCtrl)] [-p priority]\n", progName); + msglog_usage(); +} + +void main(int argc, char *argv[]) +{ + Hardware *hw; + void *subEvt; + Worker *worker; + ShmTrans *shmTrans; + int i; + int isStandalone; + char *outPath; + int priority; + size_t queueSize; + unsigned long *trigAccepted; + unsigned long *subevtsRead; + + isStandalone = 1; + outPath = "subevtqueue"; + priority = 0; + queueSize = 100 * 1024; + msglog_setlevel(argv[0], "info"); + + while ((i = getopt(argc, argv, "ap:v:")) != -1) { + switch (i) { + case 'a': + isStandalone = 0; + break; + case 'p': + priority = atoi(optarg); + break; + case 'v': + if (msglog_setlevel(argv[0], optarg) != 1) { + usage(argv[0]); + goto bailOut0; + } + break; + default: + usage(argv[0]); + goto bailOut0; + break; + } + } + + if (NULL == (worker = Worker_initBegin(argv[0], sigHandler, priority, isStandalone))) { + msglog(LOG_ERR, "connecting to agent: %s\n", strerror(errno)); + goto bailOut0; + } + if (NULL == (hw = newHardware())) { + msglog(LOG_ERR, "initializing hardware: %s\n", strerror(errno)); + goto bailOut1; + } + if (NULL == (shmTrans = ShmTrans_open(outPath, 2 * queueSize))) { + msglog(LOG_ERR, + "opening shared memory \"%s\": %s\n", outPath, strerror(errno)); + goto bailOut2; + } + trigAccepted = Worker_addStatistic(worker, "trigAccepted"); + subevtsRead = Worker_addStatistic(worker, "subevtsRead"); + + Worker_initEnd(worker); + + while (setjmp(terminateJmp) == 0) { + void *hadTu; + HadTuQueue *hadTuQueue; + Worker_dump(worker, 1); + + hadTu = ShmTrans_alloc(shmTrans, queueSize - HadTu_hdrSize()); +#ifndef NDEBUG + msglog(LOG_DEBUG, "shmTrans: %p = hadTu: %s\n", hadTu, HadTu_2charP(hadTu)); +#endif + hadTuQueue = allocMem(HadTuQueue_sizeOf()); +#ifdef BIGMSG + conHadTuQueue(hadTuQueue, hadTu, queueSize - HadTu_hdrSize()); +#else + conHadTuQueue(hadTuQueue, hadTu, Hardware_maxSubEvtSize(hw) + HadTu_hdrSize() + 8); +#endif + while (NULL != (subEvt = HadTuQueue_alloc(hadTuQueue, Hardware_maxSubEvtSize(hw)))) { + Hardware_waitForTrigger(hw, subEvt); + (*trigAccepted)++; + + Hardware_readout(hw, subEvt); + (*subevtsRead)++; +#ifndef NDEBUG + msglog(LOG_DEBUG, "hadTuQueue: %p = subEvt: %s\n", subEvt, SubEvt_2charP(subEvt)); +#endif + + HadTuQueue_push(hadTuQueue); + } + desHadTuQueue(hadTuQueue); + freeMem(hadTuQueue); + ShmTrans_send(shmTrans); + } + + Worker_fini(worker); + ShmTrans_close(shmTrans); + deleteHardware(hw); + + exit(EXIT_SUCCESS); + + ShmTrans_close(shmTrans); + bailOut2: + deleteHardware(hw); + bailOut1: + Worker_fini(worker); + bailOut0: + exit(EXIT_FAILURE); +} diff --git a/hadaq/sam_defs.h b/hadaq/sam_defs.h new file mode 100644 index 0000000..116fd66 --- /dev/null +++ b/hadaq/sam_defs.h @@ -0,0 +1,9 @@ +#ifndef SAM_DEFS_H +#define SAM_DEFS_H + +#define VMSR 0x01000008 +#define KSR 0x01000004 +#define CRAM 0x00000000 +#define CRR 0x00001ffc + +#endif diff --git a/hadaq/sched.h b/hadaq/sched.h new file mode 100644 index 0000000..5ef196a --- /dev/null +++ b/hadaq/sched.h @@ -0,0 +1,57 @@ +#ifndef OURSCHED_H +#define OURSCHED_H + +#ifdef _POSIX_PRIORITY_SCHEDULING +#include +#else +#ifdef __Lynx__ +#include +#include +#include + +struct sched_param { + int sched_priority; +}; + +static int sched_getscheduler(pid_t pid) +{ + return getscheduler(pid); +} + +static int sched_setscheduler(pid_t pid, int policy, const struct sched_param *p) +{ + return setscheduler(pid, policy, p->sched_priority); +} + +int sched_get_priority_max(int alg) +{ + return PRIO_FIFO_MAX; +} + +int sched_get_priority_min(int alg) +{ + return PRIO_FIFO_MIN; +} + +int sched_getparam(pid_t pid, struct sched_param *p) +{ + p->sched_priority = getprio(pid); + + return p->sched_priority == -1 ? -1 : 0; +} + +int sched_setparam(pid_t pid, const struct sched_param *p) +{ + return setprio(pid, p->sched_priority) == -1 ? -1 : 0; +} + +int sched_yield(void) +{ + return yield(); +} + +#else +#error POSIX_PRIORITY_SCHEDULING not available on this OS +#endif +#endif +#endif diff --git a/hadaq/semaphore.c b/hadaq/semaphore.c new file mode 100644 index 0000000..ae16635 --- /dev/null +++ b/hadaq/semaphore.c @@ -0,0 +1,147 @@ + +#define _XOPEN_SOURCE +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(__hpux) || defined(__osf__) +union semun { + int val; + struct semid_ds *buf; + unsigned short *array; +}; + +#endif + +#include "semaphore.h" + +static char *name2Path(char *path, char *name) +{ + char *prefix; + + if (NULL == (prefix = getenv("OUR_SEMAPHORE_PREFIX"))) { + prefix = ""; + } + if (strlen(prefix) + strlen(name) + 1 > _POSIX_PATH_MAX) { + errno = ENAMETOOLONG; + path = NULL; + } else { + strcpy(path, prefix); + strcat(path, name); + } + return path; +} + +sem_t *SEMAPHORE_sem_open(char *name, int oflags, mode_t mode, unsigned int value) +{ + int *sem; + char path[_POSIX_PATH_MAX]; + key_t key; + int semflg; + int fd; + union semun arg; + + if (NULL == name2Path(path, name)) { + return (sem_t *) -1; + } + if (0 > (fd = open(path, oflags, mode))) { + return (sem_t *) -1; + } + if ((key_t) - 1 == (key = ftok(path, 'A'))) { + close(fd); + return (sem_t *) -1; + } + close(fd); + + if (NULL == (sem = malloc(sizeof(int)))) { + return (sem_t *) -1; + } + semflg = mode; /* BUGBUG This depends on ipc modes having + the same */ + /* semantics as file modes */ + if ((oflags & O_CREAT) != 0) { + semflg |= IPC_CREAT; + } + if ((oflags & O_EXCL) != 0) { + semflg |= IPC_EXCL; + } + if (semget(key, 1, 0) != -1) { /* semaphore existst already */ + if (0 > (*sem = semget(key, 1, semflg))) { + free(sem); + return (sem_t *) -1; + } + } else { + arg.val = value; + if (0 > (*sem = semget(key, 1, semflg)) + || 0 > semctl(*sem, 0, SETVAL, arg) + ) { + free(sem); + return (sem_t *) -1; + } + } + return sem; +} + +int SEMAPHORE_sem_close(sem_t *sem) +{ + free(sem); + return 0; +} + +int SEMAPHORE_sem_unlink(char *name) +{ + int retVal; + sem_t semS, *sem = &semS; + char path[_POSIX_PATH_MAX]; + key_t key; + union semun arg; + + retVal = 0; + + arg.val = 0; + if ( + NULL == name2Path(path, name) + || (key_t) - 1 == (key = ftok(path, 'A')) + || 0 > (*sem = semget(key, 1, 0)) + || 0 > semctl(*sem, 0, IPC_RMID, arg) + ) { + retVal = -1; + } + if (-1 == unlink(path)) { + retVal = -1; + } + return retVal; +} + +int SEMAPHORE_sem_wait(sem_t *sem) +{ + static struct sembuf waitOpS = + {0, -1, 0}, *waitOp = &waitOpS; + + return semop(*sem, waitOp, 1); +} + +int SEMAPHORE_sem_trywait(sem_t *sem) +{ + static struct sembuf trywaitOpS = + {0, -1, IPC_NOWAIT}, *trywaitOp = &trywaitOpS; + + return semop(*sem, trywaitOp, 1); +} + +int SEMAPHORE_sem_post(sem_t *sem) +{ + static struct sembuf postOpS = + {0, +1, 0}, *postOp = &postOpS; + + return semop(*sem, postOp, 1); +} diff --git a/hadaq/semaphore.h b/hadaq/semaphore.h new file mode 100644 index 0000000..aaaa7d9 --- /dev/null +++ b/hadaq/semaphore.h @@ -0,0 +1,22 @@ +#ifndef OUR_SEMAPHORE_H +#define OUR_SEMAPHORE_H + +#include + +typedef int sem_t; + +#define sem_open SEMAPHORE_sem_open +#define sem_close SEMAPHORE_sem_close +#define sem_unlink SEMAPHORE_sem_unlink +#define sem_wait SEMAPHORE_sem_wait +#define sem_trywait SEMAPHORE_sem_trywait +#define sem_post SEMAPHORE_sem_post + +sem_t *SEMAPHORE_sem_open(char *name, int oflags, mode_t mode, unsigned int value); +int SEMAPHORE_sem_close(sem_t * sem); +int SEMAPHORE_sem_unlink(char *name); +int SEMAPHORE_sem_wait(sem_t * sem); +int SEMAPHORE_sem_trywait(sem_t * sem); +int SEMAPHORE_sem_post(sem_t * sem); + +#endif diff --git a/hadaq/shmtrans.c b/hadaq/shmtrans.c new file mode 100644 index 0000000..ae99b65 --- /dev/null +++ b/hadaq/shmtrans.c @@ -0,0 +1,343 @@ +static char rcsId[] = "$Id: shmtrans.c,v 6.1 1999-08-31 10:37:25 muench Stab $"; + +#define _POSIX_C_SOURCE 199309L +#include +#include "grmblfx.h" + +#include +#include +#include +#ifdef _POSIX_SEMAPHORES +#include +#else +#include "semaphore.h" +#endif +#include +#include + +#include + +#include "psxshm.h" +#include "hadtuqueue.h" + +#include "shmtrans.h" + +#define SPACE_IN_FRONT 16 /* Reserve a little space in front of the + hadtuqueues that is not used, but + accessible. Allows for in situ asembly of + fragments with headers. */ + +static void switchStorage(ShmTrans *my) +{ + HadTuQueue *queue; + + queue = my->rdQueue; + my->rdQueue = my->wrQueue; + my->wrQueue = queue; +} + +ShmTrans *ShmTrans_create(const char *name, size_t size) +{ + ShmTrans *my; + char ipcName[_POSIX_PATH_MAX]; + unsigned long pageSize; + size_t shmSize; + char *addr; + + my = allocMem(sizeof(ShmTrans)); + + my->wrQueue = (HadTuQueue *) allocMem(HadTuQueue_sizeOf()); + my->rdQueue = (HadTuQueue *) allocMem(HadTuQueue_sizeOf()); + + strcpy(my->name, name); + + strcpy(ipcName, my->name); + strcat(ipcName, ".shm"); + if (0 > PsxShm_unlink(ipcName)) { + switch (errno) { + case ENOENT: + break; + default: + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut1; + break; + } + } + if (0 > (pageSize = sysconf(_SC_PAGESIZE))) { + msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut1; + } + shmSize = 2 * (size + SPACE_IN_FRONT); + shmSize = (shmSize & (pageSize - 1)) + ? (shmSize & ~(pageSize - 1)) + pageSize : shmSize; + + if (NULL == (my->shm = PsxShm_open(ipcName, O_CREAT | O_RDWR, S_IRWXU, shmSize))) { + msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut1; + } + addr = my->shm->addr; + addr += SPACE_IN_FRONT; + conHadTuQueue(my->wrQueue, addr, size); + addr += size; + addr += SPACE_IN_FRONT; + conHadTuQueue(my->rdQueue, addr, size); + HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_write); + HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_write); + + strcpy(ipcName, my->name); + strcat(ipcName, "SR.sem"); + + if (0 > sem_unlink(ipcName)) { + switch (errno) { + case ENOENT: + break; + default: + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut2; + break; + } + } + if ((sem_t *) -1 == (my->switchRequest = sem_open(ipcName, O_CREAT | O_EXCL, S_IRWXU, 0))) { + msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut2; + } + strcpy(ipcName, my->name); + strcat(ipcName, "SC.sem"); + if (0 > sem_unlink(ipcName)) { + switch (errno) { + case ENOENT: + break; + default: + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut3; + break; + } + } + if ((sem_t *) -1 == (my->switchComplete = sem_open(ipcName, O_CREAT | O_EXCL, S_IRWXU, 0))) { + msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut3; + } + return my; + + bailOut3: + sem_close(my->switchRequest); + strcpy(ipcName, my->name); + strcat(ipcName, "SC.sem"); + sem_unlink(ipcName); + bailOut2: + desHadTuQueue(my->rdQueue); + desHadTuQueue(my->wrQueue); + + PsxShm_close(my->shm); + strcpy(ipcName, my->name); + strcat(ipcName, ".shm"); + PsxShm_unlink(ipcName); + bailOut1: + freeMem(my->wrQueue); + freeMem(my->rdQueue); + freeMem(my); + + return NULL; +} + +void ShmTrans_remove(ShmTrans *my) +{ + char ipcName[_POSIX_PATH_MAX]; + + sem_close(my->switchRequest); + strcpy(ipcName, my->name); + strcat(ipcName, "SR.sem"); + sem_unlink(ipcName); + + sem_close(my->switchComplete); + strcpy(ipcName, my->name); + strcat(ipcName, "SC.sem"); + sem_unlink(ipcName); + + desHadTuQueue(my->rdQueue); + desHadTuQueue(my->wrQueue); + + PsxShm_close(my->shm); + strcpy(ipcName, my->name); + strcat(ipcName, ".shm"); + PsxShm_unlink(ipcName); + + freeMem(my->wrQueue); + freeMem(my->rdQueue); + freeMem(my); +} + +ShmTrans *ShmTrans_open(const char *name, size_t size) +{ + ShmTrans *my; + char ipcName[_POSIX_PATH_MAX]; + unsigned long pageSize; + size_t shmSize; + char *addr; + + my = allocMem(sizeof(ShmTrans)); + + my->wrQueue = (HadTuQueue *) allocMem(HadTuQueue_sizeOf()); + my->rdQueue = (HadTuQueue *) allocMem(HadTuQueue_sizeOf()); + + strcpy(my->name, name); + + strcpy(ipcName, my->name); + strcat(ipcName, ".shm"); + + if (0 > (pageSize = sysconf(_SC_PAGESIZE))) { + msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut1; + } + shmSize = 2 * (size + SPACE_IN_FRONT); + shmSize = (shmSize & (pageSize - 1)) + ? (shmSize & ~(pageSize - 1)) + pageSize : shmSize; + + if (NULL == (my->shm = PsxShm_open(ipcName, O_RDWR, 0, shmSize))) { + msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut1; + } + addr = my->shm->addr; + addr += SPACE_IN_FRONT; + conHadTuQueue(my->wrQueue, addr, size); + addr += size; + addr += SPACE_IN_FRONT; + conHadTuQueue(my->rdQueue, addr, size); + HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_read); + HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_read); + + strcpy(ipcName, my->name); + strcat(ipcName, "SR.sem"); + + if ((sem_t *) -1 == (my->switchRequest = sem_open(ipcName, 0, 0, 0))) { + msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut2; + } + strcpy(ipcName, my->name); + strcat(ipcName, "SC.sem"); + + if ((sem_t *) -1 == (my->switchComplete = sem_open(ipcName, 0, 0, 0))) { + msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut3; + } + return my; + + bailOut3: + sem_close(my->switchRequest); + bailOut2: + desHadTuQueue(my->rdQueue); + desHadTuQueue(my->wrQueue); + + PsxShm_close(my->shm); + bailOut1: + freeMem(my->wrQueue); + freeMem(my->rdQueue); + freeMem(my); + + return NULL; +} + +void ShmTrans_close(ShmTrans *my) +{ + sem_close(my->switchComplete); + sem_close(my->switchRequest); + desHadTuQueue(my->rdQueue); + desHadTuQueue(my->wrQueue); + PsxShm_close(my->shm); + freeMem(my->wrQueue); + freeMem(my->rdQueue); + freeMem(my); +} + +void *ShmTrans_alloc(ShmTrans *my, size_t size) +{ + void *storage; + + if (sem_trywait(my->switchRequest) == 0) { + HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_read); + switchStorage(my); + HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_write); + sem_post(my->switchComplete); + } + while (NULL == (storage = HadTuQueue_alloc(my->wrQueue, size))) { + HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_read); + sem_wait(my->switchRequest); + switchStorage(my); + sem_post(my->switchComplete); + HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_write); + } + return storage; +} + +void *ShmTrans_tryAlloc(ShmTrans *my, size_t size) +{ + return HadTuQueue_alloc(my->wrQueue, size); +} + +void ShmTrans_requestSpace(ShmTrans *my) +{ + if (sem_trywait(my->switchRequest) == 0) { + HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_read); + switchStorage(my); + HadTuQueue_cntl(my->wrQueue, HadTuQueueProt_write); + sem_post(my->switchComplete); + } +} + +void ShmTrans_send(ShmTrans *my) +{ + HadTuQueue_push(my->wrQueue); +} + +void *ShmTrans_recv(ShmTrans *my) +{ + void *storage; + + while (NULL == (storage = HadTuQueue_front(my->rdQueue))) { + HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_write); + sem_post(my->switchRequest); + sem_wait(my->switchComplete); + switchStorage(my); + HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_read); + } + return storage; +} + +void *ShmTrans_recvWhole(ShmTrans *my) +{ + while (HadTuQueue_empty(my->rdQueue)) { + HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_write); + sem_post(my->switchRequest); + sem_wait(my->switchComplete); + switchStorage(my); + HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_read); + } + return HadTuQueue_2voidP(my->rdQueue); +} + +void *ShmTrans_tryRecv(ShmTrans *my) +{ + return HadTuQueue_front(my->rdQueue); +} + +void ShmTrans_requestData(ShmTrans *my) +{ + HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_write); + sem_post(my->switchRequest); + sem_wait(my->switchComplete); + switchStorage(my); + HadTuQueue_cntl(my->rdQueue, HadTuQueueProt_read); +} + +void ShmTrans_free(ShmTrans *my) +{ + HadTuQueue_pop(my->rdQueue); +} + +void ShmTrans_freeWhole(ShmTrans *my) +{ + HadTuQueue_clear(my->rdQueue); +} diff --git a/hadaq/shmtrans.h b/hadaq/shmtrans.h new file mode 100644 index 0000000..f8ef890 --- /dev/null +++ b/hadaq/shmtrans.h @@ -0,0 +1,42 @@ + +#ifndef SHMTRANS_H +#define SHMTRANS_H + +#include + +#ifdef _POSIX_SEMAPHORES +#include +#else +#include "semaphore.h" +#endif + +#include "psxshm.h" + +#include "hadtuqueue.h" + +typedef struct ShmTransS { + char name[_POSIX_PATH_MAX]; + PsxShm *shm; + HadTuQueue *rdQueue; + HadTuQueue *wrQueue; + sem_t *switchRequest; + sem_t *switchComplete; +} ShmTrans; + +ShmTrans *ShmTrans_create(const char *name, size_t size); +ShmTrans *ShmTrans_open(const char *name, size_t size); +void ShmTrans_close(ShmTrans *my); +void ShmTrans_remove(ShmTrans *my); + +void *ShmTrans_alloc(ShmTrans *my, size_t size); +void *ShmTrans_tryAlloc(ShmTrans *my, size_t size); +void ShmTrans_requestSpace(ShmTrans *my); +void ShmTrans_send(ShmTrans *my); +void *ShmTrans_recv(ShmTrans *my); +void *ShmTrans_recvWhole(ShmTrans *my); +void *ShmTrans_tryRecv(ShmTrans *my); +void ShmTrans_requestData(ShmTrans *my); +void ShmTrans_free(ShmTrans *my); +void ShmTrans_freeWhole(ShmTrans *my); + +#endif diff --git a/hadaq/showevt b/hadaq/showevt new file mode 100644 index 0000000..a40082c --- /dev/null +++ b/hadaq/showevt @@ -0,0 +1,3 @@ +#!/usr/bin/sh +./daq_sniff -h localhost | daq_anal -n 1 +exit 0 diff --git a/hadaq/showevt.c b/hadaq/showevt.c new file mode 100644 index 0000000..c78236b --- /dev/null +++ b/hadaq/showevt.c @@ -0,0 +1,87 @@ +static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/showevt.c,v 6.1 1999-08-31 10:37:25 muench Exp $"; + +#define _ANSI_C_SOURCE +#include + +#include +#include +#include + +#include "hldread.h" + +int startAnalysis(int argc, char **argv) +{ + msglog(LOG_DEBUG, "startAnalysis called\n"); + return 0; +} + +int analyseEvt(void *evt) +{ + int i; + void *subEvt; + + msglog(LOG_DEBUG, "analyseEvt called\n"); + + /* print the event header */ + printf( + "size: 0x%08x decoding: 0x%08x id: 0x%08x seqNr: 0x%08x\n" + "date: %s time: %s runNr: 0x%08x\n", + Evt_size(evt), Evt_decoding(evt), Evt_id(evt), Evt_seqNr(evt), + Evt_date2charP(evt), Evt_time2charP(evt), Evt_runNr(evt) + ); + + i = 0; + /* loop over all subevents */ + for (subEvt = Evt_data(evt); subEvt < Evt_end(evt); subEvt = Evt_next(evt, subEvt)) { + printf("size: 0x%08x decoding: 0x%08x id: 0x%08x trigNr: 0x%08x\n", + SubEvt_size(subEvt), SubEvt_decoding(subEvt), SubEvt_id(subEvt), SubEvt_trigNr(subEvt)); + if (SubEvt_decoding(subEvt) == SubEvtDecoding_32bitData) { + UInt4 *data; + + data = SubEvt_data(subEvt); + for (i = 0; i < SubEvt_dataSize(subEvt) / sizeof(UInt4); i++) { + if (i % 4 == 0) { /* newline and the offset in the subEvt */ + printf("\n0x%08x:", (char *) data - (char *) SubEvt_data(subEvt)); + } + printf(" 0x%08x", data[i]); + } + } else if (SubEvt_decoding(subEvt) == SubEvtDecoding_16bitData) { + UInt2 *data; + + data = SubEvt_data(subEvt); + for (i = 0; i < SubEvt_dataSize(subEvt) / sizeof(UInt2); i++) { + if (i % 8 == 0) { /* newline and the offset in the subEvt */ + printf("\n0x%08x:", (char *) data - (char *) SubEvt_data(subEvt)); + } + printf(" 0x%04x", data[i]); + } + } else if (SubEvt_decoding(subEvt) == SubEvtDecoding_8bitData) { + UInt1 *data; + + data = SubEvt_data(subEvt); + for (i = 0; i < SubEvt_dataSize(subEvt) / sizeof(UInt1); i++) { + if (i % 8 == 0) { /* newline and the offset in the subEvt */ + printf("\n0x%08x:", (char *) data - (char *) SubEvt_data(subEvt)); + } + printf(" 0x%02x", data[i]); + } + } else if (SubEvt_decoding(subEvt) == SubEvtDecoding_text) { + char *data; + + printf("%c", '\n'); + data = (char *) SubEvt_data(subEvt); + for (i = 0; i < SubEvt_dataSize(subEvt); i++) { + printf("%c", data[i]); + } + } + printf("%c", '\n'); + } + printf("%c", '\n'); + return 0; +} + +int stopAnalysis(void) +{ + msglog(LOG_DEBUG, "stopAnalysis called\n"); + return 0; +} diff --git a/hadaq/sniff.c b/hadaq/sniff.c new file mode 100644 index 0000000..82739f7 --- /dev/null +++ b/hadaq/sniff.c @@ -0,0 +1,73 @@ + +#include + +#include +#include + +#include + +#include "online.h" + +main(int argc, char *argv[]) +{ + CLIENT *cl; + char *server; + int i; + struct rpc_err rpcErrS, *rpcErr = &rpcErrS; + rpcevt rpcEvtS, *rpcEvt = &rpcEvtS; + + msglog_setlevel(argv[0], "info"); + + server = NULL; + + while ((i = getopt(argc, argv, "v:h:")) != -1) { + switch (i) { + case 'h': + server = optarg; + break; + case 'v': + if (msglog_setlevel(argv[0], optarg) == 1) { + break; + } /* FALLTHROUGH to default */ + default: + msglog(LOG_ERR, "Usage: %s -h evtBuildHost\n", argv[0]); + msglog_usage(); + exit(EXIT_FAILURE); + break; + } + } + + if (server == NULL) { + msglog(LOG_ERR, "Usage: %s -h evtBuildHost\n", argv[0]); + msglog_usage(); + exit(EXIT_FAILURE); + } + while (1) { + if (NULL == (cl = clnt_create(server, DAQPROG, DAQVERS, "tcp"))) { + msglog(LOG_INFO, "online server not running, trying to connect\n"); + msglog(LOG_DEBUG, "%s, %d: %s\n", __FILE__, __LINE__, clnt_spcreateerror(server)); + sleep(5); + } else { + do { + if (NULL == (rpcEvt = onlineevt_1(NULL, cl))) { + clnt_geterr(cl, rpcErr); + switch (rpcErr->re_status) { + case RPC_TIMEDOUT: + break; + case RPC_CANTRECV: + msglog(LOG_INFO, "server shutdown, trying to reconnect\n"); + msglog(LOG_DEBUG, "%s, %d: %s\n", __FILE__, __LINE__, clnt_sperror(cl, "onlineevt_1")); + break; + default: + msglog(LOG_ERR, "%s, %d: %s\n", __FILE__, __LINE__, clnt_sperror(cl, "onlineevt_1")); + break; + } + } else { + fwrite(rpcEvt->rpcevt_val, 1, rpcEvt->rpcevt_len, stdout); + } + } while (rpcErr->re_status != RPC_CANTRECV); + clnt_destroy(cl); + } + } + exit(0); +} diff --git a/hadaq/startacq b/hadaq/startacq new file mode 100644 index 0000000..3e33891 --- /dev/null +++ b/hadaq/startacq @@ -0,0 +1,10 @@ +#!/usr/bin/sh +./daq_evtbuild -p -1 -s 3 -v notice & +echo $! >evtbuild.pid +sleep 1; +./daq_readout -p -2 -v notice & +echo $! >readout.pid +sleep 1; +./daq_ctrlctu 0 & +echo $! >ctrlctu.pid +exit 0 diff --git a/hadaq/stopacq b/hadaq/stopacq new file mode 100644 index 0000000..fb213bb --- /dev/null +++ b/hadaq/stopacq @@ -0,0 +1,8 @@ +#!/usr/bin/sh +kill $(cat ctrlctu.pid) +rm ctrlctu.pid +kill $(cat readout.pid) +rm readout.pid +kill $(cat evtbuild.pid) +rm evtbuild.pid +exit 0 diff --git a/hadaq/subevt.c b/hadaq/subevt.c new file mode 100644 index 0000000..178026e --- /dev/null +++ b/hadaq/subevt.c @@ -0,0 +1,96 @@ +static char rcsId[] = "$Id: subevt.c,v 6.1 1999-08-31 10:37:25 muench Exp $"; + +#include +#include +#include +#include +#include + +#include "subevt.h" + +enum SubEvtIdx { + SubEvtIdx_size, + SubEvtIdx_decoding, + SubEvtIdx_id, + SubEvtIdx_trigNr, + SubEvtIdx_data +}; + +size_t SubEvt_hdrLen(void) +{ + return SubEvtIdx_data; +} + +size_t SubEvt_hdrSize(void) +{ + return SubEvt_hdrLen() * sizeof(UInt4); +} + +size_t SubEvt_dataSize(const void *my) +{ + return SubEvt_size(my) - SubEvt_hdrSize(); +} + +void *SubEvt_data(const void *my) +{ + return (void *) ((char *) my + SubEvt_hdrSize()); +} + +UInt4 SubEvt_id(const void *my) +{ + return SubEvt_hdrValue(my, SubEvtIdx_id); +} + +void SubEvt_setId(void *my, UInt4 id) +{ + SubEvt_setHdrValue(my, SubEvtIdx_id, id); +} + +UInt4 SubEvt_trigNr(const void *my) +{ + return SubEvt_hdrValue(my, SubEvtIdx_trigNr); +} + +void SubEvt_setTrigNr(void *my, UInt4 trigNr) +{ + SubEvt_setHdrValue(my, SubEvtIdx_trigNr, trigNr); +} + +char *SubEvt_2charP(const void *my) +{ + static char buf[132]; + + sprintf(buf, "size: 0x%08x\tdecoding: 0x%08x\tid: 0x%08x\ttrigNr: 0x%08x", + SubEvt_size(my), SubEvt_decoding(my), SubEvt_id(my), SubEvt_trigNr(my)); + + return buf; +} + +void *newSubEvt(UInt4 decoding, UInt4 id, UInt4 trigNr) +{ + void *my; + + my = allocMem(SubEvt_hdrSize()); + + SubEvt_setSize(my, SubEvt_hdrSize()); + SubEvt_setDecoding(my, decoding); + SubEvt_setId(my, id); + SubEvt_setTrigNr(my, trigNr); + + return my; +} + +void deleteSubEvt(void *my) +{ + freeMem(my); +} + +void *SubEvt_appendData(void *my, const void *data, size_t size) +{ + + my = reallocMem(my, SubEvt_paddedSize(my) + size); + memcpy(SubEvt_end(my), data, size); + SubEvt_setSize(my, SubEvt_paddedSize(my) + size); + + return my; +} diff --git a/hadaq/subevt.h b/hadaq/subevt.h new file mode 100644 index 0000000..6b315fe --- /dev/null +++ b/hadaq/subevt.h @@ -0,0 +1,61 @@ +#ifndef SUBEVT_H +#define SUBEVT_H + +#include + +#include "hadtu.h" + +enum SubEvtId { + SubEvtId_test1 = 1, + SubEvtId_slow = 2, + SubEvtId_test2 = 3, + SubEvtId_mdc = 6, + SubEvtId_shower = 7, + SubEvtId_rich = 8, + SubEvtId_tof = 9, + SubEvtId_start = 10, + SubEvtId_veto = 11, + SubEvtId_richPed = 12, + SubEvtId_tofTest = 400, + SubEvtId_trigCode = 500, + SubEvtId_trigInfo = 501 +}; + +enum SubEvtDecoding { + SubEvtDecoding_8bitData = 1, + SubEvtDecoding_16bitData = (1 << 16) | 1, + SubEvtDecoding_32bitData = (2 << 16) | 1, + SubEvtDecoding_text = 2 +}; + +#define SubEvt_hdr HadTu_hdr +#define SubEvt_isSwapped HadTu_isSwapped +#define SubEvt_hdrValue HadTu_hdrValue +#define SubEvt_setHdrValue HadTu_setHdrValue +#define SubEvt_decoding HadTu_decoding +#define SubEvt_setDecoding HadTu_setDecoding +#define SubEvt_alignment HadTu_alignment +#define SubEvt_size HadTu_size +#define SubEvt_setSize HadTu_setSize +#define SubEvt_paddedSize HadTu_paddedSize +#define SubEvt_begin HadTu_begin +#define SubEvt_end HadTu_end +#define SubEvt_next HadTu_next + +size_t SubEvt_hdrLen(void); +size_t SubEvt_hdrSize(void); +size_t SubEvt_dataSize(const void *my); +void *SubEvt_data(const void *my); +UInt4 SubEvt_dataValue(const void *my, unsigned idx); +char *SubEvt_2charP(const void *my); + +UInt4 SubEvt_id(const void *my); +void SubEvt_setId(void *my, UInt4 id); +UInt4 SubEvt_trigNr(const void *my); +void SubEvt_setTrigNr(void *my, UInt4 trigNr); + +void *newSubEvt(UInt4 decoding, UInt4 id, UInt4 trigNr); +void deleteSubEvt(void *my); +void *SubEvt_appendData(void *my, const void *data, size_t size); + +#endif diff --git a/hadaq/tclAppInit.c b/hadaq/tclAppInit.c new file mode 100644 index 0000000..926d24a --- /dev/null +++ b/hadaq/tclAppInit.c @@ -0,0 +1,134 @@ + +/* + * tclAppInit.c -- + * + * Provides a default version of the main program and Tcl_AppInit + * procedure for Tcl applications (without Tk). + * + * Copyright (c) 1993 The Regents of the University of California. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) tclAppInit.c 1.20 97/03/24 14:29:43 + */ + +#ifdef TCL_XT_TEST +#include +#endif + +#include "tcl.h" + +/* + * The following variable is a special hack that is needed in order for + * Sun shared libraries to be used for Tcl. + */ + +extern int matherr(); +int *tclDummyMathPtr = (int *) matherr; + + +#ifdef TCL_TEST +EXTERN int TclObjTest_Init _ANSI_ARGS_((Tcl_Interp * interp)); +EXTERN int Tcltest_Init _ANSI_ARGS_((Tcl_Interp * interp)); +#endif /* TCL_TEST */ +#ifdef TCL_XT_TEST +EXTERN int Tclxttest_Init _ANSI_ARGS_((Tcl_Interp * interp)); +#endif + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * This is the main program for the application. + * + * Results: + * None: Tcl_Main never returns here, so this procedure never + * returns either. + * + * Side effects: + * Whatever the application does. + * + *---------------------------------------------------------------------- + */ + +int main(argc, argv) +int argc; /* Number of command-line arguments. */ +char **argv; /* Values of command-line arguments. */ +{ +#ifdef TCL_XT_TEST + XtToolkitInitialize(); +#endif + Tcl_Main(argc, argv, Tcl_AppInit); + return 0; /* Needed only to prevent compiler warning. */ +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_AppInit -- + * + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error + * message in interp->result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + +int Tcl_AppInit(interp) +Tcl_Interp *interp; /* Interpreter for application. */ +{ + if (Tcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } +#ifdef TCL_TEST +#ifdef TCL_XT_TEST + if (Tclxttest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } +#endif + if (Tcltest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + if (TclObjTest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } +#endif /* TCL_TEST */ + + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. + */ + if (Daq_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + /* + * Call Tcl_CreateCommand for application-specific commands, if + * they weren't already created by the init procedures called above. + */ + + /* + * Specify a user-specific startup file to invoke if the application + * is run interactively. Typically the startup file is "~/.apprc" + * where "app" is the name of the application. If this line is deleted + * then no user-specific startup file will be run under any conditions. + */ + + Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY); + return TCL_OK; +} diff --git a/hadaq/tcldaq.c b/hadaq/tcldaq.c new file mode 100644 index 0000000..8f539ed --- /dev/null +++ b/hadaq/tcldaq.c @@ -0,0 +1,109 @@ + +#include + +#include + +#include +#include +#include + +#include + +#include +#include +#include "worker.h" +#include "agent.h" + +int AgentCmd(ClientData clientData, Tcl_Interp * interp, int argc, char *argv[]) +{ + CLIENT *cl; + + if (argc != 3) { + Tcl_AppendResult(interp, "usage: c_agent connect|disconnect|ping ", NULL); + return TCL_ERROR; + } + if (strcmp(argv[1], "connect") == 0) { + if (NULL == (cl = clnt_create(argv[2], DAQAGENTPROG, DAQAGENTVERS, "tcp"))) { + Tcl_AppendResult(interp, clnt_spcreateerror(argv[2]), NULL); + return TCL_ERROR; + } + sprintf(interp->result, "%p", cl); + } else if (strcmp(argv[1], "disconnect") == 0) { + sscanf(argv[2], "%p", &cl); + clnt_destroy(cl); + } else if (strcmp(argv[1], "ping") == 0) { + } else { + Tcl_AppendResult(interp, "usage: c_agent connect|disconnect ", NULL); + return TCL_ERROR; + } + return TCL_OK; +} + +int WorkerCmd(ClientData clientData, Tcl_Interp * interp, int argc, char *argv[]) +{ + CLIENT *cl; + int id, *idP; + + if (argc < 4) { + Tcl_AppendResult(interp, "usage: c_worker start|stop [worker options]", NULL); + return TCL_ERROR; + } + sscanf(argv[2], "%p", &cl); + if (strcmp(argv[1], "start") == 0) { + RpcWorker_startArgs startArgsS, *startArgs = &startArgsS; + + startArgs->name = argv[3]; + /* CAUTION This does not pass the closing NULL pointer in argv */ + startArgs->argv.argv_len = argc - 3; + startArgs->argv.argv_val = argv + 3; + + if (NULL == (idP = rpcworker_start_1(startArgs, cl))) { + Tcl_AppendResult(interp, clnt_sperror(cl, "rpcworker_start_1"), NULL); + return TCL_ERROR; + } + id = *idP; + sprintf(interp->result, "%d", id); + } else if (strcmp(argv[1], "stop") == 0) { + int *res; + + idP = &id; + sscanf(argv[3], "%d", idP); + if (NULL == (res = rpcworker_stop_1(idP, cl))) { + Tcl_AppendResult(interp, clnt_sperror(cl, "rpcworker_stop_1"), NULL); + return TCL_ERROR; + } + } else if (strcmp(argv[1], "status") == 0) { + char *sS, **s = &sS; + + idP = &id; + sscanf(argv[3], "%d", idP); + if (NULL == (s = rpcworker_status_1(idP, cl))) { + Tcl_AppendResult(interp, clnt_sperror(cl, "rpcworker_status_1"), NULL); + return TCL_ERROR; + } + Tcl_AppendResult(interp, *s, NULL); + } else { + Tcl_AppendResult(interp, "usage: c_worker start|stop|status [options]", NULL); + return TCL_ERROR; + } + + return TCL_OK; +} + +int Daq_Init(Tcl_Interp * interp) +{ + /* + * Call Tcl_CreateCommand for application-specific commands, if + * they weren't already created by the init procedures called above. + */ + Tcl_CreateCommand(interp, "c_worker", WorkerCmd, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, "c_agent", AgentCmd, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + + /* + * Specify a user-specific startup file to invoke if the application + * is run interactively. Typically the startup file is "~/.apprc" + * where "app" is the name of the application. If this line is deleted + * then no user-specific startup file will be run under any conditions. + */ + return TCL_OK; +} diff --git a/hadaq/tkAppInit.c b/hadaq/tkAppInit.c new file mode 100644 index 0000000..5dbb0e0 --- /dev/null +++ b/hadaq/tkAppInit.c @@ -0,0 +1,118 @@ + +/* + * tkAppInit.c -- + * + * Provides a default version of the Tcl_AppInit procedure for + * use in wish and similar Tk-based applications. + * + * Copyright (c) 1993 The Regents of the University of California. + * Copyright (c) 1994 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) tkAppInit.c 1.22 96/05/29 09:47:08 + */ + +#include "tk.h" + +/* + * The following variable is a special hack that is needed in order for + * Sun shared libraries to be used for Tcl. + */ + +extern int matherr(); +int *tclDummyMathPtr = (int *) matherr; + +#ifdef TK_TEST +EXTERN int Tktest_Init _ANSI_ARGS_((Tcl_Interp * interp)); +#endif /* TK_TEST */ + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * This is the main program for the application. + * + * Results: + * None: Tk_Main never returns here, so this procedure never + * returns either. + * + * Side effects: + * Whatever the application does. + * + *---------------------------------------------------------------------- + */ + +int main(argc, argv) +int argc; /* Number of command-line arguments. */ +char **argv; /* Values of command-line arguments. */ +{ + Tk_Main(argc, argv, Tcl_AppInit); + return 0; /* Needed only to prevent compiler warning. */ +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_AppInit -- + * + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error + * message in interp->result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + +int Tcl_AppInit(interp) +Tcl_Interp *interp; /* Interpreter for application. */ +{ + if (Tcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + if (Tk_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } +#ifdef TK_TEST + if (Tktest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } +#endif /* TK_TEST */ + + + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. + */ + if (Daq_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + /* + * Call Tcl_CreateCommand for application-specific commands, if + * they weren't already created by the init procedures called above. + */ + + /* + * Specify a user-specific startup file to invoke if the application + * is run interactively. Typically the startup file is "~/.apprc" + * where "app" is the name of the application. If this line is deleted + * then no user-specific startup file will be run under any conditions. + */ + + Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY); + return TCL_OK; +} diff --git a/hadaq/worker.c b/hadaq/worker.c new file mode 100644 index 0000000..a57db93 --- /dev/null +++ b/hadaq/worker.c @@ -0,0 +1,303 @@ +static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/worker.c,v 6.1 1999-08-31 10:37:25 muench Stab $"; + +#define _POSIX_C_SOURCE 199309L +#include + +#include +#include +#ifdef _POSIX_PRIORITY_SCHEDULING +#include +#else +#include "sched.h" +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "worker.h" + +static struct sigaction ourOldSigActionS, *ourOldSigAction = &ourOldSigActionS; + +static sigReceived = 0; + +static void noopHandler(int sig) +{ + sigReceived = sig; +} + +static int changePriority(int p) +{ + struct sched_param spS, *sp = &spS;; + + if (sched_getscheduler(0) != SCHED_FIFO) { +#if defined(__osf__) + /* FIFO priorities are not all real time under DEC-UNIX */ + sp->sched_priority = SCHED_PRIO_RT_MIN + 16; +#else + sp->sched_priority = sched_get_priority_min(SCHED_FIFO) + 16; +#endif + } else { + sched_getparam(0, sp); + } + sp->sched_priority += p; + if (0 > sched_setscheduler(0, SCHED_FIFO, sp)) { + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut0; + } + return 0; + + bailOut0: + return -1; +} + +Worker *Worker_initBegin(const char *name, void (*sigHandler) (int), int priority, int isStandalone) +{ + Worker *my; + char ipcName[_POSIX_PATH_MAX]; + struct sigaction actS, *act = &actS; + + my = allocMem(sizeof(Worker)); + + strcpy(my->name, name); + my->pid = getpid(); + + act->sa_handler = sigHandler; + sigfillset(&(act->sa_mask)); + act->sa_flags = 0; + if (0 > sigaction(SIGTERM, act, ourOldSigAction)) { + msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut1; + } + if (0 > sigaction(SIGINT, act, ourOldSigAction)) { + msglog(LOG_DEBUG, "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut2; + } + if (0 > changePriority(priority)) { + msglog(LOG_WARNING, + "changeing priority: %s\n", strerror(errno)); + } + my->isStandalone = isStandalone; + + if (my->isStandalone) { + my->statistics = allocMem(32 * sizeof(Statistic)); + } else { + strcpy(ipcName, my->name); + strcat(ipcName, ".shm"); + + if (NULL == (my->shm = PsxShm_open(ipcName, O_RDWR, 0, 32 * sizeof(Statistic)))) { + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut3; + } + my->statistics = my->shm->addr; + + } + strcpy(my->statistics[0].name, ""); + return my; + + if (my->isStandalone) { + freeMem(my->statistics); + } else { + PsxShm_close(my->shm); + } + bailOut3: + sigaction(SIGINT, ourOldSigAction, NULL); + bailOut2: + sigaction(SIGTERM, ourOldSigAction, NULL); + bailOut1: + freeMem(my); + + return NULL; +} + +void Worker_initEnd(Worker *my) +{ + if (!my->isStandalone) { + if (0 > kill(getppid(), SIGUSR1)) { + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + } + } +} + +void Worker_fini(Worker *my) +{ + if (my->isStandalone) { + freeMem(my->statistics); + } else { + PsxShm_close(my->shm); + } + sigaction(SIGINT, ourOldSigAction, NULL); + sigaction(SIGTERM, ourOldSigAction, NULL); + freeMem(my); +} + +Worker *Worker_start(const char *name, char *argv[]) +{ + Worker *my; + char ipcName[_POSIX_PATH_MAX]; + struct sigaction actS, *act = &actS; + struct sigaction oAlrmActS, *oAlrmAct = &oAlrmActS; + struct sigaction oChldActS, *oChldAct = &oChldActS; + sigset_t sigMaskS, *sigMask = &sigMaskS; + + my = allocMem(sizeof(Worker)); + + strcpy(my->name, name); + + strcpy(ipcName, my->name); + strcat(ipcName, ".shm"); + if (-1 == PsxShm_unlink(ipcName)) { + switch (errno) { + case ENOENT: + break; + default: + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut1; + break; + } + } + if (NULL == (my->shm = PsxShm_open(ipcName, O_CREAT | O_RDWR, S_IRWXU, 32 * sizeof(Statistic)))) { + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut1; + } + my->statistics = my->shm->addr; + + act->sa_handler = noopHandler; + sigfillset(&(act->sa_mask)); + act->sa_flags = 0; + if (0 > sigaction(SIGCHLD, act, oChldAct)) { + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut2; + } + if (0 > sigaction(SIGUSR1, act, oAlrmAct)) { + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut3; + } + if (0 > (my->pid = fork())) { + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut4; + } + if (my->pid == 0) { /* This is the child, we can not get out of + this block */ + if (0 > execvp(name, argv)) { + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + msglog(LOG_EMERG, "Starting %s: %s\n", name, strerror(errno)); + abort(); + } + } else { + /* BUGBUG there should be a timeout here */ + sigemptyset(sigMask); /* This is the parent, so wait for the child */ + sigsuspend(sigMask); /* to initialize */ + + if (sigReceived == SIGCHLD) { + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, strerror(errno)); + goto bailOut4; + } + } + + sigaction(SIGUSR1, oAlrmAct, NULL); + sigaction(SIGCHLD, oChldAct, NULL); + + return my; + + bailOut5: + if (0 == kill(my->pid, SIGTERM)) { + wait(NULL); + } + bailOut4: + sigaction(SIGUSR1, oAlrmAct, NULL); + bailOut3: + sigaction(SIGCHLD, oChldAct, NULL); + bailOut2: + PsxShm_close(my->shm); + strcpy(ipcName, my->name); + strcat(ipcName, ".shm"); + PsxShm_unlink(ipcName); + bailOut1: + freeMem(my); + + return NULL; +} + +char *Worker_status(Worker *my) +{ + static char buf[32 * 80]; + char *p; + int i; + + strcpy(buf, "{}"); + for ( + i = 0, p = buf; + i < 32 && strcmp(my->statistics[i].name, "") != 0; + i++) { + p += sprintf(p, + "{ %s %lu } ", my->statistics[i].name, my->statistics[i].value); + } + return buf; +} + +void Worker_stop(Worker *my, int timeout) +{ + char ipcName[_POSIX_PATH_MAX]; + + if (0 == kill(my->pid, SIGTERM)) { + wait(NULL); + } + PsxShm_close(my->shm); + strcpy(ipcName, my->name); + strcat(ipcName, ".shm"); + PsxShm_unlink(ipcName); + freeMem(my); +} + +unsigned long *Worker_addStatistic(Worker *my, const char *name) +{ + int i; + + for (i = 0; i < 32 && strcmp(my->statistics[i].name, "") != 0; i++) { + } + if (i == 32) { + errno = 0; + msglog(LOG_DEBUG, + "%s, line %d: %s\n", __FILE__, __LINE__, "Too many statistics"); + goto bailOut0; + } + strcpy(my->statistics[i].name, name); + my->statistics[i].value = 0; + strcpy(my->statistics[i + 1].name, ""); + + return &(my->statistics[i].value); + + bailOut0: + return NULL; +} + +void Worker_dump(Worker *my, time_t interval) +{ + if (my->isStandalone) { + static time_t lastTime = 0; + time_t curTime; + + curTime = time(NULL); + if (curTime >= lastTime + interval) { + msglog(LOG_INFO, "%s\n", Worker_status(my)); + lastTime = curTime; + } + } +} diff --git a/hadaq/worker.h b/hadaq/worker.h new file mode 100644 index 0000000..0a7b0e1 --- /dev/null +++ b/hadaq/worker.h @@ -0,0 +1,30 @@ +#ifndef WORKER_H +#define WORKER_H + +#include + +#include "psxshm.h" + +typedef struct StatisticS { + char name[32]; + unsigned long value; +} Statistic; + +typedef struct WorkerS { + char name[_POSIX_PATH_MAX]; + PsxShm *shm; + Statistic *statistics; + pid_t pid; + int isStandalone; +} Worker; + +Worker *Worker_start(const char *name, char *argv[]); +char *Worker_status(Worker * my); +void Worker_stop(Worker * my, int timeout); +Worker *Worker_initBegin(const char *name, void (*sigHandler) (int), int priority, int isStandalone); +void Worker_initEnd(Worker * my); +void Worker_fini(Worker * my); +unsigned long *Worker_addStatistic(Worker * my, const char *name); +void Worker_dump(Worker * my, time_t interval); + +#endif