Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Timestaming with UTAG #107

Merged
merged 23 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7c2aa68
Create release candidate for UTAG developments (#2)
joaopaulosm Nov 29, 2023
5661720
fix: Epics base 7 or higher limitations added.
jerzyjamroz Nov 30, 2023
9cd491c
perf: Removal of the epicsTimeStampUTag.
jerzyjamroz Nov 30, 2023
95b1e3f
fix: convertTS does not need the template anymore.
jerzyjamroz Nov 30, 2023
014b94d
fix: Minimal adjustment to follow the master branch.
jerzyjamroz Nov 30, 2023
1e3c125
fix: UTag value is arbitrary based, not for s&r.
jerzyjamroz Nov 30, 2023
b5888db
perf: getTimeStamp optimized to basically one function.
jerzyjamroz Dec 1, 2023
388f055
docs: File header adjusted accordingly.
jerzyjamroz Dec 1, 2023
6568af5
fix: epicsUTag always 64 bit.
jerzyjamroz Dec 1, 2023
86efe4d
test: UTag tests.
jerzyjamroz Dec 4, 2023
5848d9a
perf: Reduction of UTag operations to devEvrEvent only.
jerzyjamroz Dec 4, 2023
c46c2c2
perf: evreventutag.db handling enhanced.
jerzyjamroz Dec 4, 2023
56f8bc2
fix: event added to the EvrEventUtag handling.
jerzyjamroz Dec 5, 2023
6991a38
refactor: devEvrEvent.cpp applied to the original form.
jerzyjamroz Dec 5, 2023
63c8be4
refactor: drvem.cpp recovered to its original form.
jerzyjamroz Dec 5, 2023
82b87cd
refactor: EvrEventUtag clean up.
jerzyjamroz Dec 5, 2023
2410f60
docs: Copyright added.
jerzyjamroz Dec 5, 2023
2457330
fix: $(s=:) was used for the private -ASub_.
jerzyjamroz Dec 5, 2023
e3b5a60
fix: evreventutag.db included in the module Makefile.
jerzyjamroz Dec 6, 2023
bfc6ca2
fix: Default VAL=0 for $(EN)-SP added.
jerzyjamroz Dec 7, 2023
e638c0b
feat: Warning added which informs if epicsUTag is supported or not.
jerzyjamroz Dec 11, 2023
14a7f29
perf: process_event removed from devEvrEventUtag.cpp.
jerzyjamroz Dec 13, 2023
da6b8b6
refactor: Risk of using a dummy epicsUTag minimilised.
jerzyjamroz Dec 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions evrApp/Db/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ DB += evrcml.db
DB += evrcmlgun.db
DB += evrcmlextra.db
DB += evrevent.db
ifdef BASE_7_0
DB += evreventutag.db
endif
DB += evrevent-cycle.db
DB += evrsoftgate.db
DB += evralias.db
Expand Down
4 changes: 2 additions & 2 deletions evrApp/Db/evrcml.db
Original file line number Diff line number Diff line change
Expand Up @@ -532,13 +532,13 @@ record(bo, "$(ON)BunchTrain$(s=:)Ena-SP") {

record(longout, "$(ON)BunchTrain$(s=:)Size-SP") {
field(PINI, "YES")
field(OUT , "$(ON)BunchTrain$(s=:)ASub_.A PP")
field(OUT , "$(ON)BunchTrain-ASub_.A PP")
field(UDF , "0")
field(VAL , "1")
info(autosaveFields_pass0, "VAL")
}

record(aSub, "$(ON)BunchTrain$(s=:)ASub_") {
record(aSub, "$(ON)BunchTrain-ASub_") {
field(SDIS, "$(ON)BunchTrain$(s=:)Ena-SP")
field(DISV, "0")
field(SNAM, "Bunch Train")
Expand Down
27 changes: 27 additions & 0 deletions evrApp/Db/evreventutag.db
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Usage of "evreventutag.db"
## Timestaming + UTAG support: import "evreventutag.db" instead of "evrevent.db".
## Timestaming support only: import "evrevent.db" and ignore "evreventutag.db".

# Macros:
# EN = record name prefix
# OBJ = EVR devObj name
# CODE = Event code (hardware)

record(int64out, "$(EN)-SP") {
field(DTYP, "EVR Event Utag")
field(SCAN, "I/O Intr")
field(OUT , "@OBJ=$(OBJ),Code=$(CODE)")
field(VAL , "0")
field(TSE , "-2") # from device support
field(FLNK, "$(EN)Cnt-I")
info(autosaveFields_pass0, "OUT")
}

record(calc, "$(EN)Cnt-I") {
field(DESC, "TS and UTAG source")
#field(SDIS, "$(EN)-SP")
#field(DISV, "0")
field(CALC, "A+1")
field(INPA, "$(EN)Cnt-I NPP")
field(TSEL, "$(EN)-SP.TIME")
}
7 changes: 7 additions & 0 deletions evrApp/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ evr_SRCS += evrGTIF.cpp

evr_SRCS += devEvrStringIO.cpp

ifdef BASE_7_0
evr_SRCS += devEvrEventUtag.cpp
endif

evr_SRCS += devEvrEvent.cpp
evr_SRCS += devEvrMapping.cpp

Expand All @@ -53,6 +57,9 @@ evrtest_LIBS += evr mrfCommon

evrtest_DBD += base.dbd
evrtest_DBD += evrSupport.dbd
ifdef BASE_7_0
evrtest_DBD += evrSupportBase7.dbd
endif

ifneq ($(GENERAL_TIME),)
evrtest_LIBS += generalTime
Expand Down
198 changes: 198 additions & 0 deletions evrApp/src/devEvrEventUtag.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
/*************************************************************************\
* Copyright (c) 2023 European Spallation Source ERIC (ESS), Lund, Sweden
* mrfioc2 is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Date: 5.12.2023
* Authors: Joao Paulo Martins <joaopaulosm@gmail.com>
* Jerzy Jamroz <jerzy.jamroz@gmail.com>
*/

#include <stdlib.h>
#include <string.h>
#include <epicsExport.h>
#include <dbAccess.h>
#include <devSup.h>
#include <recGbl.h>
#include <devLib.h> // For S_dev_*
#include <alarm.h>
#include <errlog.h>

#include <int64outRecord.h>
#include <epicsVersion.h>

#include "devObj.h"
#include "evr/evr.h"

#include "linkoptions.h"

#include <stdexcept>
#include <string>

/***************** Event *****************/

struct priv
{
EVR *evr;
char obj[30];
int event;
};

static const linkOptionDef eventdef[] =
{
linkString(priv, obj, "OBJ", 1, 0),
linkInt32(priv, event, "Code", 1, 0),
linkOptionEnd};

static long add_record(struct dbCommon *prec, struct link *link)
{
long ret = 0;
try
{
assert(link->type == INST_IO);

mrf::auto_ptr<priv> p(new priv);
p->event = 0;

if (linkOptionsStore(eventdef, p.get(), link->value.instio.string, 0))
throw std::runtime_error("Couldn't parse link string");

mrf::Object *O = mrf::Object::getObject(p->obj);
if (!O)
{
errlogPrintf("%s: failed to find object '%s'\n", prec->name, p->obj);
return S_db_errArg;
}
p->evr = dynamic_cast<EVR *>(O);
if (!p->evr)
throw std::runtime_error("Failed to lookup device");

if (!p->evr->interestedInEvent(p->event, true))
throw std::runtime_error("Failed to register interest");

prec->dpvt = (void *)p.release();

return 0;
}
catch (std::runtime_error &e)
{
recGblRecordError(S_dev_noDevice, (void *)prec, e.what());
ret = S_dev_noDevice;
}
catch (std::exception &e)
{
recGblRecordError(S_db_noMemory, (void *)prec, e.what());
ret = S_db_noMemory;
}
return ret;
}

static long del_record(struct dbCommon *prec)
{
priv *p = static_cast<priv *>(prec->dpvt);
long ret = 0;
if (!p)
return 0;
try
{

p->evr->interestedInEvent(p->event, false);
delete p;
prec->dpvt = 0;
}
catch (std::runtime_error &e)
{
recGblRecordError(S_dev_noDevice, (void *)prec, e.what());
ret = S_dev_noDevice;
}
catch (std::exception &e)
{
recGblRecordError(S_db_noMemory, (void *)prec, e.what());
ret = S_db_noMemory;
}
return ret;
}

static long get_ioint_info(int, dbCommon *prec, IOSCANPVT *io)
{
if (!prec->dpvt)
return S_db_errArg;
priv *p = static_cast<priv *>(prec->dpvt);
long ret = 0;
try
{

if (!p)
return 1;

*io = p->evr->eventOccurred(p->event);

return 0;
}
catch (std::runtime_error &e)
{
recGblRecordError(S_dev_noDevice, (void *)prec, e.what());
ret = S_dev_noDevice;
}
catch (std::exception &e)
{
recGblRecordError(S_db_noMemory, (void *)prec, e.what());
ret = S_db_noMemory;
}
*io = NULL;
return ret;
}

static long process_int64out(int64outRecord *prec)
{
priv *p = static_cast<priv *>(prec->dpvt);
long ret = 0;
try
{

if (p->event >= 0 && p->event <= 255)
post_event(p->event);

if (prec->tse == epicsTimeEventDeviceTime)
{
p->evr->getTimeStamp(&prec->time, p->event);
#ifdef DBR_UTAG
prec->utag = static_cast<epicsUTag>(prec->val);
p->evr->setUtag(prec->utag, p->event);
#endif
}

return 0;
}
catch (std::runtime_error &e)
{
recGblRecordError(S_dev_noDevice, (void *)prec, e.what());
ret = S_dev_noDevice;
}
catch (std::exception &e)
{
recGblRecordError(S_db_noMemory, (void *)prec, e.what());
ret = S_db_noMemory;
}
return ret;
}

static long add_int64out(struct dbCommon *precord)
{
return add_record(precord, &((struct int64outRecord *)precord)->out);
}

dsxt dxtI64OEventUtagEVR = {add_int64out, del_record};
static common_dset devI64OEventUtagEVR = {
6, NULL,
dset_cast(&init_dset<&dxtI64OEventUtagEVR>),
(DEVSUPFUN)init_record_empty,
(DEVSUPFUN)&get_ioint_info,
dset_cast(&process_int64out),
NULL};

extern "C"
{
epicsExportAddress(dset, devI64OEventUtagEVR);
}
11 changes: 11 additions & 0 deletions evrApp/src/evr/evr.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,17 @@ class epicsShareClass EVR : public mrf::ObjectInst<EVR>
epicsUInt32 SourceTSraw() const{return (TSSource)SourceTS();};
/*@}*/

#ifdef DBR_UTAG
/**\defgroup utagman UTAG Management
*
* Get/Set UTAG value for specific event
*/
/*@{*/
virtual epicsUTag getUtag(const epicsUInt32 event) const {return 0;};
virtual void setUtag(epicsUTag tag, const epicsUInt32 event) {};
/*@}*/
#endif

private:
bus_configuration busConfiguration;
}; // class EVR
Expand Down
2 changes: 2 additions & 0 deletions evrApp/src/evrSupportBase7.dbd
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# '@C=..., Code=hweventnum'
device(int64out, INST_IO, devI64OEventUtagEVR, "EVR Event Utag")
28 changes: 28 additions & 0 deletions evrMrmApp/src/drvem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,10 @@ try{
if(busConfig.busType==busType_pci)
mrf::SPIDevice::registerDev(n+":FLASH", mrf::SPIDevice(this, 1));

#ifndef DBR_UTAG
std::cout << "WARNING EVRMRM::EVRMRM epicsUTag not supported." << std::endl;
#endif

} catch (std::exception& e) {
printf("Aborting EVR initializtion: %s\n", e.what());
cleanup();
Expand Down Expand Up @@ -1563,3 +1567,27 @@ EVRMRM::seconds_tick(void *raw, epicsUInt32)
callbackRequest(&evr->timeSrc_cb);
}
}

#ifdef DBR_UTAG
// Get UTAG value for specific event
epicsUTag
EVRMRM::getUtag(const epicsUInt32 event) const {
if(event==0) return 0;
else if(event>255) throw std::runtime_error("Event code out of range");
SCOPED_LOCK(evrLock);

return events[event].utag;
}

// Set UTAG value for specific event
void
EVRMRM::setUtag(epicsUTag tag, const epicsUInt32 event) {
if(event==0) return;
else if(event>255) throw std::runtime_error("Event code out of range");
SCOPED_LOCK(evrLock);

// set UTAG value to particular event
events[event].utag = tag;
return;
}
#endif
14 changes: 12 additions & 2 deletions evrMrmApp/src/drvem.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,19 @@ struct eventCode {
size_t waitingfor;
bool again;

// UTAG associated to event
#ifdef DBR_UTAG
epicsUTag utag;
#endif
eventCode():owner(0), interested(0), last_sec(0)
,last_evt(0), waitingfor(0), again(false)
#ifdef DBR_UTAG
,utag(0)
#endif
{
scanIoInit(&occured);
// done_cb - initialized in EVRMRM::EVRMRM()
}
}
};

/**@brief Modular Register Map Event Receivers
Expand Down Expand Up @@ -192,7 +199,10 @@ class epicsShareClass EVRMRM : public mrf::ObjectInst<EVRMRM, EVR>,
{SCOPED_LOCK(evrLock);return count_FIFO_sw_overrate;}
virtual epicsUInt32 FIFOEvtCount() const OVERRIDE FINAL {return count_fifo_events;}
virtual epicsUInt32 FIFOLoopCount() const OVERRIDE FINAL {return count_fifo_loops;}

#ifdef DBR_UTAG
virtual epicsUTag getUtag(const epicsUInt32 event) const OVERRIDE FINAL;
virtual void setUtag(epicsUTag tag, const epicsUInt32 event) OVERRIDE FINAL;
#endif
void enableIRQ(void);

bool dcEnabled() const;
Expand Down
Loading