• Skip to main content
  • Skip to header right navigation
  • Skip to site footer
CDP Studio logo

CDP Studio

The no-code and full-code software development tool for distributed control systems and HMI

  • Why CDP
    • Software developers
    • Automation engineers
    • Managers
  • Product
    • Design UI
    • Develop
    • Analyze and test
    • Deploy
    • Framework and toolbox
    • Compatibility
  • Services
  • Use cases
  • Pricing
  • Try CDP

CDP Studio Documentation

  • Framework - CDP Core
  • ChannelManager
  • 4.11.14

ChannelManager Class

(ServerIO::ChannelManager)

The ChannelManager class can be used to synchronize ICDPChannel classes between User/Worker thread and CDPProcess where the CDP class (like CDPSignal, CDPProperty) for channel implementation is created. More...

Header: #include <IO/ServerIO/ChannelManager.h>
  • List of all members, including inherited members

Public Functions

ChannelManager(CDPComponent *server)
virtual ~ChannelManager()
ICDPChannel *AllocateNewCDPChannel(XMLElementEx *pXML, double &dSize, int moduleNo, int groupNo, bool bInputChannel)
void DeregisterCDPChannel(ICDPChannel *channel)
virtual void Destroy()
std::list<ICDPChannel *> GetChannelList()
int GetInputSyncGroupId() const
int GetOutputSyncGroupId() const
ICDPChannel *HandleCDPChannelElement(XMLElementEx *pEx)
ICDPChannel *HasChannel(const std::string &shortName)
void RegisterCDPChannel(ICDPChannel *channel)
void SetSyncGroupId(bool bInputChannel, ICDPChannel *pChannel)
void SynchronizeValuesIn()
void SynchronizeValuesOut()

Static Public Members

ICDPChannel *NewICDPChannel(XMLElementEx *pXML, double &dSize, int moduleNo, int groupNo, bool bInputChannel)

Detailed Description

The ChannelManager class can be used to synchronize ICDPChannel classes between User/Worker thread and CDPProcess where the CDP class (like CDPSignal, CDPProperty) for channel implementation is created.

The ChannelManager is typically added to an IOServer like this: Include header:

#include <IO/ServerIO/ChannelManager.h>

Add ChannelManager:

ServerIO::ChannelManager* m_pChannelManager;

In the IOServer constructor, initialize the ChannelManager:

CustomIO::CustomIO()
: m_pChannelManager(new ServerIO::ChannelManager(this))
{
}

Make sure to delete it in the destructor...

CustomIO::~CustomIO()
{
  delete m_pChannelManager;
}

..and override Destroy to free its resources:

CustomIO::Destroy()
{
  IOServer::Destroy();
  m_pChannelManager->Destroy();
}

In your library, add a CDPChannel Table like this:

  • Add a CDPModel -> AggregateBaseModel
  • In the Elements table, rename AggregateBaseModel to CDPChannel
  • Set the {CDPChannel} AcceptsBase column value to CDPSignalChannel<> to accept CDPSignalChannel models.
  • Build the library to apply the changes; a table named CDPChannel should now appear in your model.

Extend HandleXMLElement() to auto-generate and register the channels in the ChannelManager when they are read from the configuration CDPChannel table:

bool CustomIO::HandleXMLElement(XMLElementEx *pEx)
{
  // Handle creation of objects that have an XML configuration in the component configuration file
  if (pEx->GetName()=="CDPChannel")
  {
    double dataSize;
    ServerIO::ICDPChannel* pChannel = ServerIO::ChannelManager::NewICDPChannel(pEx,dataSize,0,0,0);
    if (pChannel==nullptr)
    {
      CDPMessage("Suspending %s: Failed creating CDPChannel for Name=%s.\n",ShortName(), pEx->GetAttributeValue("Name").c_str());
      this->Suspend();
      return false;
    }
    pChannel->SetNodeOwner(this);
    std::string channelName = pEx->GetAttributeValue("Name").c_str();
    pChannel->Create(channelName.c_str(),this);
    pChannel->SetChannelParameters(pEx->GetAttributeValue("Input"),0,0,pEx->GetAttributeValue("Nr"));
    pChannel->Configure(pEx);
    m_pChannelManager->RegisterCDPChannel(pChannel);
    return true; // don't call HandleXMLElement() for children of CDPChannel-element
  }
  ...

To expose the channels in Online mode, override FillNodeChildren():

void CustomIO::FillNodeChildren(CDP::StudioAPI::NodeStream &serializer) const
{
  ...

  for (auto channel: m_pChannelManager->GetChannelList())
    serializer << AdoptedChild(channel);
}

Update the IOServer::ProtocolImplementation() to update the channels before sending them and after receiving them:

void CustomIO::ProtocolImplementation()
{
  m_pChannelManager->SynchronizeValuesIn();
  // Send the updated signals...
  ...
  // Receive the signals from the device, then do:
  m_pChannelManager->SynchronizeValuesOut();
}

See also IOServer and ServerIO::IChannel.

Member Function Documentation

ChannelManager::ChannelManager(CDPComponent *server)

ChannelManager constructor that takes in the IOServer pointer the channel manager is used in.

server should contain IOServer pointer that is used as parent of CDPSignalChannels when locking MemberAccess mutex.

[virtual] ChannelManager::~ChannelManager()

Destructor that deletes all Channels that are left in ChannelManager at the point of it's destruction.

ICDPChannel *ChannelManager::AllocateNewCDPChannel(XMLElementEx *pXML, double &dSize, int moduleNo, int groupNo, bool bInputChannel)

Allocates a new CDPSignal channel or other ICDPChannel implementing channel. Models supported are "CDPSignal", "CDPSignalChannel", "CDPProperty", "CDPPropertyChannel", "ComponentState" or "ComponentStateChannel". Create and Configure are called on the created channel instance.

pXML pointer to XMLElement which must contain one of the supported Models and other configuration.

dSize will return the created channel's datasize (1/8 for bool, channel's GetDataSize() for other types).

