Skip to content
Snippets Groups Projects
Commit 0c16c4b2 authored by Jonathan Hanks's avatar Jonathan Hanks
Browse files

Updating simple_pv to allow for more int types.

 * Reworking the simpleIntPv and simpleIntAttribute interface to be templates to allow for semi-arbitrary int PV types.
   * Done to support int, uint, ushort types in the epics sequencer.
parent 8b26b1db
No related branches found
No related tags found
2 merge requests!439RCG 5.0 release fro deb 10,!343convert the sequencer to C++
add_library(simple_pv simple_pv.cc
simple_epics.cc
simple_epics_internal.cc)
simple_pv_internal.cc)
target_include_directories(simple_pv PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(simple_pv PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/private)
target_link_libraries(simple_pv PUBLIC epics::cas epics::gdd /usr/lib/epics/lib/linux-x86_64/libCom.so)
target_requires_cpp11(simple_pv PUBLIC)
add_library(pv::simple_pv ALIAS simple_pv)
......
//
// Created by jonathan.hanks on 3/16/22.
//
#ifndef DAQD_TRUNK_SIMPLE_EPICS_INTERNAL_INT_HH
#define DAQD_TRUNK_SIMPLE_EPICS_INTERNAL_INT_HH
#include "simple_pv_types.hh"
#include "simple_pv_internal.hh"
#include <mutex>
#include <type_traits>
#include <iostream>
namespace simple_epics
{
namespace detail
{
/*!
* @brief A representation of a R/O integer in a PV
*/
template < typename IntType >
class simpleBasicIntPV : public simplePVBase
{
static_assert( std::is_integral< IntType >::value,
"Must use an interger type" );
public:
simpleBasicIntPV( caServer& server,
pvBasicIntAttributes< IntType > attr )
: simplePVBase( ), server_{ server }, attr_{ std::move(
attr ) },
val_( ), monitored_{ false }
{
std::once_flag initted{ };
std::call_once(
initted, []( ) { simpleBasicIntPV::setup_func_table( ); } );
val_ = new gddScalar( gddAppType_value,
ait_data_type< IntType >::value );
val_->unreference( );
set_value( *attr_.src( ) );
}
~simpleBasicIntPV( ) override = default;
caStatus
read( const casCtx& ctx, gdd& prototype ) override
{
return get_func_table( ).read( *this, prototype );
}
caStatus
write( const casCtx& ctx, const gdd& value ) override
{
if ( attr_.mode( ) != PVMode::ReadWrite )
{
return S_casApp_noSupport;
}
aitInt32 newValue;
value.get( &newValue, ait_data_type< IntType >::value );
set_value( newValue );
*const_cast< IntType* >( attr_.src( ) ) = newValue;
return S_casApp_success;
}
void destroy( ) override{ };
aitEnum
bestExternalType( ) const override
{
return val_->primitiveType( );
}
const char*
getName( ) const override
{
return attr_.name( ).c_str( );
}
caStatus
interestRegister( ) override
{
monitored_ = true;
return S_casApp_success;
}
void
interestDelete( ) override
{
monitored_ = false;
}
void
update( ) override
{
set_value( *attr_.src( ) );
}
private:
void
set_value( int value )
{
int current_value = 0;
val_->getConvert( current_value );
if ( current_value == value )
{
return;
}
val_->putConvert( value );
aitTimeStamp ts = aitTimeStamp( epicsTime::getCurrent( ) );
val_->setTimeStamp( &ts );
aitUint16 stat = epicsAlarmNone;
aitUint16 sevr = epicsSevNone;
if ( value >= attr_.alarm_high( ) )
{
stat = epicsAlarmHiHi;
sevr = epicsSevMajor;
}
else if ( value <= attr_.alarm_low( ) )
{
stat = epicsAlarmLoLo;
sevr = epicsSevMajor;
}
else if ( value >= attr_.warn_high( ) )
{
stat = epicsAlarmHigh;
sevr = epicsSevMinor;
}
else if ( value <= attr_.warn_low( ) )
{
stat = epicsAlarmLow;
sevr = epicsSevMinor;
}
val_->setSevr( sevr );
val_->setStat( stat );
if ( monitored_ )
{
casEventMask mask =
casEventMask( server_.valueEventMask( ) );
bool alarm_changed = ( stat != val_->getStat( ) ||
sevr != val_->getSevr( ) );
if ( alarm_changed )
{
mask |= server_.alarmEventMask( );
}
postEvent( mask, *val_ );
}
}
static void
setup_func_table( )
{
auto install = []( const char* name,
gddAppFuncTableStatus (
simpleBasicIntPV::*handler )( gdd& ) ) {
gddAppFuncTableStatus status;
// char error_string[100];
status = get_func_table( ).installReadFunc( name, handler );
if ( status != S_gddAppFuncTable_Success )
{
// errSymLookup(status, error_string,
// sizeof(error_string));
// throw std::runtime_error(error_string);
throw std::runtime_error(
"Unable to initialize pv lookup table" );
}
};
install( "units", &simpleBasicIntPV::read_attr_not_handled );
install( "status", &simpleBasicIntPV::read_status );
install( "severity", &simpleBasicIntPV::read_severity );
install( "maxElements",
&simpleBasicIntPV::read_attr_not_handled );
install( "precision", &simpleBasicIntPV::read_precision );
install( "alarmHigh", &simpleBasicIntPV::read_alarm_high );
install( "alarmLow", &simpleBasicIntPV::read_alarm_low );
install( "alarmHighWarning",
&simpleBasicIntPV::read_warn_high );
install( "alarmLowWarning", &simpleBasicIntPV::read_warn_low );
install( "maxElements",
&simpleBasicIntPV::read_attr_not_handled );
install( "graphicHigh",
&simpleBasicIntPV::read_attr_not_handled );
install( "graphicLow",
&simpleBasicIntPV::read_attr_not_handled );
install( "controlHigh",
&simpleBasicIntPV::read_attr_not_handled );
install( "controlLow",
&simpleBasicIntPV::read_attr_not_handled );
install( "enums", &simpleBasicIntPV::read_attr_not_handled );
install( "menuitem", &simpleBasicIntPV::read_attr_not_handled );
install( "timestamp",
&simpleBasicIntPV::read_attr_not_handled );
install( "value", &simpleBasicIntPV::read_value );
}
static gddAppFuncTable< simpleBasicIntPV >&
get_func_table( )
{
static gddAppFuncTable< simpleBasicIntPV > func_table;
return func_table;
}
gddAppFuncTableStatus
read_attr_not_handled( gdd& g )
{
return S_casApp_success;
}
gddAppFuncTableStatus
read_status( gdd& g )
{
g.putConvert( val_->getStat( ) );
return S_casApp_success;
}
gddAppFuncTableStatus
read_severity( gdd& g )
{
g.putConvert( val_->getSevr( ) );
return S_casApp_success;
}
gddAppFuncTableStatus
read_precision( gdd& g )
{
g.putConvert( 0 );
return S_casApp_success;
}
gddAppFuncTableStatus
read_alarm_high( gdd& g )
{
g.putConvert( attr_.alarm_high( ) );
return S_casApp_success;
}
gddAppFuncTableStatus
read_alarm_low( gdd& g )
{
g.putConvert( attr_.alarm_low( ) );
return S_casApp_success;
}
gddAppFuncTableStatus
read_warn_high( gdd& g )
{
g.putConvert( attr_.warn_high( ) );
return S_casApp_success;
}
gddAppFuncTableStatus
read_warn_low( gdd& g )
{
g.putConvert( attr_.warn_low( ) );
return S_casApp_success;
}
gddAppFuncTableStatus
read_value( gdd& g )
{
auto status = gddApplicationTypeTable::app_table.smartCopy(
&g, val_.get( ) );
return ( status ? S_cas_noConvert : S_casApp_success );
}
caServer& server_;
pvBasicIntAttributes< IntType > attr_;
smartGDDPointer val_;
bool monitored_;
};
using simpleIntPV = simpleBasicIntPV< std::int32_t >;
using simpleUIntPV = simpleBasicIntPV< std::uint32_t >;
using simpleUShortPV = simpleBasicIntPV< std::uint16_t >;
} // namespace detail
} // namespace simple_epics
#endif // DAQD_TRUNK_SIMPLE_EPICS_INTERNAL_INT_HH
//
// Created by jonathan.hanks on 1/6/20.
// Created by jonathan.hanks on 3/16/22.
//
#ifndef DAQD_TRUNK_SIMPLE_PV_INTERNAL_HH
#define DAQD_TRUNK_SIMPLE_PV_INTERNAL_HH
#include "simple_epics.hh"
#include <memory>
#include "simple_epics.hh"
#include "simple_pv_int.hh"
namespace simple_epics
{
namespace detail
{
// std::make_unique didn't make it into C++11, so
// to allow this to work in a pre C++14 world, we
// provide a simple replacement.
......@@ -36,80 +37,6 @@ namespace simple_epics
new T( std::forward< Ts >( params )... ) );
}
class setup_int_pv_table;
/*!
* @brief A representation of a R/O integer in a PV
*/
class simpleIntPV : public simplePVBase
{
friend class setup_int_pv_table;
public:
simpleIntPV( caServer& server, pvIntAttributes attr )
: simplePVBase( ), server_{ server }, attr_{ std::move(
attr ) },
val_( ), monitored_{ false }
{
val_ = new gddScalar( gddAppType_value, aitEnumInt32 );
val_->unreference( );
set_value( *attr_.src( ) );
}
~simpleIntPV( ) override;
caStatus read( const casCtx& ctx, gdd& prototype ) override;
caStatus write( const casCtx& ctx, const gdd& value ) override;
void destroy( ) override{ };
aitEnum bestExternalType( ) const override;
const char*
getName( ) const override
{
return attr_.name( ).c_str( );
}
caStatus interestRegister( ) override;
void interestDelete( ) override;
void update( ) override;
private:
void set_value( int value );
static void setup_func_table( );
static gddAppFuncTable< simpleIntPV >& get_func_table( );
gddAppFuncTableStatus
read_attr_not_handled( gdd& g )
{
return S_casApp_success;
}
gddAppFuncTableStatus read_status( gdd& g );
gddAppFuncTableStatus read_severity( gdd& g );
gddAppFuncTableStatus read_precision( gdd& g );
gddAppFuncTableStatus read_alarm_high( gdd& g );
gddAppFuncTableStatus read_alarm_low( gdd& g );
gddAppFuncTableStatus read_warn_high( gdd& g );
gddAppFuncTableStatus read_warn_low( gdd& g );
gddAppFuncTableStatus read_value( gdd& g );
caServer& server_;
pvIntAttributes attr_;
smartGDDPointer val_;
bool monitored_;
};
class setup_string_pv_table;
/*!
* @brief A representation of a R/O integer in a PV
......@@ -248,9 +175,7 @@ namespace simple_epics
smartGDDPointer val_;
bool monitored_;
};
} // namespace detail
} // namespace simple_epics
#endif // DAQD_TRUNK_SIMPLE_PV_INTERNAL_HH
//
// Created by jonathan.hanks on 3/16/22.
//
#ifndef DAQD_TRUNK_SIMPLE_PV_TYPES_HH
#define DAQD_TRUNK_SIMPLE_PV_TYPES_HH
#include <cstdint>
#include <string>
#include "aitTypes.h"
namespace simple_epics
{
namespace detail
{
/**
* @brief ait_data_type is used to map between C++ types and the
* CAS ait (architecture independent) data types.
* @tparam T The type to map
*/
template < typename T >
struct ait_data_type
{
static const aitEnum value = aitEnumInvalid;
};
template <>
struct ait_data_type< std::int16_t >
{
static const aitEnum value = aitEnumInt16;
};
template <>
struct ait_data_type< std::uint16_t >
{
static const aitEnum value = aitEnumUint16;
};
template <>
struct ait_data_type< std::int32_t >
{
static const aitEnum value = aitEnumInt32;
};
template <>
struct ait_data_type< std::uint32_t >
{
static const aitEnum value = aitEnumUint32;
};
template <>
struct ait_data_type< float >
{
static const aitEnum value = aitEnumFloat32;
};
template <>
struct ait_data_type< double >
{
static const aitEnum value = aitEnumFloat64;
};
template <>
struct ait_data_type< const char* >
{
static const aitEnum value = aitEnumString;
};
template <>
struct ait_data_type< std::string >
{
static const aitEnum value = aitEnumString;
};
} // namespace detail
} // namespace simple_epics
#endif // DAQD_TRUNK_SIMPLE_PV_TYPES_HH
......@@ -2,7 +2,7 @@
// Created by jonathan.hanks on 12/20/19.
//
#include "simple_epics.hh"
#include "simple_epics_internal.hh"
#include "simple_pv_internal.hh"
#include <stdexcept>
#include <algorithm>
......@@ -11,6 +11,24 @@ namespace simple_epics
{
Server::~Server( ) = default;
void
Server::addPV( pvUShortAttributes attr )
{
std::lock_guard< std::mutex > l_( m_ );
auto it = pvs_.find( attr.name( ) );
if ( it != pvs_.end( ) )
{
throw std::runtime_error(
"Duplicate key insertion to the epics db" );
}
std::string name{ attr.name( ) };
pvs_.insert(
std::make_pair( std::move( name ),
detail::make_unique_ptr< detail::simpleUShortPV >(
*this, std::move( attr ) ) ) );
}
void
Server::addPV( pvIntAttributes attr )
{
......@@ -29,6 +47,24 @@ namespace simple_epics
*this, std::move( attr ) ) ) );
}
void
Server::addPV( pvUIntAttributes attr )
{
std::lock_guard< std::mutex > l_( m_ );
auto it = pvs_.find( attr.name( ) );
if ( it != pvs_.end( ) )
{
throw std::runtime_error(
"Duplicate key insertion to the epics db" );
}
std::string name{ attr.name( ) };
pvs_.insert(
std::make_pair( std::move( name ),
detail::make_unique_ptr< detail::simpleUIntPV >(
*this, std::move( attr ) ) ) );
}
void
Server::addPV( pvStringAttributes attr )
{
......
......@@ -9,6 +9,7 @@
#include <memory>
#include <mutex>
#include <string>
#include <type_traits>
#include <gddAppFuncTable.h>
#include <epicsTimer.h>
......@@ -47,14 +48,20 @@ namespace simple_epics
* @note this is given a pointer to the data. This value is only read
* when a Server object is told to update its data.
*/
class pvIntAttributes
template < typename IntType >
class pvBasicIntAttributes
{
static_assert( std::is_integral< IntType >::value,
"integer type required" );
public:
pvIntAttributes( std::string pv_name,
int* value,
std::pair< int, int > alarm_range,
std::pair< int, int > warn_range,
PVMode mode = PVMode::ReadOnly )
using value_type = IntType;
pvBasicIntAttributes( std::string pv_name,
IntType* value,
std::pair< IntType, IntType > alarm_range,
std::pair< IntType, IntType > warn_range,
PVMode mode = PVMode::ReadOnly )
: name_{ std::move( pv_name ) },
alarm_low_{ alarm_range.first },
......@@ -69,28 +76,28 @@ namespace simple_epics
return name_;
}
int
IntType
alarm_high( ) const noexcept
{
return alarm_high_;
}
int
IntType
alarm_low( ) const noexcept
{
return alarm_low_;
}
int
IntType
warn_high( ) const noexcept
{
return warn_high_;
}
int
IntType
warn_low( ) const noexcept
{
return warn_low_;
}
const int*
const IntType*
src( ) const noexcept
{
return src_;
......@@ -105,14 +112,19 @@ namespace simple_epics
private:
std::string name_;
int alarm_high_;
int alarm_low_;
int warn_high_;
int warn_low_;
IntType alarm_high_;
IntType alarm_low_;
IntType warn_high_;
IntType warn_low_;
PVMode mode_;
int* src_{ nullptr };
PVMode mode_;
IntType* src_{ nullptr };
};
using pvIntAttributes = pvBasicIntAttributes< std::int32_t >;
using pvUIntAttributes = pvBasicIntAttributes< std::uint32_t >;
using pvUShortAttributes = pvBasicIntAttributes< std::uint16_t >;
static_assert( sizeof( std::int32_t ) == sizeof( int ),
"int must be 32 bit" );
/*!
* @brief A description of a PV, used to describe a string PV to the server.
......@@ -255,7 +267,9 @@ namespace simple_epics
/*!
* @brief Add a PV to the server.
*/
void addPV( pvUShortAttributes attr );
void addPV( pvIntAttributes attr );
void addPV( pvUIntAttributes attr );
void addPV( pvStringAttributes attr );
void addPV( pvDoubleAttributes attr );
......
......@@ -3,7 +3,7 @@
//
#include "simple_pv.h"
#include "simple_epics.hh"
#include "simple_epics_internal.hh"
#include "simple_pv_internal.hh"
#include <algorithm>
#include <memory>
......@@ -29,15 +29,14 @@ simple_pv_server_create( const char* prefix, SimplePV* pvs, int pv_count )
std::for_each(
pvs,
pvs + pv_count,
[&prefix_, pv_server]( const SimplePV& pv ) -> void {
[ &prefix_, pv_server ]( const SimplePV& pv ) -> void {
if ( !pv.name || !pv.data )
{
return;
}
switch ( pv.pv_type )
{
case SIMPLE_PV_INT:
{
case SIMPLE_PV_INT: {
pv_server->addPV( simple_epics::pvIntAttributes(
prefix_ + pv.name,
reinterpret_cast< int* >( pv.data ),
......@@ -45,14 +44,12 @@ simple_pv_server_create( const char* prefix, SimplePV* pvs, int pv_count )
std::make_pair< int, int >( pv.warn_low, pv.warn_high ) ) );
}
break;
case SIMPLE_PV_STRING:
{
case SIMPLE_PV_STRING: {
pv_server->addPV( simple_epics::pvStringAttributes(
prefix_ + pv.name, reinterpret_cast< char* >( pv.data ) ) );
}
break;
case SIMPLE_PV_DOUBLE:
{
case SIMPLE_PV_DOUBLE: {
pv_server->addPV( simple_epics::pvDoubleAttributes(
prefix_ + pv.name,
reinterpret_cast< double* >( pv.data ),
......
//
// Created by jonathan.hanks on 1/6/20.
//
#include "simple_epics_internal.hh"
#include "simple_pv_internal.hh"
#include <cstring>
namespace simple_epics
{
namespace detail
{
class setup_int_pv_table
{
public:
setup_int_pv_table( )
{
simpleIntPV::setup_func_table( );
}
};
setup_int_pv_table pv_int_table_setup_;
class setup_string_pv_table
{
public:
......@@ -41,214 +30,6 @@ namespace simple_epics
setup_double_pv_table pv_double_table_setup_;
/*
* Start of int PV
*/
gddAppFuncTable< simpleIntPV >&
simpleIntPV::get_func_table( )
{
static gddAppFuncTable< simpleIntPV > func_table;
return func_table;
}
simpleIntPV::~simpleIntPV( ) = default;
gddAppFuncTableStatus
simpleIntPV::read_status( gdd& g )
{
g.putConvert( val_->getStat( ) );
return S_casApp_success;
}
gddAppFuncTableStatus
simpleIntPV::read_severity( gdd& g )
{
g.putConvert( val_->getSevr( ) );
return S_casApp_success;
}
gddAppFuncTableStatus
simpleIntPV::read_precision( gdd& g )
{
g.putConvert( 0 );
return S_casApp_success;
}
gddAppFuncTableStatus
simpleIntPV::read_alarm_high( gdd& g )
{
g.putConvert( attr_.alarm_high( ) );
return S_casApp_success;
}
gddAppFuncTableStatus
simpleIntPV::read_alarm_low( gdd& g )
{
g.putConvert( attr_.alarm_low( ) );
return S_casApp_success;
}
gddAppFuncTableStatus
simpleIntPV::read_warn_high( gdd& g )
{
g.putConvert( attr_.warn_high( ) );
return S_casApp_success;
}
gddAppFuncTableStatus
simpleIntPV::read_warn_low( gdd& g )
{
g.putConvert( attr_.warn_low( ) );
return S_casApp_success;
}
gddAppFuncTableStatus
simpleIntPV::read_value( gdd& g )
{
auto status =
gddApplicationTypeTable::app_table.smartCopy( &g, val_.get( ) );
return ( status ? S_cas_noConvert : S_casApp_success );
}
void
simpleIntPV::setup_func_table( )
{
auto install =
[]( const char* name,
gddAppFuncTableStatus ( simpleIntPV::*handler )( gdd& ) ) {
gddAppFuncTableStatus status;
// char error_string[100];
status = get_func_table( ).installReadFunc( name, handler );
if ( status != S_gddAppFuncTable_Success )
{
// errSymLookup(status, error_string,
// sizeof(error_string));
// throw std::runtime_error(error_string);
throw std::runtime_error(
"Unable to initialize pv lookup table" );
}
};
install( "units", &simpleIntPV::read_attr_not_handled );
install( "status", &simpleIntPV::read_status );
install( "severity", &simpleIntPV::read_severity );
install( "maxElements", &simpleIntPV::read_attr_not_handled );
install( "precision", &simpleIntPV::read_precision );
install( "alarmHigh", &simpleIntPV::read_alarm_high );
install( "alarmLow", &simpleIntPV::read_alarm_low );
install( "alarmHighWarning", &simpleIntPV::read_warn_high );
install( "alarmLowWarning", &simpleIntPV::read_warn_low );
install( "maxElements", &simpleIntPV::read_attr_not_handled );
install( "graphicHigh", &simpleIntPV::read_attr_not_handled );
install( "graphicLow", &simpleIntPV::read_attr_not_handled );
install( "controlHigh", &simpleIntPV::read_attr_not_handled );
install( "controlLow", &simpleIntPV::read_attr_not_handled );
install( "enums", &simpleIntPV::read_attr_not_handled );
install( "menuitem", &simpleIntPV::read_attr_not_handled );
install( "timestamp", &simpleIntPV::read_attr_not_handled );
install( "value", &simpleIntPV::read_value );
}
caStatus
simpleIntPV::read( const casCtx& ctx, gdd& prototype )
{
return get_func_table( ).read( *this, prototype );
}
caStatus
simpleIntPV::write( const casCtx& ctx, const gdd& value )
{
if ( attr_.mode( ) != PVMode::ReadWrite )
{
return S_casApp_noSupport;
}
aitInt32 newValue;
value.get( &newValue, aitEnumInt32 );
set_value( newValue );
*const_cast<int*>(attr_.src()) = newValue;
return S_casApp_success;
}
aitEnum
simpleIntPV::bestExternalType( ) const
{
return val_->primitiveType( );
}
caStatus
simpleIntPV::interestRegister( )
{
monitored_ = true;
return S_casApp_success;
}
void
simpleIntPV::interestDelete( )
{
monitored_ = false;
}
void
simpleIntPV::update( )
{
set_value( *attr_.src( ) );
}
void
simpleIntPV::set_value( int value )
{
int current_value = 0;
val_->getConvert( current_value );
if ( current_value == value )
{
return;
}
val_->putConvert( value );
aitTimeStamp ts = aitTimeStamp( epicsTime::getCurrent( ) );
val_->setTimeStamp( &ts );
aitUint16 stat = epicsAlarmNone;
aitUint16 sevr = epicsSevNone;
if ( value >= attr_.alarm_high( ) )
{
stat = epicsAlarmHiHi;
sevr = epicsSevMajor;
}
else if ( value <= attr_.alarm_low( ) )
{
stat = epicsAlarmLoLo;
sevr = epicsSevMajor;
}
else if ( value >= attr_.warn_high( ) )
{
stat = epicsAlarmHigh;
sevr = epicsSevMinor;
}
else if ( value <= attr_.warn_low( ) )
{
stat = epicsAlarmLow;
sevr = epicsSevMinor;
}
val_->setSevr( sevr );
val_->setStat( stat );
if ( monitored_ )
{
casEventMask mask = casEventMask( server_.valueEventMask( ) );
bool alarm_changed =
( stat != val_->getStat( ) || sevr != val_->getSevr( ) );
if ( alarm_changed )
{
mask |= server_.alarmEventMask( );
}
postEvent( mask, *val_ );
}
}
/*
* Start of string PV
*/
......@@ -533,7 +314,7 @@ namespace simple_epics
aitFloat64 newValue;
value.get( &newValue, aitEnumFloat64 );
set_value( newValue );
*const_cast<double*>(attr_.src()) = newValue;
*const_cast< double* >( attr_.src( ) ) = newValue;
return S_casApp_success;
}
......
......@@ -7,34 +7,45 @@
#include "fdManager.h"
std::atomic<bool> done{false};
std::atomic< bool > done{ false };
void
signal_handler(int dummy)
signal_handler( int dummy )
{
done = true;
}
int
main(int argc, char* argv[])
main( int argc, char* argv[] )
{
using pvInt = simple_epics::pvIntAttributes;
simple_epics::Server server{};
simple_epics::Server server{ };
int int1val = 0;
pvInt int1{"int1", &int1val, std::make_pair(-1,100), std::make_pair(-1, 100), simple_epics::PVMode::ReadWrite};
int int1val = 0;
pvInt int1{ "int1",
&int1val,
std::make_pair( -1, 100 ),
std::make_pair( -1, 100 ),
simple_epics::PVMode::ReadWrite };
double float1val = 0.0;
simple_epics::pvDoubleAttributes float1{ "float1",
&float1val,
std::make_pair( -1, 100 ),
std::make_pair( -1, 100 ),
simple_epics::PVMode::ReadWrite };
server.addPV(int1);
server.addPV( int1 );
server.addPV( float1 );
std::signal(SIGINT, signal_handler);
server.update();
while (!done)
std::signal( SIGINT, signal_handler );
server.update( );
while ( !done )
{
if (int1val == 42)
if ( int1val == 42 )
{
done = true;
}
server.update();
server.update( );
fileDescriptorManager.process( 0. );
}
return 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment