SilecsBlock.cpp 5.60 KiB
/*
Copyright (c) 2017 European Organization for Nuclear Research (CERN).
All rights reserved. This program and the accompanying materials
are made available under the terms of the GNU Public License v3.0
which accompanies this distribution, and is available at
http://www.gnu.org/licenses/gpl.html
Contributors:
.European Organization for Nuclear Research (CERN) - initial API and implementation
.GSI Helmholtzzentrum für Schwerionenforschung (GSI) - features and bugfixes
*/
#include <silecs-communication/interface/core/SilecsService.h>
#include <silecs-communication/interface/utility/XMLParser.h>
#include <silecs-communication/interface/equipment/SilecsPLC.h>
#include <silecs-communication/interface/equipment/SilecsBlock.h>
#include <silecs-communication/interface/equipment/SilecsRegister.h>
#include <silecs-communication/interface/core/SilecsAction.h>
#include <silecs-communication/interface/utility/SilecsException.h>
#include <silecs-communication/interface/utility/SilecsLog.h>
#include <silecs-communication/interface/utility/StringUtilities.h>
namespace Silecs
{
Block::Block(const ElementXML& blockNode, Connection& plcConnection) :
plcConnection_(plcConnection),
configuration_(false)
{
name_ = blockNode.getAttribute("name");;
if(blockNode.getName() == "Configuration-Block")
configuration_ = true;
StringUtilities::fromString(size_, blockNode.getAttribute("size"));
StringUtilities::fromString(memSize_, blockNode.getAttribute("mem-size"));
StringUtilities::fromString(address_, blockNode.getAttribute("address"));
if (blockNode.hasAttribute("ioType")) // only IO-Blocks have this attribute
accessArea_ = Block::whichAccessArea(blockNode.getAttribute("ioType"));
else
accessArea_ = AccessArea::Memory;
resetCustomAttributes(); //by default custom-size of the block is the maximum size
accessType_ = whichAccessType(blockNode.getName());
}
Block::~Block()
{
if (DEBUG & Log::topics_)
LOG(ALLOC) << "Block (delete): " << name_;
}
AccessType Block::whichAccessType(const std::string& type)
{
if (type == "Acquisition-Block")
return AccessType::Acquisition;
else if (type == "Command-Block")
return AccessType::Command;
else if (type == "Configuration-Block")
return AccessType::Setting;
else if (type == "Setting-Block")
return AccessType::Setting;
else if (type == "Setting-IO-Block")
return AccessType::Setting;
else if (type == "Acquisition-IO-Block")
return AccessType::Acquisition;
else if (type == "Command-IO-Block")
return AccessType::Command;
else
throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_ACCESS_TYPE, type);
}
std::string Block::whichAccessType(AccessType type)
{
switch (type)
{
case AccessType::Command:
return "WRITE-ONLY";
case AccessType::Acquisition:
return "READ-ONLY";
case AccessType::Setting:
return "READ-WRITE";
default:
throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_ACCESS_TYPE, StringUtilities::toString(static_cast<int>(type)));
}
}
AccessArea Block::whichAccessArea(std::string area)
{
StringUtilities::toLower(area);
if (area == "memory")
return AccessArea::Memory;
else if (area == "digital-io")
return AccessArea::Digital;
else if (area == "analog-io")
return AccessArea::Analog;
else
throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_ACCESS_AREA, area);
}
std::string Block::whichAccessArea(AccessArea area)
{
switch (area)
{
case AccessArea::Memory:
return "MEMORY";
case AccessArea::Digital:
return "DIGITAL-IO";
case AccessArea::Analog:
return "ANALOG-IO";
default:
throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_ACCESS_AREA, StringUtilities::toString(static_cast<int>(area)));
}
}
void Block::setCustomAttributes(const unsigned long customAddress, const unsigned long customOffset, const unsigned long customSize)
{
//user wants to limit the size of data to be sent/receive - check that it is lower than design allocation size
if (customSize > memSize_)
throw SilecsException(__FILE__, __LINE__, PARAM_EXCEEDED_BLOCK_SIZE, StringUtilities::toString(memSize_));
customAddress_ = customAddress;
customOffset_ = customOffset;
customSize_ = customSize;
customAttributes_ = true;
LOG(DEBUG) << "Set custom attributes of block: " << name_ << ", memSize: " << memSize_ << ", customSize: " << customSize << ", customAddress: " << customAddress << ", customOffset: " << customOffset;
}
void Block::resetCustomAttributes()
{
customAttributes_ = false;
LOG(DEBUG) << "Reset custom attributes of block: " << name_;
}
void Block::importRegisters(void* pBuffer, timeval ts)
{
for (auto& reg : registers_)
{
if (reg->getFormat() == String)
{
reg->importString(pBuffer, ts);
}
else
{
reg->importValue(pBuffer, ts);
}
}
}
void Block::exportRegisters(void* pBuffer)
{
for (auto& reg : registers_)
{
if (reg->getFormat() == String)
{
reg->exportString(pBuffer);
}
else
{
reg->exportValue(pBuffer);
}
}
}
void Block::copyInToOut()
{
for (auto& reg : registers_)
{
if (reg->isReadable() && reg->isWritable())
{
reg->copyValue();
}
}
}
const std::vector<std::unique_ptr<Register>>& Block::getRegisters() const
{
return registers_;
}
} // namespace