moduleNo is set as parameter of the Channel instance if applicable.

groupNo is set as parameter of the Channel instance if applicable.

bInputChannel holds the direction of CDP primiteve in the channel. Input expects valus from CDP, output provides them.

Returns a pointer to ICDPChannel if successful, otherwise nullptr is returned.

void ChannelManager::DeregisterCDPChannel(ICDPChannel *channel)

Removes a channel from manager. Removed channels need to be deleted manually.

channel holds the channel-pointer to be removed.

[virtual] void ChannelManager::Destroy()

Destroys all channels in m_channels.

std::list<ICDPChannel *> ChannelManager::GetChannelList()

Returns the list of all channel pointers in ChannelManager, updated by RegisterCDPChannel/DeregisterCDPChannel. This method should not be used for frequent iteration needs in IOServers.

int ChannelManager::GetInputSyncGroupId() const

Returns sync Id for the channels to be synchronised in by CDP.

int ChannelManager::GetOutputSyncGroupId() const

Returns sync Id for the channels to be synchronised out by CDP.

ICDPChannel *ChannelManager::HandleCDPChannelElement(XMLElementEx *pEx)

Will call AllocateNewCDPChannel() and RegisterCDPChannel() based on contents of pEx. pEx is a pointer to XMLElement containing configuration, must at least contain "CDPChannel" and "Model".

Returns a pointer to ICDPChannel if successful, otherwise nullptr is returned.

ICDPChannel *ChannelManager::HasChannel(const std::string &shortName)

Returns a pointer to ICDPChannel if a channel is found with the same Name() as shortName, otherwise nullptr is returned.

[static] ICDPChannel *ChannelManager::NewICDPChannel(XMLElementEx *pXML, double &dSize, int moduleNo, int groupNo, bool bInputChannel)

Allocation of ICDPChannel based on XMLElement without Create or Configure calls. Models supported are "CDPSignal", "CDPSignalChannel", "CDPProperty", "CDPPropertyChannel", "ComponentState" or "ComponentStateChannel".

pXML pointer to XMLElement which must contain one of the supported Models and other configuration.

dSize will return the created channel's datasize (1/8 for bool, channel's GetDataSize() for other types)

moduleNo not used

groupNo not used

bInputChannel not used

Returns a pointer to ICDPChannel if successful, otherwise nullptr is returned.

void ChannelManager::RegisterCDPChannel(ICDPChannel *channel)

Registers the Channel in channel manager. In destructor the manager class destroys all channels still in management list.

channel holds the channel-pointer to add. Channel manager takes over the ownership of the channel and will call destructer when manager itself is deleted.

void ChannelManager::SetSyncGroupId(bool bInputChannel, ICDPChannel *pChannel)

Sets the "SyncGroupId" property value. If bInputChannel is true, value from GetInputSyncGroupId() is used, otherwise value from GetOutputSyncGroupId() is used. SetProperty() is called on pChannel .

void ChannelManager::SynchronizeValuesIn()

SynchronizeValuesIn should be called before using values in a user thread loop or process to get the current IChannel values safely to thread context.

void ChannelManager::SynchronizeValuesOut()

SynchronizeValuesOut should be called after writing values from a user thread loop or process to update the current IChannel values to correct CDPProcess context.

The content of this document is confidential information not to be published without the consent of CDP Technologies AS.

CDP Technologies AS, www.cdpstudio.com

Get started with CDP Studio today

Let us help you take your great ideas and turn them into the products your customer will love.

Try CDP Studio for free
Why CDP Studio?

CDP Technologies AS
Hundsværgata 8,
P.O. Box 144
6001 Ålesund, Norway

Tel: +47 990 80 900
E-mail: info@cdptech.com

Company

About CDP

Contact us

Services

Partners

Blog

Developers

Get started

User manuals

Support

Document download

Release notes

Follow CDP

  • LinkedIn
  • YouTube
  • GitHub

    © Copyright 2022 CDP Technologies. Privacy and cookie policy.

    Return to top