compiled soft_proton
Some checks failed
Example Action / Lint (push) Successful in 8s
Example Action / BuildAndTest (push) Failing after 15s

This commit is contained in:
2026-01-19 09:48:07 +01:00
parent 72b6affcf9
commit 42a91cf645
2 changed files with 67 additions and 68 deletions

View File

@@ -29,6 +29,7 @@ DBDS += src/daq.dbd
# Source files to build
SOURCES += src/daq.cpp
SOURCES += src/daq_soft_proton.c
SCRIPTS += scripts/daq_4ch.cmd
SCRIPTS += scripts/daq_8ch.cmd
@@ -36,6 +37,6 @@ SCRIPTS += scripts/daq_2nd_gen.cmd
SCRIPTS += sim/daq_sim.py
CXXFLAGS += -std=c++17
USR_CFLAGS += -Wall -Wextra #-Werror
USR_CFLAGS += -std=c11 -Wall -Wextra #-Werror
# MISCS would be the place to keep the stream device template files

View File

@@ -5,12 +5,13 @@
* Typically it is sampling the proton rate from HIPA via
* channel access.
*/
#include <stdio.h>
#include <string.h>
#include <dbDefs.h>
#include <errlog.h>
#include <aSubRecord.h>
#include <epicsTypes.h>
#include <epicsString.h>
#include <registryFunction.h>
#include <epicsExport.h>
@@ -32,6 +33,7 @@ struct spc_internal {
epicsUInt32 count_type;
epicsInt64 preset_count;
epicsFloat64 preset_time;
epicsFloat64 average_rate;
};
/* Enum with values for all commands
@@ -41,7 +43,7 @@ enum commands {
COUNT_PRESET = 1,
TIME_PRESET = 2,
PAUSE = 3,
CONTINUE = 4
CONTINUE = 4,
STOP = 5,
FULL_RESET = 6
};
@@ -57,45 +59,44 @@ enum status {
};
int handleNoop(struct spc_internal* spc_int, epicsChar** msg_text) {
const char[] funcstr = "handleNoop";
int handleNoop(struct spc_internal* spc, epicsOldString* msg_text) {
const char* funcstr = "handleNoop";
/* This shouldn't happen, but let's handle it just in case */
if (spc_int->status >= INVALID || spc->command_trig > FULL_RESET) {
*msg_text = "INVALID STATE!";
if (spc->status >= INVALID || spc->command_trig > FULL_RESET) {
strcpy(*msg_text, "INVALID STATE!");
errlogPrintf("%s: Status and/or command triggers are invalid \n"
"Status has value %d, \n Command trigger has value %d\n",
funcstr, spc_int->status, spc_int->command_trig);
funcstr, spc->status, spc->command_trig);
return 1;
}
/* Determine if we are idle and have received a noop command */
if (spc_int->status == IDLE) {
switch (spc_int->command_trig) {
if (spc->status == IDLE) {
switch (spc->command_trig) {
case PAUSE:
case CONTINUE:
case STOP:
*msg_text = "Can not PAUSE/CONTINUE/STOP during IDLE.";
strcpy(*msg_text, "Can not PAUSE/CONTINUE/STOP during IDLE.");
printf("%s: %s\n"
"Status has value %d, \n"
"Command trigger has value %d\n",
funcstr, spc_int->status, spc_int->command_trig);
*exit_status = 1; /* Positive value: No alarm and no output processing */
"Command trigger has value %d\n", *msg_text,
funcstr, spc->status, spc->command_trig);
return 1;
}
}
/* Determine if we are counting, low_rate or paused;
* and have received a noop command */
if (spc_int->status == COUNTING || spc_int->status == LOW_RATE ||
spc_int -> PAUSED) {
switch (spc_int->command_trig) {
if (spc->status == COUNTING || spc->status == LOW_RATE ||
spc->status == PAUSED) {
switch (spc->command_trig) {
case COUNT_PRESET:
case TIME_PRESET:
strcpy(*msg_text, "Already counting");
printf("%s: Already counting can not start a new count\n"
"Status has value %d, \n"
"Command trigger has value %d\n",
funcstr, spc_int->status, spc_int->command_trig);
*exit_status = 0;
funcstr, spc->status, spc->command_trig);
/* This case could be seen as OK.
* Nothing is keeping us from continuing, so let's do that. */
return 0;
@@ -103,12 +104,11 @@ int handleNoop(struct spc_internal* spc_int, epicsChar** msg_text) {
}
/* Determine if we are paused and a pause command */
if (spc_int->status == PAUSED && spc_int->command_trig == PAUSE) {
if (spc->status == PAUSED && spc->command_trig == PAUSE) {
errlogPrintf("%s: Already paused\n"
"Status has value %d, \n"
"Command trigger has value %d\n",
funcstr, spc_int->status, spc_int->command_trig);
*exit_status = 1; /* Positive value: No alarm and no output processing */
funcstr, spc->status, spc->command_trig);
return 1;
}
/* None of the noop cases detected */
@@ -117,62 +117,60 @@ int handleNoop(struct spc_internal* spc_int, epicsChar** msg_text) {
/*
* This function is called everytime the record processes.
* Even though this record can process arrays, we only use it with scalars,
* hence all the [0]'s.
* Even though this record can process arrays, we only use it with scalars.
*/
static long processEmulatedCounter(struct aSubRecord *psub)
{
const char[] funcstr = "processEmulatedCounter";
const char* funcstr = "processEmulatedCounter";
if (softProtonDebug) printf("%s was called\n", funcstr);
/* Declare internal variable */
struct spc_internal spc_int;
struct spc_internal spc = &spc_int;
int exit_status = 0;
struct spc_internal* spc = &spc_int;
/* Copy input values to a struct on the stack
* to simplify creation of functions */
spc->status = psub->a[0];
spc->monitor_count = psub->b[0];
spc->elapsed_time = psub->c[0];
spc->command_trig = psub->d[0];
spc->threshold = psub->e[0];
spc->count_type = psub->f[0];
spc->preset_count = psub->g[0];
spc->preset_time = psub->h[0];
spc->prev_proton_rate = psub->j[0];
spc->proton_rate = psub->l[0];
spc->status = *(epicsUInt32*)psub->a;
spc->monitor_count = *(epicsInt64*)psub->b;
spc->elapsed_time = *(epicsFloat64*)psub->c;
spc->command_trig = *(epicsUInt32*)psub->d;
spc->threshold = *(epicsFloat64*)psub->e;
spc->count_type = *(epicsUInt32*)psub->f;
spc->preset_count = *(epicsInt64*)psub->g;
spc->preset_time = *(epicsFloat64*)psub->h;
spc->prev_proton_rate = *(epicsFloat64*)psub->j;
spc->proton_rate = *(epicsFloat64*)psub->l;
/* Get the pointer to output values only to increase readability. */
epicsUInt32* status_out = psub->vala;
epicsInt64* monitor_count_out = psub->valb;
epicsFloat64* elaped_time_out = psub->valc;
epicsUInt32* command_trig_out = psub->vald;
epicsFloat64* prev_proton_rate_out = psub->vale;
epicsUInt32* is_low_rate_out = psub->valf;
epicsChar* msg_txt_out = &psub->valg;
epicsUInt32* status_out = (epicsUInt32*)psub->vala;
epicsInt64* monitor_count_out = (epicsInt64*)psub->valb;
epicsFloat64* elapsed_time_out = (epicsFloat64*)psub->valc;
epicsUInt32* command_trig_out = (epicsUInt32*)psub->vald;
epicsFloat64* prev_proton_rate_out = (epicsFloat64*)psub->vale;
epicsUInt32* is_low_rate_out = (epicsUInt32*)psub->valf;
epicsOldString* msg_txt_out = (epicsOldString*)psub->valg;
/* Always no matter what, handle the rate */
/* - Calculate average rate */
average_rate = (spc->proton_rate + spc->prev_proton_rate) / 2;
spc->average_rate = (spc->proton_rate + spc->prev_proton_rate) / 2;
/* - Store current rate as previous rate */
*prev_proton_rate_out = spc_int->proton_rate;
*prev_proton_rate_out = spc->proton_rate;
if (average_rate < spc->threshold) {
if (spc->average_rate < spc->threshold) {
*is_low_rate_out = 0; /* Illogical but 0 is low_rate, 1 high rate */
} else {
*is_low_rate_out = 1; /* Illogical but 0 is low_rate, 1 high rate */
}
/* Handle noop situations both valid and invalid */
if (handle_noop(spc, &msg_txt_out))
if (handleNoop(spc, msg_txt_out))
/* We have state that prohibits further processing */
return 0;
return 0;
/* Commands with priority always yielding IDLE status first */
if (spc->command_trig == FULL_RESET) {
msg_txt_out = "Full reset!";
strcpy(*msg_txt_out, "Full reset!");
/* Reset everything, done! */
*status_out = IDLE;
*monitor_count_out = 0;
@@ -192,7 +190,7 @@ static long processEmulatedCounter(struct aSubRecord *psub)
} else if (((spc->status == COUNTING || spc->status == LOW_RATE)
&& spc->command_trig == PAUSE) ||
(spc->status == PAUSED && spc->command_trig == NONE)) {
msg_txt_out = "Stopping!";
strcpy(*msg_txt_out, "Stopping!");
/* We are counting or at low rate and received pause.
* Also we are paused but have received no command, this
* is probably slightly inaccurate but simplifies things.*/
@@ -206,7 +204,7 @@ static long processEmulatedCounter(struct aSubRecord *psub)
/* Determine if we are idle but received a count command */
if (softProtonDebug) printf("%s: Starting Count!\n", funcstr);
/* Sanity check that count type is properly stored */
if (command_trig != count_type) {
if (spc->command_trig != spc->count_type) {
if (softProtonDebug) printf("%s: Count type not stored!\n", funcstr);
return -1;
}
@@ -215,22 +213,22 @@ static long processEmulatedCounter(struct aSubRecord *psub)
*monitor_count_out = 0;
*elapsed_time_out = 0;
*command_trig_out = NONE;
if (is_low_rate_out == 1) {
if (*is_low_rate_out == 1) {
*status_out = LOW_RATE;
} else {
*status_out = COUNTING;
}
return 0;
} else if ((((spc_int->status == LOW_RATE && spc_int->command_trig == NONE) ||
(spc_int->status == LOW_RATE && spc_int->command_trig == CONTINUE)))
&& is_low_rate_out == 1) {
} else if ((((spc->status == LOW_RATE && spc->command_trig == NONE) ||
(spc->status == LOW_RATE && spc->command_trig == CONTINUE)))
&& *is_low_rate_out == 1) {
*status_out = LOW_RATE;
/* LOW_RATE or resuming from PAUSE */
*command_trig_out = NONE;
/* Maintain same counter and time*/
*monitor_count_out = spc_int->monitor_count;
*elapsed_time_out = spc_int->elapsed_time;
return 0
*monitor_count_out = spc->monitor_count;
*elapsed_time_out = spc->elapsed_time;
return 0;
}
/* Ending up here means:
@@ -247,12 +245,12 @@ static long processEmulatedCounter(struct aSubRecord *psub)
*status_out = COUNTING;
/* Increament counter and time */
*monitor_count_out = spc_int->monitor_count +
average_rate * SOFT_PROTON_SAMPLE_RATE;
*elapsed_time_out = spc_int->elapsed_time + SOFT_PROTON_SAMPLE_RATE;
*monitor_count_out = spc->monitor_count +
spc->average_rate * SOFT_PROTON_SAMPLE_RATE;
*elapsed_time_out = spc->elapsed_time + SOFT_PROTON_SAMPLE_RATE;
/* Check if we are below threshold */
if (is_low_rate_out == 1) {
if (*is_low_rate_out == 1) {
*status_out = LOW_RATE;
} else {
*status_out = COUNTING;
@@ -261,11 +259,11 @@ static long processEmulatedCounter(struct aSubRecord *psub)
/* Check if count is finished normally.
* Higher priority than low rate */
if (/* Time based count finished */
(*elapsed_time_out >= spc_int->preset_time &&
spc_int->count_type = TIME_PRESET) ||
(*elapsed_time_out >= spc->preset_time &&
spc->count_type == TIME_PRESET) ||
/* Monitor based count finished */
(*monitor_count_out >= spc_int->preset_time &&
spc_int->count_type = COUNT_PRESET)) {
(*monitor_count_out >= spc->preset_time &&
spc->count_type == COUNT_PRESET)) {
*status_out = IDLE;
}