ChimeraTK-DeviceAccess 03.20.00
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Using push-type inputs with AccessMode::wait_for_new_data

Usually the content of device registers are read out synchronously: Whe read() is called in an accessor the hardware is accessed.

We call this "poll type" mode. The data transfer is initiated by the application code. The read() operation return immediately after the data transfer, which was initiated by the read operation itself, has finished (non-blocking).

Some accessors provide the possibity to have "push type" operation. In this case the data transfer is initialised by the device. Typical scenarios are interrupts or publish-subcribe patterns where new data is send to the subscriber as soon as it is available. In this case the code does not know when the read() operation will return. It is waiting for new data to arrive (blocking).

To activate the push-type behaviour, the flag AccessMode::wait_for_new_data is used when requesting the accessor. You can check in the catalogue whether the particular accors supports AccessMode::wait_for_new_data. If you reqest this mode but the accessor does not support it, a ChimeraTK::logic_error is thrown.

// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
// SPDX-License-Identifier: LGPL-3.0-or-later
/* Unfortunately the DeviceAccess base package does not have a demo push type accessor we can use.
* That's why this code uses the Doocs backend. Use it together with example2 from ApplicationCore.
* You have to activate the zmq sending in the ApplicationCore example2 by using the configuration files
* demoApp2-DoocsVariableConfig.xml and demo_example2.conf, which are provided with this example.
*
* Compile this file by linking directly with the Doocs backend (for instance directly on the command line):
* g++ read_temperature_doocs_zmq.cpp -o read_temperature_doocs_zmq `ChimeraTK-DeviceAccess-config --cppflags
* --ldflags` -lpthread -Wl,--no-as-needed -lChimeraTK-DeviceAccess-DoocsBackend
*/
#include <ChimeraTK/Device.h>
#include <iostream>
int main() {
d.open("(doocs:TEST.DOOCS/LOCALHOST_610498009/Bakery)");
// You have to activate the receiving of asynchronousy send data before an accessor with AccessMode::wait_for_new_data
// will receive anything. You can first create all accessors and then activate all of them at the same point in time
// with this.
// The third argument is a list of ChimeraTK::AccessMode. We only have one argument in it:
// AccessMode::wait_for_new_data.
auto temperature =
d.getScalarRegisterAccessor<float>("Oven.temperatureReadback", 0, {ChimeraTK::AccessMode::wait_for_new_data});
// The read now blocks until data is received. You can use it to syncrchonise your code to incoming data. No need for
// additional sleeps etc.
while(true) {
temperature.read();
std ::cout << "The temperature is " << temperature << " degC. " << std ::endl;
}
}
int main()
Class allows to read/write registers from device.
Definition Device.h:39
ScalarRegisterAccessor< UserType > getScalarRegisterAccessor(const RegisterPath &registerPathName, size_t wordOffsetInRegister=0, const AccessModeFlags &flags=AccessModeFlags({})) const
Get a ScalarRegisterObject object for the given register.
Definition Device.h:266
void activateAsyncRead() noexcept
Activate asyncronous read for all transfer elements where AccessMode::wait_for_new_data is set.
Definition Device.cc:91
void open(std::string const &aliasName)
Open a device by the given alias name from the DMAP file.
Definition Device.cc:58
@ wait_for_new_data
Make any read blocking until new data has arrived since the last read.