Skip to content

Commit

Permalink
Add support for building on Windows
Browse files Browse the repository at this point in the history
Building is possible with submoduled ADS lib,
or with library included with a TwinCAT install.
To use the latter, `TCDIR` must be defined.
  • Loading branch information
FreddieAkeroyd authored and jevarlec committed Feb 27, 2023
1 parent 2944b29 commit 7e8a826
Show file tree
Hide file tree
Showing 18 changed files with 221 additions and 66 deletions.
84 changes: 49 additions & 35 deletions adsApp/src/ADSPortDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
#include <Variable.h>
#include <autoparamHandler.h>
#include <err.h>
#ifndef USE_TC_ADS
#include <standalone/AdsDef.h>
#endif /* USE_TC_ADS */
#include <Connection.h>
#include <chrono>
#include <cstddef>
Expand All @@ -20,6 +22,7 @@
#include <stdexcept>
#include <thread>
#include <vector>
#include <boost/algorithm/string.hpp>

bool ADSDeviceAddress::operator==(DeviceAddress const &other) const {
ADSDeviceAddress const &b = static_cast<ADSDeviceAddress const &>(other);
Expand Down Expand Up @@ -94,12 +97,23 @@ ADSPortDriver::ADSPortDriver(
.setAutoConnect(true)
.setAutoDestruct()
.setInitHook(initHook)),
portName(portName), ipAddr(ipAddr), amsNetId(amsNetId),
portName(portName), ipAddr(ipAddr), amsNetId{0, 0, 0 ,0 ,0 ,0},
sumBufferSize(sumBufferSize), adsFunctionTimeout(adsFunctionTimeout),
adsConnection(new Connection()), SumRead(sumBufferSize, adsConnection),
exitCalled(false), initialized(false),
currentDeviceState(ADSSTATE_INVALID) {

#ifdef USE_TC_ADS
std::vector<std::string> split_ams;
boost::split(split_ams, amsNetId, boost::is_any_of("."));
for(int i=0; i < split_ams.size() && i < 6; ++i)
{
this->amsNetId.b[i] = atoi(split_ams[i].c_str());
}
#else
this->amsNetId = std::string(amsNetId);
#endif

// scalars
registerHandlers<epicsInt32>(ads_datatypes_str.at(ADSDataType::BOOL),
integerRead<epicsInt8, epicsInt32>,
Expand Down Expand Up @@ -520,55 +534,55 @@ void ADSPortDriver::performIOIntr() {
auto const &nelem = adsVar.adsPV->addr->get_nelem();

switch (dataType) {
case BOOL:
case BYTE:
case SINT: {
case ADSDataType::BOOL:
case ADSDataType::BYTE:
case ADSDataType::SINT: {
performArrayCallbacks<epicsInt8, epicsInt8>(adsVar, nelem);
break;
}

case INT: {
case ADSDataType::INT: {
performArrayCallbacks<epicsInt16, epicsInt16>(adsVar, nelem);
break;
}

case DINT: {
case ADSDataType::DINT: {
performArrayCallbacks<epicsInt32, epicsInt32>(adsVar, nelem);
break;
}
case LINT: {
case ADSDataType::LINT: {
performArrayCallbacks<epicsInt64, epicsInt64>(adsVar, nelem);
break;
}

case REAL: {
case ADSDataType::REAL: {
performArrayCallbacks<epicsFloat32, epicsFloat32>(adsVar,
nelem);
break;
}

case LREAL: {
case ADSDataType::LREAL: {
performArrayCallbacks<epicsFloat64, epicsFloat64>(adsVar,
nelem);
break;
}

case USINT: {
case ADSDataType::USINT: {
performArrayCallbacks<epicsUInt8, epicsInt8>(adsVar, nelem);
break;
}
case WORD:
case UINT: {
case ADSDataType::WORD:
case ADSDataType::UINT: {
performArrayCallbacks<epicsUInt16, epicsInt16>(adsVar, nelem);
break;
}
case DWORD:
case UDINT: {
case ADSDataType::DWORD:
case ADSDataType::UDINT: {
performArrayCallbacks<epicsUInt32, epicsInt32>(adsVar, nelem);
break;
}

case STRING: {
case ADSDataType::STRING: {
std::vector<char> buffer(nelem);
Autoparam::Octet readArray(buffer.data(), buffer.size());

Expand All @@ -585,27 +599,27 @@ void ADSPortDriver::performIOIntr() {

} else if (func.find("_digi") != std::string::npos) {
switch (dataType) {
case BOOL:
case BYTE:
case USINT: {
case ADSDataType::BOOL:
case ADSDataType::BYTE:
case ADSDataType::USINT: {
UInt32ReadResult result =
digitalRead<epicsUInt8>(adsVar, 0xFFFF);

setParam(adsVar, result.value, result.status,
result.alarmStatus, result.alarmSeverity);
break;
}
case WORD:
case UINT: {
case ADSDataType::WORD:
case ADSDataType::UINT: {
UInt32ReadResult result =
digitalRead<epicsUInt16>(adsVar, 0xFFFF);

setParam(adsVar, result.value, result.status,
result.alarmStatus, result.alarmSeverity);
break;
}
case DWORD:
case UDINT: {
case ADSDataType::DWORD:
case ADSDataType::UDINT: {
UInt32ReadResult result =
digitalRead<epicsUInt32>(adsVar, 0xFFFF);

Expand All @@ -619,9 +633,9 @@ void ADSPortDriver::performIOIntr() {

} else {
switch (dataType) {
case BOOL:
case BYTE:
case SINT: {
case ADSDataType::BOOL:
case ADSDataType::BYTE:
case ADSDataType::SINT: {
Int32ReadResult result =
integerRead<epicsInt8, epicsInt32>(adsVar);

Expand All @@ -630,7 +644,7 @@ void ADSPortDriver::performIOIntr() {
break;
}

case INT: {
case ADSDataType::INT: {
Int32ReadResult result =
integerRead<epicsInt16, epicsInt32>(adsVar);

Expand All @@ -639,7 +653,7 @@ void ADSPortDriver::performIOIntr() {
break;
}

case DINT: {
case ADSDataType::DINT: {
Int32ReadResult result =
integerRead<epicsInt32, epicsInt32>(adsVar);

Expand All @@ -648,7 +662,7 @@ void ADSPortDriver::performIOIntr() {
break;
}

case LINT: {
case ADSDataType::LINT: {
Int64ReadResult result =
integerRead<epicsInt64, epicsInt64>(adsVar);

Expand All @@ -658,23 +672,23 @@ void ADSPortDriver::performIOIntr() {
break;
}

case REAL: {
case ADSDataType::REAL: {
Float64ReadResult result = floatRead<epicsFloat32>(adsVar);

setParam(adsVar, result.value, result.status,
result.alarmStatus, result.alarmSeverity);
break;
}

case LREAL: {
case ADSDataType::LREAL: {
Float64ReadResult result = floatRead<epicsFloat64>(adsVar);

setParam(adsVar, result.value, result.status,
result.alarmStatus, result.alarmSeverity);
break;
}

case USINT: {
case ADSDataType::USINT: {
Int32ReadResult result =
integerRead<epicsInt16, epicsInt32>(adsVar);

Expand All @@ -683,8 +697,8 @@ void ADSPortDriver::performIOIntr() {
break;
}

case WORD:
case UINT: {
case ADSDataType::WORD:
case ADSDataType::UINT: {
Int32ReadResult result =
integerRead<epicsInt32, epicsInt32>(adsVar);

Expand All @@ -693,8 +707,8 @@ void ADSPortDriver::performIOIntr() {
break;
}

case DWORD:
case UDINT: {
case ADSDataType::DWORD:
case ADSDataType::UDINT: {
Int64ReadResult result =
integerRead<epicsInt64, epicsInt64>(adsVar);

Expand Down
10 changes: 9 additions & 1 deletion adsApp/src/ADSPortDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

#include "ADSAddress.h"
#include "autoparamHandler.h"
#include "standalone/AdsDef.h"
#ifndef USE_TC_ADS
#include <standalone/AdsDef.h>
#endif /* ifndef USE_TC_ADS */
#include <atomic>
#include <chrono>
#include <cstdint>
Expand All @@ -17,7 +19,13 @@
#include <thread>
#include <vector>

#ifdef USE_TC_ADS
#include <windows.h>
#include <TcAdsDef.h>
#include <TcAdsApi.h>
#else
#include <AdsLib.h>
#endif /* ifdef USE_TC_ADS */
#include <autoparamDriver.h>
#include <SumReadRequest.h>
#include <Types.h>
Expand Down
19 changes: 16 additions & 3 deletions adsApp/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ DBD += ads.dbd

EPICS_ADS=$(TOP)/adsApp/src

USR_CXXFLAGS += -std=c++11
USR_CXXFLAGS_Linux += -std=c++11
USR_CXXFLAGS_WIN32 += -DNOMINMAX

# use ADS from twincat
ifdef TCDIR
USR_CXXFLAGS += -DUSE_TC_ADS
USR_CXXFLAGS += -I$(TCDIR)/3.1/sdk/Include
endif

# specify all source files to be compiled and added to the library
SRC_DIRS += $(EPICS_ADS)/epics-ads
Expand All @@ -33,6 +40,7 @@ ads_SRCS += RWLock.cpp
ads_SRCS += Types.cpp
ads_SRCS += err.cpp

ifndef TCDIR
# specify beckhoff ads lib source files to be compiled and added
SRC_DIRS += $(EPICS_ADS)/beckhoffAdsLib/AdsLib
ads_SRCS += AdsDef.cpp
Expand All @@ -54,16 +62,21 @@ ads_SRCS += standalone_NotificationDispatcher.cpp

# Because AdsLib.cpp exists both in AdsLib/ and AdsLib/standalone, those in standalone/ are copied and renamed to standalone_*.
$(filter standalone_%,$(ads_SRCS)): standalone_%: $(EPICS_ADS)/beckhoffAdsLib/AdsLib/standalone/%
cp $< $@
$(CP) $< $@

endif

# libpthread is needed for POSIX R/W locks used in RWLock.h
ads_SYS_LIBS += pthread
ads_SYS_LIBS_Linux += pthread

# ads_LIBS += DynamicAsynPort
ads_LIBS += autoparamDriver
ads_LIBS += asyn
ads_LIBS += $(EPICS_BASE_IOC_LIBS)
ifdef TCDIR
ads_SYS_LIBS_WIN32 += $(TCDIR)/AdsApi/TcAdsDll/x64/lib/TcAdsDll
endif
ads_SYS_LIBS_WIN32 += ws2_32

#===========================

Expand Down
12 changes: 11 additions & 1 deletion adsApp/src/epics-ads/Connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

#include "Connection.h"

#ifndef AMSPORT_R0_PLC_TC3
#define AMSPORT_R0_PLC_TC3 851
#endif

bool Connection::is_connected() { return (this->ads_port != 0 ? true : false); }

const AmsNetId Connection::get_remote_ams_netid() {
Expand All @@ -20,18 +24,22 @@ Connection::Connection() {}
Connection::~Connection() {}

void Connection::set_local_ams_id(const AmsNetId ams_id) {
#ifndef USE_TC_ADS
AdsSetLocalAddress(ams_id);
#endif
}

int Connection::connect(const AmsNetId ams_id, const std::string address) {
std::lock_guard<epicsMutex> lock(this->mtx);

/* Add AMS route */
#ifndef USE_TC_ADS
long rc = AdsAddRoute(ams_id, address.c_str());
if (rc != 0) {
LOG_ERR("could not add ADS rout (%li): %s", rc, errorMap[rc].c_str());
return EPICSADS_DISCONNECTED;
}
#endif

const long port = AdsPortOpenEx();
if (port == 0) {
Expand All @@ -55,8 +63,10 @@ int Connection::disconnect() {
AdsPortCloseEx(this->ads_port);
this->ads_port = 0;

#ifndef USE_TC_ADS
/* TODO: does this bork other ADS connections? */
AdsDelRoute(this->remote_ams_netid);
#endif
this->remote_ams_netid = {0, 0, 0, 0, 0, 0};

return 0;
Expand Down Expand Up @@ -106,7 +116,7 @@ int Connection::resolve_variables(
sizeof(handle), // read length
&handle, // read data
ads_var->addr->get_var_name().size(), // write length
ads_var->addr->get_var_name().c_str(), // write data
const_cast<char*>(ads_var->addr->get_var_name().c_str()), // write data
nullptr); // bytes read

if (rc != 0) {
Expand Down
8 changes: 7 additions & 1 deletion adsApp/src/epics-ads/Connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@
#include <vector>

#include <epicsMutex.h>
#include "AdsLib.h"
#ifdef USE_TC_ADS
#include <windows.h>
#include <TcAdsDef.h>
#include <TcAdsApi.h>
#else
#include <AdsLib.h>
#endif

#include "Variable.h"

Expand Down
Loading

0 comments on commit 7e8a826

Please sign in to comment.