ACQ400_XRM (xrmIoc)
Loading...
Searching...
No Matches
xrm_structs.h File Reference

Declarations for key XRM structures for internal and wire (external) use. More...

#include <epicsTypes.h>
#include <cstring>

Go to the source code of this file.

Classes

struct  FMT_ROW
 FMT_ROW defines a row of FMT: More...
struct  SOE_LUT_ROW
 SOE_LUT_ROW defines a row of SOE_LUT. More...
struct  SOE_HOLD_HEADER
 SOE_HOLD_HEADER Header for Hold Table. lut_row is a copy of the relevant SOE_LUT_ROW, for traceability. More...
struct  XRM_MAGPS_SAMPLE
struct  XRM_QPMS_SAMPLE
struct  XRM_INST_A_SAMPLE
struct  XRM_INST_B_SAMPLE

Macros

#define SOE_HOLD_HEADER_VERSION   1

Typedefs

typedef struct FMT_ROW FMT[FMT_ROWS]
 FMT : FNAL Multicast Table.
typedef struct SOE_LUT_ROW SOE_LUT[SOE_LUT_ROWS]
 SOE_LUT Sample On Event Lookup Table definition.
typedef epicsUInt32 U32
typedef struct SOE_HOLD_HEADERSOE_HOLD_TABLE
 SOE_HOLD_TABLE.

Functions

void print (FMT &fmt, bool verbose=false)
void print (SOE_LUT &lut, bool verbose=false)
void print (SOE_HOLD_HEADER *ht, bool verbose=false)

Variables

const epicsUInt16 EV99 = 65535U
const int FMT_ROWS = 64
const int SOE_LUT_ROWS = 64
const int SPAD0_SC = 0
const int SPAD1_TS = 1
const int SOE_HLD_ROWS = 64
const int XRM_MAGPS_AI16 = 32
const int XRM_MAGPS_DI32 = 2
const int XRM_MAGPS_SP32 = 6
const int XRM_QPMS_AI16 = 128
const int XRM_QPMS_DI32 = 0
const int XRM_QPMS_SP32 = 8
const int XRM_INST_A_AI16 = 32
const int XRM_INST_A_DI32 = 0
const int XRM_INST_A_SP32 = 4
const int XRM_INST_B_AI16 = 32
const int XRM_INST_B_DI32 = 1
const int XRM_INST_B_SP32 = 3

Detailed Description

Declarations for key XRM structures for internal and wire (external) use.

Typedef Documentation

◆ FMT

typedef struct FMT_ROW FMT[FMT_ROWS]

FMT : FNAL Multicast Table.

input from plant: 20Hz

This is the binary implementation that goes out on the wire.

each row of the FMT is a struct FMT_ROW.

ROW event pad client_data timestamp
0 u16 u16 u32 int64
1 u16 u16 u32 int64
2 u16 u16 u32 int64
.. ... ... ... ...
64 u16 u16 u32 int64

◆ SOE_HOLD_TABLE

SOE_HOLD_TABLE.

  • This is the OUTPUT from each CYCLE
  • For N events, the OUTPUT comprises:
    1. N+1 SOE_HOLD_HEADER rows, headers for N events + 1 row of zeros (DELIMITER)
    2. N RAW SAMPLE rows
  • The HEADER includes the geometry of the raw sample entries, so the data is self-describing.
  • The RAW SAMPLE row varies per unit type, the fixed header includes info to access the RAW SAMPLE.
  • We prefer to offer the RAW sample because
    • Blitting off a row of data is our most efficient transfer
    • No conversion to EGU's. User to do that thanks to $UUT:*:EOFF,ESLO
    • RAW sample includes METADATA for checking purposes.
  • To interpret a received HOLD DATA:
    • iterate the SOE_HOLD_HEADER rows until zero
    • use data_offset to access the data.
  • the first 4 data elements shown are in fact a copy of the relevant SOE_LUT_ROW, where
    • lut_row.pv_id, lut_row.event and lut_row.offset_us allow the user to check the row match with the original LUT definition.
    • lut_row.pad has the table version encoding as
    • 'S' << 16 | VERSION
    • currently the VERSION is 1, but this should allow us to check on any future upgrade.
  • In summary, the memory layout looks like this:
ROW pv_id,event,pad,offset_us client_data timestamp data_offset ss_u32 ai_count di_count sp_count
0 u32,u16,u16,int32 u32 int64 u16 u8 u8 u8 u8
1 u32,u16,u16,int32 u32 int64 u16 u8 u8 u8 u8
... u32,u16,u16,int32 u32 int64 u16 u8 u8 u8 u8
DEL 0,0,0,0 0 0 0 0 0 0 0
RAW ai di sp
R0 i16 u32 U32
R1 i16 u32 U32
Example 4 entries
sizeof(SOE_HOLD_HEADER==32)
XRMMAGPS: SSB=128 ruler in byte*2:
00000111112222233333444445555566666777778888899999AAAAABBBBBCCCC
0246802468024680246802468024680246802468024680246802468024680246
|SOE HOLD 1 |
|SOE HOLD 2 |
|SOE HOLD 3 |
|SOE HOLD 4 |
|0000000000000000|
|RAW SMPL 1 AIAIAIAIAIAIAIAIAIAIAIDIDISPSPSPSPSPSPSPSPSPSPSPSPSP|
|RAW SMPL 2 AIAIAIAIAIAIAIAIAIAIAIDIDISPSPSPSPSPSPSPSPSPSPSPSPSP|
|RAW SMPL 3 AIAIAIAIAIAIAIAIAIAIAIDIDISPSPSPSPSPSPSPSPSPSPSPSPSP|
|RAW SMPL 4 AIAIAIAIAIAIAIAIAIAIAIDIDISPSPSPSPSPSPSPSPSPSPSPSPSP|
showing the SOE HOLD struct on a line of bytes
0123456789012345678901246802468012468024680246802468024680246802468024680246
EV_______________________________| epicsUInt16 event;
__PA_____________________________| epicsUint16 pad; // aka VERSION
_____PVID ________________________| epicsUInt32 pv_id;
________OFFS_____________________| epicsInt32 offset_usec;
____________CLID_________________| epicsUInt32 client_data;
________________TIMSTAMP_________| epicsInt64 timestamp;
________________________DO_______| epicsUInt16 data_offset;
__________________________SADP___| epicsUInt8 ss_u32, ai_count, di_count, sp_count;
SOE_HOLD_HEADER Header for Hold Table. lut_row is a copy of the relevant SOE_LUT_ROW,...
Definition xrm_structs.h:103

Or in terms of offsets (sizes in bytes):

(base) pgm@hoy6:~/PROJECTS/ACQ400/ACQ400_XRM$ ./bin/linux-x86_64/xrm_ht_monitor -S
structure_test
sizeof SOE_HOLD_HEADER 32
offsetof lut_row.event : 0
offsetof lut_row.pad : 2
offsetof lut_row.pv_id : 4
offsetof lut_row.offset_us : 8
offsetof client_data : 12
offsetof timestamp : 16
offsetof data_offset : 24
offsetof ss_u32 : 26
offsetof ai_count : 27
offsetof di_count : 28
offsetof sp_count : 29

Actual wire protocol:

  • We meet the letter of the requirement by sending as a PVA ARRAY of U32
    • where NORD gives the overall size of the table, including DATA.
  • In the above example, MAGPS with 4 EVENTS,
    • NORD = (5 * sizeof(SOE_HOLD_HEADER))/sizeof(int32) + 4*SSB/sizeof(int32)
    • NORD = (5 * 32)/4 + 128
    • NORD = 168

@todo We've attempted to meet the spirit of the requirement using the PVXS API to create an Array of Groups, but this has not been a success. Happy to revisit later when we have an example that works.

◆ SOE_LUT

typedef struct SOE_LUT_ROW SOE_LUT[SOE_LUT_ROWS]

SOE_LUT Sample On Event Lookup Table definition.

matches events to PV's with a selectable time offset.

input from user at user-timescale.

in EPICS, we provide a "ROW_EDIT" PV to enable update, this works well for Phoebus and P4P

@todo: unsure how to make a direct pvput for the whole table.

  • Currently this would have to be an array of u32
  • Don't know how to make a EPICS V4 array for this
  • Workaround: the "ROW EDIT" is available to change a row at a time, or a set of rows.
ROW event pad pv_id offset_us
0 u16 u16 u32 int32
1 u16 u16 u32 int32
2 u16 u16 u32 int32
.. ... ... ... ...
64 u16 u16 u32 int32

Variable Documentation

◆ FMT_ROWS

const int FMT_ROWS = 64

define number of rows in FMT.

◆ SPAD0_SC

const int SPAD0_SC = 0

SPAD[0] is sample count (u32)

◆ SPAD1_TS

const int SPAD1_TS = 1

SPAD[1] is WR TS 3 bit seconds, 28 bit ticks