The aim of this talk is to provide a practical, more detailed introduction to EPICS V4, enabling you to create your own V4 services and use V4 tools. It will cover
The focus will be on the C++ implementation.
A summary, in advance, of the talk is:
There are a number of resources for EPICS V4:
The C++ tar can be downloaded from the EPICS V4 site. The latest version is 4.5.0.
C++ uses the EPICS build facility (see EPICS V3 Application Developer Guide, chapter 4) and builds against EPICS base.
Once you unzip the 4.5.0 tar, all you need do is set your CONFIG and RELEASE through CONFIG_SITE.local and RELEASE.local (or through the host and target specific CONFIG and RELEASE files) and type make. An example RELEASE.local is provided.
A config script is provided so that, if you're on a Linux system and if you have the shell variable EPICS_BASE defined to your EPICS base installation (and exported), then likely all you need do is:
chmod +x configure.sh make configure make
See the getting started guide, for details.
The latest can be obtained by cloning from the GitHub repos
The modules all build using the EPICS build system and make
. There's no top-level Makefile so you'll need to build each separately, create your own makefile or borrow the one from the release tar.
See the getting started guide, for details.
The pvaSrv module has a test example of an IOC running pvaSrv. To run this, having already built pvaSrv (and its dependencies, pvCommonCPP, pvDataCPP, pvAccessCPP), cd
to your pvaSrv directory and then do the following:
[pc0046 pvaSrv]$ cd testTop/iocBoot/testDbPv [pc0046 testDbPv]$ ../../bin/$EPICS_HOST_ARCH/testDbPv st.cmd
You should see
< envPaths epicsEnvSet("ARCH","linux-x86_64") epicsEnvSet("IOC","testDbPv") epicsEnvSet("TOP","/epicsv4/pvaSrv/testTop") epicsEnvSet("PVASRV","/epicsv4/pvaSrv/testTop/..") epicsEnvSet("EV4_BASE","/epicsv4") epicsEnvSet("PVACCESS","/epicsv4/pvAccessCPP") epicsEnvSet("PVDATA","/epicsv4/pvDataCPP") epicsEnvSet("PVCOMMON","/epicsv4/pvCommonCPP") epicsEnvSet("EPICS_BASE","/dls_sw/epics/R<IP_ADDRESS>/base") cd /epicsv4/pvaSrv/testTop ## Register all support components dbLoadDatabase("dbd/testDbPv.dbd") testDbPv_registerRecordDeviceDriver(pdbbase) ## Load record instances dbLoadRecords("db/dbInteger.db","name=byte01,type=byter") ... (ommitting most of the dbLoadRecords commands) dbLoadRecords("db/dbCounter.db","name=counter03"); cd /epicsv4/pvaSrv/testTop/iocBoot/testDbPv iocInit() Starting iocInit ############################################################################ ## EPICS R<IP_ADDRESS> $Date: Mon 2012-12-17 14:11:47 -0600$ ## EPICS Base built Mar 18 2015 ############################################################################ iocRun: All initialization complete epicsThreadSleep(2.0) casr Channel Access Server V4.13 No clients connected. startPVAServer VERSION : pvAccess Server v4.1.0-SNAPSHOT PROVIDER_NAMES : dbPv BEACON_ADDR_LIST : AUTO_BEACON_ADDR_LIST : 1 BEACON_PERIOD : 15 BROADCAST_PORT : 5076 SERVER_PORT : 5075 RCV_BUFFER_SIZE : 16384 IGNORE_ADDR_LIST: STATE : INITIALIZED dbpf string01 10.1 DBR_STRING: "10.1" dbpf wait01 1 DBR_SHORT: 1 0x1 dbpf wait02 2 DBR_SHORT: 2 0x2 dbpf wait03 3 DBR_SHORT: 3 0x3
For each dbLoadRecords command, the IOC should have the corresponding records:
epics> dbl double01 double02 ... (omitting most of the records) bigstring01 epics>
The IOC's records are published over channel access and we can, for example, use channel access tools in the usual way:
[pc0012 ~]$ caget double01 double01 0
The IOC's records are also published over pvAccess. The startPVAServer
command starts the pvAccess server. The server is using the default pvAccess port which is 5075. pvaSrv's dbPv provider has been registered with pvAccess automatically.
We can use Version 4 client tools to issue requests over pvAccess (more on this in the next section), for example we can use the Version 4 equivalent of caget:
[pc0012 ~]$ pvget double01 double01 0
Here pvget is creating a pvAccess channel and sending a Channel Get request over pvAccess. The channel is provided on the server side by the dbPv provider which accesses the V3 IOC database directly.
The pvDatabaseCPP module has a number of examples:
This example publishes a V4 PV using a pvDatabase record. This implements a simple HelloWorld service through puts and gets to subfields, rather than using the RPC operation.
It can be run one of two ways. As a standard application or through the IOC shell.
To run this without the IOC shell cd
to pvDatabaseCPP/exampleServer and then do the following:
[pc0046 exampleServer]$ ./bin/$EPICS_HOST_ARCH/exampleServerMain
You should see something like:
[pc0046 exampleServer]$ ./bin/linux-x86_64/exampleServerMain VERSION : pvAccess Server v4.1.0-SNAPSHOT PROVIDER_NAMES : local BEACON_ADDR_LIST : AUTO_BEACON_ADDR_LIST : 1 BEACON_PERIOD : 15 BROADCAST_PORT : 5076 SERVER_PORT : 5075 RCV_BUFFER_SIZE : 16384 IGNORE_ADDR_LIST: STATE : INITIALIZED exampleServer laptoprecordListPGRPC traceRecordPGRPC Type 'exit' to stop:
From another terminal, preferably remotely, you can use pvget to fetch the current value of exampleServer:
[pc0012 ~]$ pvget exampleServer exampleServer structure structure argument string value structure result string value time_t timeStamp <undefined> 0
If you set the argument field using pvput:
[pc0012 ~]$ pvput -r "argument" exampleServer Dave Old : structure structure argument string value New : structure structure argument string value Dave
then pvget returns:
[pc0012 ~]$ pvget exampleServer exampleServer structure structure argument string value Dave structure result string value Hello Dave time_t timeStamp 2015-05-21T09:15:47.559 0
There are two other PVs. laptoprecordListPGRPC is a RecordListRecord. It implements a put get service that queries the database and returns the records present (the regular expression option isn't implemented). An initial pvget gives:
[pc0012 ~]$ pvget laptoprecordListPGRPC laptoprecordListPGRPC structure structure argument string database string regularExpression structure result string status string[] names
The provider in pvDatabase has a database called "master". Putting the value master gives:
[pc0012 ~]$ pvput -r "argument" laptoprecordListPGRPC master "" Old : structure structure argument string database string regularExpression New : structure structure argument string database master string regularExpression [pc0012 ~]$ pvget laptoprecordListPGRPC laptoprecordListPGRPC structure structure argument string database master string regularExpression structure result string status string[] names [exampleServer,laptoprecordListPGRPC,traceRecordPGRPC]
The other is a TraceRecord that set the trace-level of other records:
pc0012 ~]$ pvget traceRecordPGRPC traceRecordPGRPC structure structure argument string recordName int level 0 structure result string status [pc0012 ~]$ pvput -r "argument" traceRecordPGRPC exampleServer 3 Old : structure structure argument string recordName int level 0 New : structure structure argument string recordName exampleServer int level 3 [pc0012 ~]$ pvget traceRecordPGRPC traceRecordPGRPC structure structure argument string recordName exampleServer int level 3 structure result string status success
Setting the trace to 1 causes trace to be outputting on Channel connection changes. 2 on connection changes for ChannelGet, ChannelPut, ChannelMonitor and so on. 3 is most verbose, printing locking and group put changes. E.g. for trace level 3 and a pvget the server prints
PVRecord::addPVRecordClient() exampleServer PVRecord::lock() exampleServer PVRecord::unlock() exampleServer ChannelGetLocal::create recordName exampleServer PVRecord::lock() exampleServer PVRecord::unlock() exampleServer ChannelGetLocal::get PVRecord::lock() exampleServer PVRecord::unlock() exampleServer ChannelGetLocal::destroy destroyed 0 ~ChannelGetLocal() ChannelLocal::destroy() beingDestroyed 0 PVRecord::removePVRecordClient() exampleServer PVRecord::lock() exampleServer PVRecord::unlock() exampleServer ~ChannelLocal()
This example can be run through the IOC shell. cd
to pvDatabaseCPP/exampleServer/iocBoot/exampleServer and runs as follows:
../../bin/linux-x86_64/exampleServer st.cmd
exampleServer creates an IOC shell command exampleServerCreateRecord
. The boot script uses this to create a PV called exampleServer as in the non-IOC shell version.
There are a number of pvAccess tools which currently reside in pvAccessCPP. The examples assume pvAccess/bin/${EPICS_HOST_ARCH}
is in your path.
pvinfo is the Version 4 equivalent of cainfo. It gives information on the location, state and introspection data of a PV.
For example if you're running the pvaSrv example above:
[pc0012 ~]$ pvinfo enum01 CHANNEL : enum01 STATE : CONNECTED ADDRESS : <IP_ADDRESS>:5075 epics:nt/NTEnum:1.0 enum_t value int index string[] choices alarm_t alarm int severity int status string message time_t timeStamp long secondsPastEpoch int nanoseconds int userTag
If you're using the 4.4 release code, pvinfo necessarily uses pvAccess on the wire.
From 4.5.0 onwards you can also use the channel access provider to get information on a PV using channel access on the wire. By default pvinfo will use pvAccess, but you can specify either channel access or pvAccess with the -p
option supplying either ca
or pva
. For example,
pvinfo -p ca enum01 CHANNEL : enum01 STATE : CONNECTED ADDRESS : <IP_ADDRESS>:5064 epics:nt/NTEnum:1.0 enum_t value int index string[] choices alarm_t alarm int severity int status string message time_t timeStamp long secondsPastEpoch int nanoseconds int userTag
will use channel access on the wire, so it can be used with existing Version 3 PVs without modifying the IOC.
From 4.5.0 onwards pvinfo also understands a URI syntax, where the URI's scheme is either pva or ca. The following are equivalent and use pvAccess on the wire:
[pc0012 ~]$ pvinfo enum01 [pc0012 ~]$ pvinfo -p pva enum01 [pc0012 ~]$ pvinfo pva:///enum01and the following use channel access:
[pc0012 ~]$ pvinfo -p ca enum01 [pc0012 ~]$ pvinfo ca:///enum01
pvinfo -h
shows a full set of options.
pvget is the Version 4 equivalent of caget. By default, if a PV has a value
field, such as for a Version 3 IOC record accessed via pvaSrv or caProvider, pvget fetches its value.
[pc0012 ~]$ pvget double01 double01 0otherwise it gets the whole structure, for example
[pc0012 point]$ pvinfo point01 CHANNEL : point01 STATE : CONNECTED ADDRESS : <IP_ADDRESS>:5075 point double x double y [pc0012 ~]$ pvget point01 point01 point double x 1.2 double y 1.7
pvget has support for enumerated types, which are encoded as structures. By default pvget displays the string choice corresponding to the value of the index field. The -n
option displays the index and the -i
option turns off the support so expressing the result as a structure.
[pc0012 ~]$ pvget enumPV1 enumPV1 Off [pc0012 ~]$ pvget -n enumPV1 enumPV1 0 [pc0012 ~]$ pvget -i enumPV1 enumPV1 structure enum_t value int index 0 string[] choices [Off,On]
Like pvinfo, the 4.4 release version of pvget is pvAccess only, but from 4.5.0 onwards pvget has channel access support through caProvider and supports the -p
option and URI syntax. So for pvAccess the following will work
pvget double01 pvget -p pva double01 pvget pva:///double01
and for channel access you can do:
pvget -p ca double01 pvget ca:///double01
When creating the pvAccess Channel Get, a structure, pvRequest, is supplied. This specifies which fields should be retrieved and any options. It is possible to specify this using the -r
option.
The simplest type of request is a comma separated list of fields, for example:
[pc0012 ~]$ pvinfo enumPV1 CHANNEL : enumPV1 STATE : CONNECTED ADDRESS : <IP_ADDRESS>:5075 epics:nt/NTEnum:1.0 enum_t value int index string[] choices alarm_t alarm int severity int status string message time_t timeStamp long secondsPastEpoch int nanoseconds int userTag [pc0012 ~]$ pvget -r "value" enumPV1 enumPV1 structure enum_t value Off [pc0012 ~]$ pvget -r "value,timeStamp" enumPV1 structure enum_t value Off time_t timeStamp 2015-05-19T12:54:00.368 0 [pc0012 ~]$ pvget -r "value,timeStamp,alarm" enumPV1 enumPV1 structure enum_t value Off time_t timeStamp 2015-05-19T12:54:00.368 0 alarm_t alarm NO_ALARM NO_STATUS <no message>
The request is of one of the following forms:
The "field" syntax allows you to get any substructure of the top-level structure. field_def is a list of fields, separated by commas. Periods are used to request subfields and curly braces for requesting multiple subfields."field()" get all fields.
pvget -r "field()" enumPV1 epics:nt/NTEnum:1.0 enum_t value Off alarm_t alarm NO_ALARM NO_STATUS <no message> time_t timeStamp 2015-05-19T12:54:00.368 0 [pc0012 ~]$ pvget -r "field(value,alarm)" enumPV1 structure enum_t value Off alarm_t alarm NO_ALARM NO_STATUS <no message> [pc0012 ~]$ pvget -r "field(value.choices)" enumPV1 enumPV1 structure structure value string[] choices [Off,On] [pc0012 ~]$ pvget -r "field(value,alarm.severity,timeStamp{secondsPastEpoch,nanoseconds})" enumPV1 enumPV1 structure enum_t value Off structure alarm int severity 0 structure timeStamp long secondsPastEpoch<PHONE_NUMBER> int nanoseconds 368293834
The field options are currently fully supported by pvDatabase. pvaSrv supports lists of fields, but does not support the "." and "{}" syntax. The ca provider has only limited supported for the field syntax in request.
The record options currently supported are "process" and "block". "process" indicated that the process variable should be processed before performing the get. "block" is only used for puts to do put with callback.
The specification for pvRequest is still under development. The last draft is available at http://epics-pvdata.sourceforge.net/informative/pvRequest.html. See in particular the Syntax section.
pvget with the -m option is the Version 4 eqivalent of camonitor. It functions in a similar fashion to pvget without -m. In particular it supports the request, enum and provider options and the URI syntax. For example
[pc0012 ~]$ pvget -m ca:///SR-DI-DCCT-01:SIGNAL SR-DI-DCCT-01:SIGNAL 190.702 SR-DI-DCCT-01:SIGNAL 190.694 SR-DI-DCCT-01:SIGNAL 190.684 SR-DI-DCCT-01:SIGNAL 190.675 ^C [pc0012 ~]$ pvget -m counter01 counter01 4 counter01 5 counter01 6 counter01 7
pvput is the Version 4 equivalent of caput. By default, if a PV has a value
field, such as for a Version 3 IOC record accessed via pvaSrv or caProvider, pvput puts to its value.
pc0012 ~]$ pvput double01 3.14 Old : double01 0 New : double01 3.14
As for pvget, pvput has good support for enums:
pvput enumPV1 On Old : enumPV1 Off New : enumPV1 On [pc0012 ~]$ pvput enumPV1 0 Old : enumPV1 On New : enumPV1 Off [pc0012 ~]$ pvput -n enumPV1 1 Old : enumPV1 0 New : enumPV1 1
For puts to arrays you supply the number of elements, followed by the element values themselves:
[pc0012 ~]$ pvput doubleArray01 2 3.14 2.718 Old : doubleArray01 0 New : doubleArray01 2 3.14 2.718
The request syntax also works for pvput:
pvput -r "field(value.choices)" enumPV1 2 Disabled Enabled Old : structure structure value string[] choices [Off,On] New : structure structure value string[] choices [Disabled,Enabled]
Puts to multiple fields are possible:
[pc0012 ~]$ pvput -r "field(value{index,choices})" enumPV1 1 2 Stop Start Old : structure structure value int index 0 string[] choices [Disabled,Enabled] New : structure structure value int index 1 string[] choices [Stop,Start]
pvlist prints the PVs for a given server address list/GUID:
pc0012 ~]$ pvlist <IP_ADDRESS>:5075 double01 double02 double03 counter01 counter02 counter03 int01 ... bigstring01
This is similar to pvget, but has more support for normative types. It can also be used to query services using the "-s" option. It supports the -p provider option and URI syntax from version 4.4.0. See eget -h
for more details.
exampleCPP contains an extremely simple example of an RPC service. It's based on the equivalent Java service in exampleJava.
The client sends a structure containing a person's name, e.g.:
structure string personsname Dave
and the server responds with a structure containing a greeting:
structure string greeting Hello Dave
which the client prints.
To run the example, on the server cd
to exampleCPP/HelloWorld and then start the server:
[pc0046 HelloWorld]$ ./helloServerRunner
You should see something like:
[pc0046 HelloWorld]$ ./helloServerRunner pvAccess Server v4.1.0-SNAPSHOT VERSION : pvAccess Server v4.1.0-SNAPSHOT PROVIDER_NAMES : rpcService BEACON_ADDR_LIST : AUTO_BEACON_ADDR_LIST : 1 BEACON_PERIOD : 15 BROADCAST_PORT : 5076 SERVER_PORT : 5075 RCV_BUFFER_SIZE : 16384 IGNORE_ADDR_LIST: STATE : INITIALIZED
Then on the client (also in exampleCPP/HelloWorld) send the request:
[pc0012 HelloWorld]$ ./helloClientRunner Dave Hello Dave
The service can be queried using eget with the -z and -N options (to send as a "pure query", i.e. not an NTURI) and to turn off error messages about non-normative types:"
[pc0012 HelloWorld]$ eget -zN -s helloService -a "personsname=Dave" structure string greeting Hello Dave
You can also use pvinfo:
[pc0012 HelloWorld]$ pvinfo helloService CHANNEL : helloService STATE : CONNECTED ADDRESS : <IP_ADDRESS>:5075 (null introspection data)
To implement an RPC service all you need to do is inherit from epics::pvAccess::RPCService, implementing its request() member function.
So in the HelloWorld example
/** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS exampleCPP is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ // HelloService.h #ifndef HELLOSERVICERPC_H #define HELLOSERVICERPC_H #include <pv/rpcService.h> namespace epics { namespace helloService { /** * Declaration of the Hello World RPC service. */ class HelloService : public epics::pvAccess::RPCService { public: POINTER_DEFINITIONS(HelloService); epics::pvData::PVStructurePtr request( epics::pvData::PVStructurePtr const & args ) throw (epics::pvAccess::RPCRequestException); }; } } #endif
The implementation of request receives a structure containing the RPC arguments, checks it is of the right form and constructs a response structure:
/** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS exampleCPP is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ // HelloService.cpp #include <pv/rpcServer.h> #include "HelloService.h" using namespace epics::pvData; namespace epics { namespace helloService { // returns this service's result structure type definition. StructureConstPtr makeResponseStructure() { FieldCreatePtr fieldCreate = getFieldCreate(); FieldBuilderPtr builder = fieldCreate->createFieldBuilder(); return builder->add("greeting", pvString)->createStructure(); } // Definition of the Hello World RPC service. epics::pvData::PVStructurePtr HelloService::request( epics::pvData::PVStructurePtr const & pvArgument ) throw (pvAccess::RPCRequestException) { epics::pvData::PVStringPtr nameField = pvArgument->getStringField("personsname"); if (!nameField) { throw pvAccess::RPCRequestException(Status::STATUSTYPE_ERROR, "PVString field with name 'personsname' expected."); } PVStructurePtr result( getPVDataCreate()->createPVStructure(makeResponseStructure())); PVStringPtr greetingValueField = result->getStringField("greeting"); greetingValueField->put("Hello " + nameField->get()); return result; } } }
The service is then registered with the RPCServer and started in the main function.
/** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS exampleCPP is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ // HelloServiceMain.cpp #include <pv/rpcServer.h> #include "HelloService.h" using namespace epics::pvAccess; // Main is the entry point of the HelloService server side executable. int main(int argc,char *argv[]) { RPCServer server; // register our service as "helloService" server.registerService("helloService", RPCService::shared_pointer(new epics::helloService::HelloService())); server.printInfo(); server.run(); return 0; }
It's relatively simply to modify the implementation to write your own service.
#include <pv/pvData.h> #include <string> #include <iostream> using namespace epics::pvData; using namespace std; int main (int argc, char *argv[]) { FieldBuilderPtr builder = getFieldCreate()->createFieldBuilder(); StructureConstPtr aggregateStruc = builder->setId("NTAgregate") ->add("value", pvDouble) ->add("N", pvInt) ->add("dispersion", pvDouble) ->add("max", pvDouble) ->add("min", pvDouble) ->add("description", pvDouble) ->createStructure(); cout << *aggregateStruc << endl; cout << aggregateStruc->getType() << endl; cout << aggregateStruc->getID() << endl << endl; PVStructurePtr aggregate1 = getPVDataCreate()->createPVStructure(aggregateStruc); cout << *aggregate1 << endl; cout << *aggregateStruc << endl << endl; cout << aggregateStruc->getType() << endl; cout << aggregateStruc->getID() << endl << endl; PVStructurePtr aggregate1 = getPVDataCreate()->createPVStructure(aggregateStruc); PVDoublePtr valueField = aggregate1->getSubField>PVDouble>("value"); valueField->put(3.14); aggregate1->getSubField<PVInt>("N")->put(42); aggregate1->getSubField<PVDouble>("dispersion")->put(0.05); aggregate1->getSubField<PVDouble>("max")->put(300.5); aggregate1->getSubField<PVDouble>("min")->put(299.3); aggregate1->getSubField<PVString>("description")->put("Beam current statistics"); cout << *aggregate1 << endl; return 0; }
#include <pv/pvData.h> #include <epicsTime.h> #include <string> #include <iostream> using namespace epics::pvData; using namespace std; int main (int argc, char *argv[]) { FieldBuilderPtr builder = getFieldCreate()->createFieldBuilder(); StructureConstPtr timeStampStruc = builder->setId("time_t") ->add("secondsPastEpoch", pvLong) ->add("nanoseconds", pvInt) ->add("userTag", pvInt) ->createStructure(); cout << *timeStampStruc << endl << endl; StructureConstPtr alarmStruc = builder->setId("alarm_t") ->add("severity", pvInt) ->add("status", pvInt) ->add("message", pvString) ->createStructure(); cout << *alarmStruc << endl << endl; StructureConstPtr ntscalarStruc = builder->setId("NTScalar") ->add("value", pvDouble) ->add("description", pvString) ->add("alarm", alarmStruc) ->add("timeStamp", timeStampStruc) ->createStructure(); PVStructurePtr ntscalar1 = getPVDataCreate()->createPVStructure(ntscalarStruc); PVStructurePtr alarmField = ntscalar1->getSubField<PVStructure>("alarm"); alarmField->getSubField<PVInt>("severity")->put(2); alarmField->getSubField<PVInt>("status")->put(4); alarmField->getSubField<PVString>("message")->put("LINK_ALARM"); epicsTimeStamp ts = epicsTime::getCurrent(); PVStructurePtr timeStampField = ntscalar1->getSubField<PVStructure>("timeStamp"); timeStampField->getSubField<PVLong>("secondsPastEpoch")->put(ts.secPastEpoch + POSIX_TIME_AT_EPICS_EPOCH); timeStampField->getSubField<PVInt>("nanoseconds")->put(ts.nsec); timeStampField->getSubField<PVInt>("userTag")->put(0); cout << *ntscalar1 << endl; return 0; }
#include <pv/pvData.h> #include <pv/standardField.h> #include <pv/timeStamp.h> #include <pv/pvTimeStamp.h> #include <pv/alarm.h> #include <pv/pvAlarm.h> #include <string> #include <iostream> using namespace epics::pvData; using namespace std; int main (int argc, char *argv[]) { FieldCreatePtr fieldCreate = getFieldCreate(); FieldBuilderPtr builder = fieldCreate->createFieldBuilder(); StandardFieldPtr standardField = getStandardField(); StructureConstPtr ntscalarStruc = builder->setId("NTScalar") ->add("value", pvDouble) ->add("description", pvString) ->add("alarm", standardField->alarm()) ->add("timeStamp", standardField->timeStamp()) ->createStructure(); cout << *ntscalarStruc << endl << endl; PVStructurePtr ntscalar1 = getPVDataCreate()->createPVStructure(ntscalarStruc); PVTimeStamp pvTimeStamp; TimeStamp timeStamp; pvTimeStamp.attach(ntscalar1->getSubField("timeStamp")); timeStamp.getCurrent(); pvTimeStamp.set(timeStamp); PVAlarm pvAlarm; PVStructurePtr alarmField = ntscalar1->getSubField<PVStructure>("alarm"); pvAlarm.attach(alarmField); Alarm alarm; alarm.setSeverity(majorAlarm); alarm.setStatus(dbStatus); alarm.setMessage("LINK_ALARM"); pvAlarm.set(alarm); //alarmField->getSubField<PVInt>("severity")->put(2); //alarmField->getSubField<PVInt>("status")->put(4); //alarmField->getSubField<PVString>("message")->put("LINK_ALARM"); cout << *ntscalar1 << endl; return 0; }
/** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS exampleCPP is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ #include <pv/pvData.h> #include <pv/standardField.h> #include <string> #include <iostream> using namespace epics::pvData; using namespace std; int main (int argc, char *argv[]) { FieldCreatePtr fieldCreate = getFieldCreate(); FieldBuilderPtr builder = fieldCreate->createFieldBuilder(); StandardFieldPtr standardField = getStandardField(); StructureConstPtr ntScalarArrayStruc = builder->setId("ntScalarArray") ->addArray("value", pvDouble) ->add("description", pvString) ->add("alarm", standardField->alarm()) ->add("timeStamp", standardField->timeStamp()) ->createStructure(); cout << *ntScalarArrayStruc << endl << endl; PVStructurePtr ntScalarArray1 = getPVDataCreate()->createPVStructure(ntScalarArrayStruc); PVDoubleArrayPtr valueField = ntScalarArray1->getSubField<PVDoubleArray>("value"); { PVDoubleArray::svector values; values.push_back(3.14); values.push_back(2.718); PVDoubleArray::const_svector cvalues = freeze(values); valueField->replace(cvalues); cout << *ntScalarArray1 << endl << endl; } { PVDoubleArray::const_svector cvalues = valueField->view(); for (size_t i = 0; i < cvalues.size(); ++i) cout << cvalues[i] << endl; for (PVDoubleArray::const_svector::const_iterator it = cvalues.begin(); it != cvalues.end(); ++it) cout << *it << endl; } { PVDoubleArray::svector values(valueField->reuse()); values.resize(2); values[0]= 1.5; values[1]= 2.5; PVDoubleArray::const_svector cvalues = freeze(values); valueField->replace(cvalues); cout << *ntScalarArray1 << endl << endl; } return 0; }
/** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS exampleCPP is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ #include <pv/pvData.h> #include <pv/standardField.h> #include <string> #include <iostream> using namespace epics::pvData; using namespace std; int main (int argc, char *argv[]) { FieldCreatePtr fieldCreate = getFieldCreate(); FieldBuilderPtr builder = fieldCreate->createFieldBuilder(); StandardFieldPtr standardField = getStandardField(); UnionConstPtr valueUnion = builder->add("doubleValue",pvDouble) ->add("intValue",pvInt) ->addArray("doubleArrayValue",pvDouble) ->createUnion(); StructureConstPtr ntunionStruc = builder->setId("NTUnion") ->add("value", valueUnion) ->createStructure(); cout << *ntunionStruc << endl << endl; PVStructurePtr ntunion1 = getPVDataCreate()->createPVStructure(ntunionStruc); cout << *ntunion1 << endl << endl; PVUnionPtr valueField = ntunion1->getSubField<PVUnion>("value"); cout << *valueField << endl; cout << valueField->getUnion()->isVariant() << endl << endl; valueField->select<PVDouble>("doubleValue")->put(3.14); valueField->postPut(); cout << *ntunion1 << endl << endl; valueField->select<PVInt>("intValue")->put(42); valueField->postPut(); cout << *ntunion1 << endl << endl; PVDoubleArray::svector s; s.push_back(1.5); s.push_back(2.7); valueField->select<PVDoubleArray>("doubleArrayValue")->replace(freeze(s)); valueField->postPut(); cout << *ntunion1 << endl << endl; return 0; }
/** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS exampleCPP is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ #include <pv/pvData.h> #include <pv/standardField.h> #include <string> #include <iostream> using namespace epics::pvData; using namespace std; void setValueDouble_ref(const PVUnionPtr & unionField, double value) { PVDoublePtr storedValue = getPVDataCreate()->createPVScalar<PVDouble>(); storedValue->put(value); unionField->set(storedValue); } template<typename PVS> void setValue_ref(const PVUnionPtr & unionField, typename PVS::value_type value) { typename PVS::shared_pointer storedValue = getPVDataCreate()->createPVScalar<PVS>(); storedValue->put(value); unionField->set(storedValue); } void setValueDouble_val(const PVUnionPtr & unionField, double value) { PVDoublePtr storedValue = unionField->get<PVDouble>(); if (storedValue.get() == NULL) storedValue = getPVDataCreate()->createPVScalar<PVDouble>(); storedValue->put(value); unionField->set(storedValue); } template<typename PVS> void setValue_val(const PVUnionPtr & unionField, typename PVS::value_type value) { typename PVS::shared_pointer storedValue = unionField->get<PVS>(); if (storedValue.get() == NULL) storedValue = getPVDataCreate()->createPVScalar<PVS>(); storedValue->put(value); //unionField->postPut(); unionField->set(storedValue); } int main (int argc, char *argv[]) { FieldCreatePtr fieldCreate = getFieldCreate(); FieldBuilderPtr builder = fieldCreate->createFieldBuilder(); StandardFieldPtr standardField = getStandardField(); StructureConstPtr ntunionStruc = builder->setId("NTUnion") ->add("value", fieldCreate->createVariantUnion()) //->add("description", pvString) //->add("alarm", standardField->alarm()) //->add("timeStamp", standardField->timeStamp()) ->createStructure(); cout << *ntunionStruc << endl << endl; cout << ntunionStruc->getType() << endl; PVStructurePtr ntunion1 = getPVDataCreate()->createPVStructure(ntunionStruc); cout << *ntunion1 << endl << endl; PVUnionPtr valueField = ntunion1->getSubField<PVUnion>("value"); cout << *valueField << endl; cout << valueField->getUnion()->isVariant() << endl << endl; setValueDouble_ref(valueField, 299.5); cout << *ntunion1 << endl << endl; setValue_ref<PVInt>(valueField, 50); cout << *ntunion1 << endl << endl; setValue_ref<PVDouble>(valueField, 299.5); cout << *ntunion1 << endl << endl; setValue_ref<PVDouble>(valueField, 301.5); cout << *ntunion1 << endl << endl; setValue_ref<PVInt>(valueField, 42); cout << *ntunion1 << endl << endl; setValue_val<PVInt>(valueField, 25); cout << *ntunion1 << endl << endl; setValue_val<PVDouble>(valueField, 302.0); cout << *ntunion1 << endl << endl; return 0; }
/** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS exampleCPP is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ #include <pv/pvData.h> #include <pv/standardField.h> #include <string> #include <iostream> using namespace epics::pvData; using namespace std; template<typename PVS> void setValue(const PVUnionPtr & unionField, typename PVS::value_type value) { typename PVS::shared_pointer storedValue = unionField->get<PVS>(); if (storedValue.get() == NULL) storedValue = getPVDataCreate()->createPVScalar<PVS>(); storedValue->put(value); unionField->set(storedValue); } int main (int argc, char *argv[]) { FieldCreatePtr fieldCreate = getFieldCreate(); FieldBuilderPtr builder = fieldCreate->createFieldBuilder(); StandardFieldPtr standardField = getStandardField(); StructureConstPtr ntattributeStruc = builder->setId("NTUnion") ->add("value", fieldCreate->createVariantUnion()) ->add("name", pvString) ->add("description", pvString) ->createStructure(); StructureConstPtr ntndarrayStruc = builder->setId("NTNDArray") ->addArray("attribute", ntattributeStruc) ->createStructure(); cout << *ntndarrayStruc << endl << endl; cout << ntndarrayStruc->getField("attribute")->getType() << endl; PVStructurePtr ntndarray1 = getPVDataCreate()->createPVStructure(ntndarrayStruc); cout << *ntndarray1 << endl << endl; PVStructureArrayPtr attributeField = ntndarray1->getSubField<PVStructureArray>("attribute"); PVStructureArray::svector attributes; { PVStructurePtr attributeElement = getPVDataCreate()->createPVStructure(ntattributeStruc); setValue<PVInt>(attributeElement->getSubField<PVUnion>("value"), 0); attributeElement->getSubField<PVString>("name")->put("ColorMode"); attributeElement->getSubField<PVString>("description")->put("Color Mode"); attributes.push_back(attributeElement); } { PVStructurePtr attributeElement = getPVDataCreate()->createPVStructure(ntattributeStruc); setValue<PVInt>(attributeElement->getSubField<PVUnion>("value"), 299.5); attributeElement->getSubField<PVString>("name")->put("SR-DI-DCCT-01:SIGNAL"); attributeElement->getSubField<PVString>("description")->put("Beam current"); attributes.push_back(attributeElement); } attributeField->replace(freeze(attributes)); cout << *ntndarray1 << endl << endl; return 0; }


If you need help on a specific part of your code, you can highlight them to notify the helper.
Search your prior requests' title.
R{{$root.requests.length-$index}} {{request.title | limitTo:45}}{{request.title.length > 45 ? '...' : ''}}
{{tag}}
Q: {{request.request_description}}
File:{{request.changelog[1].title}}
{{request.notification}}
asked
Helper: {{request.currentHelperName}} is working
{{selectedObj.notification}}
asked
{{selectedObj.title }}
{{tag}}
Q: {{selectedObj.request_description}}
File:{{selectedObj.changelog[1].title}}
{{selectedObj.notification}}
asked
No response yet!
-
Answer
{{request.question_id}}
hell-{{outerIndex}}


#include <tty.h>
Public Types | |
| using | value_type = T |
Types & Constants | |
| enum class | type : type_t { unknown = 0 , not_set = 1 << 0 , char_device = 1 << 1 , block_device = 1 << 2 , tty = 1 << 3 , file = 1 << 4 , socket = 1 << 5 } |
| using | type_t = unsigned int |
Public Member Functions | |
Constructors & Destructor | |
| template<typename ... Args> | |
| tty_implementable (const char *name, Args &&... args) | |
| virtual | ~tty_implementable () |
Public Member Functions | |
| value_type & | impl (void) const |
Public Member Functions | |
| virtual int | tcgetattr (termios *ptio) |
| virtual int | tcsetattr (int options, const termios *ptio) |
| virtual int | tcflush (int queue_selector) |
| virtual int | tcsendbreak (int duration) |
| virtual int | tcdrain (void) |
Public Member Functions | |
| virtual ssize_t | read (void *buf, std::size_t nbyte) |
| virtual ssize_t | write (const void *buf, std::size_t nbyte) |
| virtual ssize_t | writev (const iovec *iov, int iovcnt) |
| int | fcntl (int cmd,...) |
| virtual int | vfcntl (int cmd, std::va_list args) |
| int | isatty (void) |
| virtual int | fstat (struct stat *buf) |
| virtual off_t | lseek (off_t offset, int whence) |
| type_t | get_type (void) const |
| file_descriptor_t | file_descriptor (void) const |
| bool | is_opened (void) |
Protected Member Functions | |
Private Member Functions | |
| void | file_descriptor (file_descriptor_t fildes) |
| void | clear_file_descriptor (void) |
| io * | alloc_file_descriptor (void) |
Public Member Functions | |
| int | open (const char *path=nullptr, int oflag=0,...) |
| int | vopen (const char *path, int oflag, std::va_list args) |
| virtual int | close (void) override |
| int | ioctl (int request,...) |
| virtual int | vioctl (int request, std::va_list args) |
| virtual void | sync (void) |
| virtual bool | match_name (const char *name) const |
| const char * | name (void) const |
| static const char * | device_prefix (void) |
|
inherited |
| using os::posix::tty_implementable< T >::value_type = T |
|
stronginherited |
| os::posix::tty_implementable< T >::tty_implementable | ( | const char * | name, |
| Args &&... | args | ||
| ) |
|
virtual |
|
protectedinherited |
|
inlineprotectedinherited |
|
overridevirtualinherited |
Reimplemented from os::posix::io.
Reimplemented in os::posix::block_device_lockable< T, L >.
Definition at line 114 of file device.cpp.
|
inlinestaticinherited |
|
inlineprotectedinherited |
|
inlineinherited |
|
virtualinherited |
Reimplemented in os::posix::file_lockable< T, L >.
|
inlineinherited |
| tty_implementable< T >::value_type & os::posix::tty_implementable< T >::impl | ( | void | ) | const |
|
inherited |
Definition at line 138 of file device.cpp.
|
virtualinherited |
Reimplemented in os::posix::block_device_lockable< T, L >, and os::posix::file_lockable< T, L >.
|
virtualinherited |
Definition at line 192 of file device.cpp.
|
inlineinherited |
|
inherited |
| path | May be nullptr. |
| oflag | Output flags |
Definition at line 64 of file device.cpp.
|
virtualinherited |
Reimplemented in os::posix::block_device_lockable< T, L >, and os::posix::file_lockable< T, L >.
|
virtualinherited |
Reimplemented in os::posix::block_device_lockable< T, L >.
Definition at line 174 of file device.cpp.
|
inlinevirtualinherited |
|
inlinevirtualinherited |
|
inlinevirtualinherited |
|
inlinevirtualinherited |
|
virtualinherited |
Reimplemented in os::posix::block_device_lockable< T, L >, and os::posix::file_lockable< T, L >.
|
virtualinherited |
Reimplemented in os::posix::block_device_partition_lockable< T, L >, os::posix::block_device, and os::posix::block_device_lockable< T, L >.
Definition at line 155 of file device.cpp.
|
inherited |
| path | May be nullptr. |
| oflag | Output flags |
| args | Arguments |
Definition at line 76 of file device.cpp.
|
virtualinherited |
Reimplemented in os::posix::block_device_lockable< T, L >, and os::posix::file_lockable< T, L >.
|
virtualinherited |
Reimplemented in os::posix::block_device_lockable< T, L >, and os::posix::file_lockable< T, L >.


My All Projects and Commits/Collaborations/Changes i have Done is given below in Organised manner.
This is All in one userbot for telegram users it is Simple,Smart and Safe.
This bot can play high quality sound in your telegram group's voice chat.
This is High tech GroupManager Bot You can add this to make your groups safe from spammers/scammers and flooders.
This is not launched publically yet But you can have some patience.
I have Many Friends But Special of them are listed here .
Pro Python Coder
Best Offline Friend
S class Linux Hacker boi
Fire Cracker
Piro Hexa Player and Coder
Gajab Porya
Error 404, Could not define
Endless
Shhhhh...
<


Welcome to CodeClan
Nigeria
Login to access your account
Email address
password
Remember me
forgot password ?
Don't have an account?
Sign Up


This block symbolises the distinct clause. Sometimes a column can contain many duplicate values. If you want to list only the different values, you use distinct. It is used as a value in the "SELECT"-section and in some of the groupfunctions. The block changes also the colour to represent types.
As you see in the picture on the right, this block is used with one table and column block. Notice that there can be only one table and column block for each distinct clause.
This colour ,apple green, symbolises list, like all selected columns.
This colour,violet, symbolises the numeric values of the database
This colour, brown, symbolises the textual values of the database
This colour,tapestry, symbolises the date values of the database
This colour ,cyan, symbolises the boolean values of the database


Arsenal fans react as Emery hints at Granit Xhaka return
by Jordan HarrisArsenal fans have taken to Twitter to react after Unai Emery suggested, in comments reported by the club’s official website, that Granit Xhaka could make his return this weekend.
It has almost been a month since the Swiss last played for the Gunners. His angry reaction as he left the field during the 2-2 draw with Crystal Palace prompted many to suggest that he should not play for the club again.
Xhaka has since lost the captaincy and not been involved in any of Arsenal’s last four games in all competitions. However, it appears that that run may soon come to an end.
Emery suggested ahead of this weekend’s clash with Southampton that the 27-year-old is in contention to feature, and a decision about whether he will play will be made in the coming days.
“He is feeling better and also feeling that his team is Arsenal now. He wants to come back with confidence with the supporters, and we are going to decide. But I think little by little we can help him come back and connect with us and our supporters,” he told the club’s official website.
“We are going to decide tomorrow [whether he will be in the squad for Saturday] but I want to do that comeback, give him confidence and make him comfortable. And when we can connect with our supporters with a good moment and a good performance and being strong with them.”
Fan anger remains
Emery’s comments have left some of the Arsenal fans on social media divided. The minority appear to be extremely pleased about the prospect of Xhaka returning. They may well be hoping that the club can move past the recent events, and that Xhaka can silence his critics upon his return to the pitch.
However, most Gunners supporters appear to have little interest in seeing Xhaka come back. They believe that the damage has been done and his focus should be on finding a new club for January.
It must also be noted that Xhaka is not only the figure at the club that the fans want gone in the near future.
Here is what some of the supporters were saying on social media after Emery’s comments…
Have something to tell us about this article?
Let us know


Just click in the query field, type your query text then hit 'ENTER' or click 'Submit'.
The lines and changing lines will then be randomised using the "3 coin method" (with the 'seed' set using the current time).
All generated consultations are recorded in the archive and can be referred back to later, however there is no identifying information stored along with them.
Alternatively, to look up a reading without generating it randomly, e.g. 12 → 1 just append "12/1/" to the main URL. Or if there are no changing lines in the reading enter the initial hexagram twice, e.g. "12/12/"
Note: do not think of this like querying a search engine, think of it as like asking a wise person or even an omniscient universal consciousness.
If you sincerely seek to live life in accord with the Way and align with the universal flow, then the I Ching will speak clearly to give you guidance and insight.
{% block content %} {% endblock %}


Good Day, With warm heart I offer my friendship, and send my best wishes in this special season. However strange or surprising this contact might seem to you, as we have not met personally or had any dealings in the past, I humbly ask that you take due consideration of its importance and immense benefit. I also sincerely seek your confidence, as I make this proposal to you as a person of integrity. First and foremost I wish to introduce myself properly to you. My name is Oliveira Chuli Savimbi, I am a nephew and Personal Assistant to Late Jonas Malheiro Savimbi, leader of UNITA (National Union for the Total Independence of Angola). As led by my instinct, I selected your email address from an internet directory, in my search for a partner, hence this email. My Uncle(Mentor) was killed in a battle with government forces of Angola, led by President Dos Santos, on Friday 22nd February 2002. After his death, Mr. Antonio Dembo who was his second in command, assumed office as leader of UNITA, due to lack of the Charisma my Uncle had carried the party with in Dembo, there was chaos and struggle for leadership. Prominent members like Carlos Morgado lobbied to depose him and assume office as leader to enrich themselves and some of them who saw me as a threat to their ambitions, including Mr.Dembo, planned to kill me. The tension and confusion in UNITA become uncontrollable when Mr. Dembo died 10days after my Uncle's death. As I lost my mentor in this struggle which has been on for three decades now, not so much of this struggle interests me anymore, as there is now no sense of direction. I now desire a peaceful life, as I am no more interested in conflicts and wars. For this reason, I secretly left Angola and came here (Holland) to seek! political asylum. I am sincerely proposing to you to render me your highly needed assistance in respect to safekeeping of some of my Uncle's money that arose from Diamonds sales. This money (US$18.5million), which was already on its way to my Uncle's Swiss Bank account, through the Diplomatic means we use to move money abroad, and was on transit with a private safe deposit security company here in Amsterdam, Holland in February when the tragic incident of my Uncle's death occurred. I then instructed the company to secure the consignment containing the money pending on further instructions from me. I have waited for sometime now for security reasons, and have now deicded to act with your reliable assistance. As a matter of fact, the reason I came to Holland and sought for political asylum here is the safe deposit. President Dos Santos has lobbied the International Community to freeze my Uncle's assets and accounts abroad, to ground UNITA, and has already done this in Angola. Hence I cannot lodge the funds in my name. Also I did not declare the funds to the here. I plan to use this money to safeguard my future. It is very essential that you understand that the kind of trust and confidence I want to put in you is extraordinary, and an act of desperation on my part, in order not to lose this money. Also, ensure that this contact with you should be treated with utmost secrecy. Your role in this project, is clearing the safety deposit containing the money which is deposited in my name, from the Security company, after which, the money will lodged into an account preferably a new account you should open for this transaction. My share of the money will be returned to me when my asylum application in this country is granted, and I have permission to do business and open an account here. For your reliable assistance, I will reward you with 15%($2,775,000) of the money. I have with me, the Certificate of Deposit for the consignment containing the funds, which will be used for claim from the security company, and the release codes of the vaults. Also, everything will be legally processed for transfer of ownership to you, and this transaction should be completed immediately depending on your prompt response. I thank you in advance as I anticipate your assistance in enabling me achieve this goal. Please contact me whether or not you are interested in assisting me. This will enable me scout for another partner in the event of non-interest on your part. To know more about the struggle by UNITA to liberate Angola, click on the link below and read. http://www.the-idler.com/IDLER-02/3-16.html Sincerely, O.C.Savimbi.


Coronation Street star Jane Hazlegrove reveals heartbreaking battle with Imposter Syndrome
Jane, , who plays Bernie Winter on the ITV soap, spoke on Lorraine today (Friday, November 15)
by James Rodger, https://www.facebook.com/jamesrodgerjournalistCoronation Street's Jane Hazlegrove has revealed her heartbreaking battle with 'Imposter Syndrome'.
The Corrie actress appeared on Lorraine today where she discussed her gruelling battle with her self-esteem and sense of self-worth.
Jane, , who plays Bernie Winter on the ITV soap, spoke on Lorraine today (Friday, November 15).
 I tend to throw things at the television. I am quite hard on myself. I think that’s important though don’t you?
“Imposter syndrome - that at any moment I could say, are you Jane Hazelgrove? Yea, get out.”
Lorraine replied: “I hear you. Someone will tap you on the shoulder and say, actually we’ve found you out and you have to go away now.”
Jane said: “The arrogance of youth - I wasn’t nervous at all then.
"Now I’m a woman in my 50s, it was really frightening, because it’s Coronation Street, it’s a big gig and I don’t want to let the show down and I don’t want to let myself down or the family or anything.”
Speaking of her return to the long-running ITV1 soap: “I was petrified, but Dolly [Rose Campbell] and Sam [Aston] who play Gemma and Chesney, they pushed me around, guided me to the green room and worked out when I needed a cup of tea.”
Praising actor Peter Ash for his portrayal of Paul, Jane said: “I hope it gives lots of people a vocabulary and the courage to go, hang on, this is what I have been carrying around with me for a long time and it’s not right.”


| Class | Description |
|---|---|
| ST25TA02KDTag | |
| ST25TA02KGDTag | |
| ST25TA02KGPTag | |
| ST25TA02KGTag |
ST25TA02K cut 2.2 from July 2017
This tag handles signature differently than previous versions
|
| ST25TA02KPTag | |
| ST25TA02KTag | |
| ST25TA512GTag | |
| ST25TA512Tag | |
| ST25TAGpoTag | |
| ST25TATag | |
| SysFileST25TA | |
| SysFileST25TAGpo |
COPYRIGHT 2017 STMicroelectronics. All rights reserved.