change counts to 64 bit integer, improve broken packet check, correct order of updating status

This commit is contained in:
2025-11-14 14:07:54 +01:00
parent c530de3566
commit 9d93238db4
4 changed files with 82 additions and 35 deletions

View File

@@ -101,6 +101,13 @@ asynStatus asynStreamGeneratorDriver::createInt32Param(
setIntegerParam(*variable, initialValue));
}
asynStatus asynStreamGeneratorDriver::createInt64Param(
asynStatus status, char *name, int *variable, epicsInt64 initialValue) {
// TODO should show error if there is one
return (asynStatus)(status | createParam(name, asynParamInt64, variable) |
setInteger64Param(*variable, initialValue));
}
asynStatus asynStreamGeneratorDriver::createFloat64Param(asynStatus status,
char *name,
int *variable,
@@ -120,7 +127,7 @@ asynStreamGeneratorDriver::asynStreamGeneratorDriver(
const char *detectorTopic, const int kafkaQueueSize,
const int kafkaMaxPacketSize)
: asynPortDriver(portName, 1, /* maxAddr */
asynInt32Mask | asynFloat64Mask |
asynInt32Mask | asynInt64Mask | asynFloat64Mask |
asynDrvUserMask, /* Interface mask */
asynInt32Mask, // | asynFloat64Mask, /* Interrupt mask */
0, /* asynFlags. This driver does not block and it is
@@ -173,7 +180,7 @@ asynStreamGeneratorDriver::asynStreamGeneratorDriver(
for (std::size_t i = 0; i < this->num_channels; ++i) {
memset(pv_name_buffer, 0, 100);
epicsSnprintf(pv_name_buffer, 100, P_CountsString, i);
status = createInt32Param(status, pv_name_buffer, P_Counts + i);
status = createInt64Param(status, pv_name_buffer, P_Counts + i);
memset(pv_name_buffer, 0, 100);
epicsSnprintf(pv_name_buffer, 100, P_RateString, i);
@@ -407,7 +414,7 @@ asynStatus asynStreamGeneratorDriver::writeInt32(asynUser *pasynUser,
}
} else if (isClearCount) {
if (!currentStatus) {
setIntegerParam(P_Counts[channelToClear], 0);
setInteger64Param(P_Counts[channelToClear], 0);
status = (asynStatus)callParamCallbacks();
} else {
return asynError;
@@ -447,7 +454,7 @@ void asynStreamGeneratorDriver::receiveUDP() {
const char *functionName = "receiveUDP";
asynStatus status = asynSuccess;
int isConnected = 1;
// int isConnected = 1;
std::size_t received;
int eomReason;
@@ -468,8 +475,10 @@ void asynStreamGeneratorDriver::receiveUDP() {
&received, &eomReason);
if (received) {
const uint16_t bufferLength = ((uint16_t *)buffer)[0];
const std::size_t headerLength = 42;
if ((received - 42) % 6 == 0) {
if (received >= headerLength && received == bufferLength * 2) {
epicsRingBytesPut(this->udpQueue, (char *)buffer, bufferSize);
@@ -499,7 +508,7 @@ void asynStreamGeneratorDriver::normaliseUDP() {
std::size_t received;
int eomReason;
// The correlation unit sents messages with a maximum size of 1500 bytes.
// The correlation unit sends messages with a maximum size of 1500 bytes.
// These messages don't have any obious start or end to synchronise
// against...
const std::size_t bufferSize = 1500;
@@ -516,6 +525,9 @@ void asynStreamGeneratorDriver::normaliseUDP() {
epicsInt32 droppedMessages = 0;
const UDPHeader *header;
const DetectorEvent *d_event;
const MonitorEvent *m_event;
NormalisedEvent ne;
while (true) {
@@ -524,9 +536,8 @@ void asynStreamGeneratorDriver::normaliseUDP() {
epicsRingBytesGet(this->udpQueue, (char *)buffer, bufferSize);
UDPHeader *header = (UDPHeader *)buffer;
std::size_t total_events = (header->BufferLength - 21) / 3;
header = (UDPHeader *)buffer;
const std::size_t total_events = (header->BufferLength - 21) / 3;
if (header->BufferNumber - lastBufferNumber[header->McpdID] > 1 &&
lastBufferNumber[header->McpdID] !=
@@ -540,22 +551,22 @@ void asynStreamGeneratorDriver::normaliseUDP() {
lastBufferNumber[header->McpdID]);
setIntegerParam(P_UdpDropped, ++droppedMessages);
}
lastBufferNumber[header->McpdID] = header->BufferNumber;
for (std::size_t i = 0; i < total_events; ++i) {
char *event = (buffer + 21 * 2 + i * 6);
const bool isMonitorEvent = event[5] & 0x80;
if (event[5] & 0x80) { // Monitor Event
MonitorEvent *m_event = (MonitorEvent *)event;
if (isMonitorEvent) {
m_event = (MonitorEvent *)event;
ne.timestamp =
header->nanosecs() + (uint64_t)m_event->nanosecs();
ne.source = 0;
ne.pixelId = m_event->DataID;
} else { // Detector Event
DetectorEvent *d_event = (DetectorEvent *)event;
} else {
d_event = (DetectorEvent *)event;
ne.timestamp =
header->nanosecs() + (uint64_t)d_event->nanosecs();
ne.source = header->McpdID;
@@ -661,7 +672,7 @@ void asynStreamGeneratorDriver::processEvents() {
epicsTimeStamp lastProcess = epicsTime::getCurrent();
epicsTimeStamp currentTime = lastProcess;
epicsInt32 counts[this->num_channels];
epicsInt64 counts[this->num_channels];
double elapsedSeconds = 0;
uint64_t startTimestamp = std::numeric_limits<uint64_t>::max();
uint64_t currTimestamp;
@@ -741,6 +752,8 @@ void asynStreamGeneratorDriver::processEvents() {
1;
elapsedSeconds = (eventsA[i].timestamp - startTimestamp) / 1e9;
// TODO should really check there an no more events with the
// same final timestamp
if ((countPreset && counts[presetChannel] >= countPreset) ||
(timePreset && elapsedSeconds > (double)timePreset))
break;
@@ -750,7 +763,7 @@ void asynStreamGeneratorDriver::processEvents() {
}
for (size_t i = 0; i < num_channels; ++i) {
setIntegerParam(P_Counts[i], counts[i]);
setInteger64Param(P_Counts[i], counts[i]);
}
setDoubleParam(P_ElapsedTime, elapsedSeconds);