• 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

  • Doc
  • Why CDP
    • Software developers
    • Automation engineers
    • Managers
  • Products
    • Automation Designer
    • HMI Designer
    • Maritime HMIs
  • Services
  • Use cases
  • Pricing
  • Try CDP

CDP Studio Documentation

  • Framework - CDP Core
  • Basics: Architecture
  • 5.0.0

Framework - CDP Core Advanced: CDP Model syntax

Basics: Architecture

Definitions

Definitions of commonly used terms are available in a separate Glossary.

Introduction

The CDP System is a distributed control system that runs on one or more controllers. The system consists of one or more applications, each containing components. The components are scheduled by the CDP runtime system and the components communicate with each other using real-time values and messages. The system is configured in CDP Studio, where the applications and components are defined. The system is then built and uploaded to the controller(s) for execution or run locally on the development computer for testing.

This document describes the basics of the architecture of a CDP System, including the structure of CDP Applications and Components. It also describes the CDP runtime components and the CDP Message log. The document ends with some best practices for system design.

CDP System and Applications

The example below shows a system consisting of one GUI application and 2 control applications, running on 3 CDP Controllers. The control applications contain different components like CDP runtime, I/O Servers (for example CANOpen and ModBus that are responsible for translating the I/O signals to CDPSignals and vice versa), and other user-made components.

CDP System

A CDP System is the top-level collection of one or more applications (processes) that work together for a common automation purpose. These applications can be distributed across different controllers (physical devices) yet operate in a coordinated way. For example, you might have one HMI (GUI) application and two control applications running on three separate controller devices, all part of one CDP System​. The CDP Framework enables these applications to discover each other and share data in real-time, forming a unified system.

CDP Application

A CDP Application is a program (typically an OS process) running on a single controller, containing a set of configured components. An application is defined entirely by configuration (there is usually no custom user code written in the main program itself – the logic lives in the components). Application can be native GUI applications and control (console) applications​. WebGUI support can be added to both types of applications.

The behavior of application is determined by the components and their relationships as specified in an configuration files of the application​. This configuration is structured as a hierarchical tree of components (and sub-components), each with defined properties and connections​. In essence, the application executable is a container that loads the configured components and orchestrates them, rather than hardcoding the control logic. This makes applications flexible – the same binary can run different configurations to perform different tasks, depending on which components are defined in the configuration files.

CDP Component

A CDPComponent is the fundamental building block of CDP applications. Each component encapsulates a specific functionality or part of the control logic (for example, a PID controller, a sensor interface, a communication module, etc.). Components interact with each other through well-defined interfaces such as real-time data signals, ports, and messages. Every component has specific execution settings. Notably, these settings include a cyclic frequency (fs, in Hz), which determines how frequently the component runs, and a scheduling priority (Low, Normal, or High), indicating its thread scheduling importance. For more details, see SchedulingGroup and Priority levels.

The CDP scheduler uses these settings to call the component’s processing code at regular intervals. Components can also be grouped by a SchedulingGroup property, which allows the system to run certain groups of components in separate threads for parallelism on multi-core systems​. Importantly, components can contain child components, forming a hierarchy: a component can own sub-components that operate under it. This nested structure reflects the logical design of the system​. For instance, a “RobotArm” component might have sub-components for each joint controller. Organizing components hierarchically provides a clear separation of concerns and makes the system easier to manage. All components, whether user-defined or built-in, share common base functionality, as they inherit from the base CDPComponent class provided by the framework. Components are defined by their definition files, called Models, which specify their properties, I/O signals, child components, and more. These Models are analogous to class definitions in an object-oriented programming (OOP) context.

CDP Components can also be used just as logic containers to create logical structures in applications. They can be used to group signals, alarms, other components and operators together to create larger reusable design units.

In summary, CDP Components are self-contained modules of logic that run at a set rate and communicate with other modules, and they are the main structural units from which CDP applications are built​.

When adding a new CDP Component Model to a library in CDP Studio, the default frequency (fs) for the CDPComponent is 10Hz, and Priority is set to normal. The lower limit is 0, but there is no upper limit in software. The physical hardware will limit what is achievable as a maximum value.

Fundamental Logic of CDP Operation

At runtime, the CDP Framework takes care of initializing and executing your system in a structured way. In simple terms, a CDP application goes through the following phases.

Startup & Configuration Loading

When a CDP application is launched, it creates an Application object and loads the XML configuration that describes all the components in that application​. The framework then instantiates each component listed in the configuration and sets up their initial properties and connections (wiring up signals and any references). This involves calling each component’s factory creation method and configuring it according to the XML definitions. Essentially, CDP builds the in-memory object hierarchy exactly as defined by the configuration files.

Initialization & Activation

After all components are created and configured, the framework initializes them and transitions them to an active state​ based on their Activate timing values. In CDP, components often have internal state machines (for example, to handle states like Stopped or Running). During activation, each component’s state machine is started. The CDP framework also establishes the necessary scheduling “processes” (threads) based on the components’ configuration – for example, it will set up timers/threads for each unique combination of Priority and SchedulingGroup used by the components (more on this in the next section). Once activation is complete, the application is fully set up: All components know about each other (through their configured connections) and the scheduler is ready to run them.

Continuous Execution

After startup, the application enters its continuous execution phase. Each component now repeatedly executes its logic at the configured frequency (if it has a cyclic role), under the governance of the CDP scheduler. During each cycle, the framework updates the component’s input signals with any new values from other components before the component’s own Process function runs and then runs the component’s Process (performing whatever computation or control action it is programmed to do)​. Immediately after that, the component’s output signals are published/propagated to any connected inputs so that other components will see the new values by the time their next cycle runs (this is often referred to as “sync in/sync out” for inputs and outputs)​. All components are invoked in this manner according to their individual rates, in a repeating loop. Importantly, the CDP runtime also handles asynchronous events alongside this cyclic execution: if a component sends out a message (an event) to another component, that message is delivered and processed in between the normal cyclic ticks​. In other words, the recipient component will be “woken up” immediately to handle the message, rather than waiting for its next scheduled cycle. This ensures that time-sensitive messages or commands propagate through the system without delay, while the periodic control loops continue to run deterministically. CDP’s engine guarantees that both periodic processing and event-driven processing occur in a coordinated fashion, delivering each piece of data or message to the right component at the right time​. The application continues in this steady-state operation until it is stopped, with CDP managing all timing, data propagation, and event handling behind the scenes.

Note: In the case of a multi-application CDP System, an additional step occurs during startup: after activation, each application broadcasts a discovery message to find other running applications in the same system domain. This allows applications to connect their data paths across the network, enabling inter-application signal routing and messaging​. This discovery happens automatically when the system starts, so from the user’s perspective, it is seamless.

Data Propagation in CDP Framework

Routing and Communication Between Components

In CDP, components do not communicate directly with each other. Instead, they rely on the Routing mechanism. This mechanism uses CDP's hierarchical naming system to propagate both real-time values and messages between components. The Routing mechanism ensures decoupled communication, allowing components to exchange data without creating direct dependencies on one another. Routing enhances flexibility and scalability in distributed control systems by allowing system elements to be modified independently.

Routings define how data flows between components and are configured on component real-time values and messages, specifying source or destination endpoint for communication. Through Routing, CDP ensures that real-time values (such as sensor readings, computed parameters, or control outputs) are efficiently propagated to the appropriate components while simultaneously allowing messages (such as event notifications, and commands) to be reliably transmitted to their intended recipients.

By leveraging Routing, CDP applications can efficiently manage complex interactions while maintaining a well-structured and modular system, ensuring that data reaches the right components at the right time. CDP Studio tracks routings and notifies about broken routings in the Issues pane.

Real-Time Values

Real-time values are used for synchronous communication between components. Simple real-time values subscribe to a single source via Routing in the same or some other component. Before the Process function for the component is called, the real-time values for all the component's input Signals are updated (sync in). In the same way, all the component's output Signals are updated right after the Process function has run (sync out).

Note: It is important to remember that simpler operator-based objects like all Automation resource Operators and Sequencer resource blocks use Arguments as real-time values and all objects have Properties that can be used as a real-time value source.

Configuration Values

Configuration values are used to configure the components and are stored in the configuration each time the value is changed. CDPComponents can have CDPParameters and Properties that are used for configuration. Other objects use mainly Properties for configuration. Operator based blocks also use input Arguments as stored configuration when they are not Routed from a value source.

When Configuration values are used as a source for a real-time value, the value is only propagated when the configuration value is changed and does not used the same sync in/out mechanism, but is updated via a value change event trough the CDP Event system and has a more lax timing.

Messages

Messages are used for asynchronous communication between components. A message is a data structure that contains a Command and a Payload. Messages are delivered to the target component using the configured RoutingList asynchronously and interleaved between periodic process runs.

CDP Standard Runtime Components

CDP Runtime components

All CDP Applications have some standard components that run CDP System services. They are communicating with OS and ethernet, scheduling components, and automatically connecting to other CDP applications. Values, Messages, and Events are also distributed by the CDP runtime system. The CDP runtime components are found as subcomponents inside the hidden a component called CDP. In addition, GUI applications have a component called CDP2Qt. The CDP runtime components should not be removed.

Application Output

The Applications will print some info at startup, like ethernet interface info and versions of CDP and libraries, see below for an example.
It is recommended that this message log is checked, especially during development and commissioning, to check if any error or warning messages are printed.
To get more printouts, see the Debug printout description.

CDP Messagelog

Example of Application Output:

The CDP Message log is available in the Application Output pane at the bottom of CDP Studio, but another possibility to retrieve the message log from a connected application is to click on the LogURL link: Click on the application in Configure mode Project tree and choose the Table Editor tab. Go to the Properties section, find the property called LogURL and click into the Value column. Click on the symbol as shown in the picture below. A web page should then open in your web browser, containing the message log.

Help Menu

When run from the command line, the applications have a command-line interface where you may give keyboard input. By pushing 'h', the application will display a list of keys that can be pushed to get specific printouts, see the example below.
The list of available keys depends on which libraries are linked to the application. It is also possible to add a keyboard handler for your library by calling Application::AddKeyboardHandler(), see Handling keyboard keypresses.

If you do not have a keyboard attached to the control application but are connected online with CDP Studio, you may still invoke the command-line function: In Configure mode, click on the application, and find the Message called SendKeyToKeyboard, enter the character/command you want to give in the column called 'Parameters', and click the Send button. See also Debug Printout below.

Debug Printout

Console applications will normally only print out some info at startup to the command-line interface, and then stop printing. If an error occurs, there might be new printouts. In addition, there is the possibility to increase and decrease the component's debug level. This can be done by changing the value of the property called Debug. A value of 0 means no extra debug printouts, 1 means some printouts, and increasing the value up to 9 gives more printouts. The author of the component decides which debug printouts are available at each level by specifying which debug level they should be shown at.

Note: For more detailed information, and how to make your printouts, see Debugging.

Exceptions in Code

In the c++ code, process functions are surrounded by a try-catch block. If a CDPException is thrown (because an error has been detected by code, a null-pointer is used, or division by zero occurs) the exception will be caught. The CDPComponent will be suspended (the Process-functions will not be called anymore), and the CDPComponent's "Component Suspended" alarm will be Set, and also CDPEngine's "A Component is Suspended" alarm is Set. The time from the error occurs until it is handled varies depending on OS and type of exception: Throwing a CDPException is handled fast. Access violation and division by zero are handled much more slowly. Under Linux, the typical time is a few milliseconds, while under Windows this may take several hundred milliseconds. During this exception-handling period, the Process-functions of other CDPComponents with the same priority are blocked (not called).

Best Practice of System Design

A general system design should be thought through before starting to implement the functionality. This will make it easier to achieve reuse of source code and configurations. Make sure to read through the Developer Guide to get a good understanding of the functionality and possibilities of CDP and CDP Studio.

A control system made with CDP Studio may consist of one or more applications. You can create separate applications dedicated to specific tasks that together form the complete control system. For instance, the user interface (UI) and functional logic could be separated into different applications.

It is advised to not have any logic inside GUI elements in the application but to only have the possibility to give commands to the control system and to display or monitor its status. Doing it this way makes sure that the display of the state is separated from the control and storage of the state. If the user interface screen is somehow taken offline, the control system can run unimpeded, and a replacement screen can be added without losing any state information. Another benefit is that if the control system decides to not perform the commanded action, the state of multiple displays will always be automatically correct across all the connected displays.

Applications can contain components that run with different frequencies and priorities. You may run several Applications on the same controller or separate controllers.

When designing control logic, it is not necessary to focus on protocols and details regarding I/O communication. Just assume that you will have these signals available. The signals will be provided by I/O server(s) or other applications/components/subcomponents. Focus on developing reusable components by using state machines and transitions. By having multiple states, you can simplify the logic and make it easier to follow what happens in each state, as the code is very specific to only that state. Alarms, connectors, and/or signals can be used to verify that each component is in a correct state.

Component Structure

The component tree structure is mostly controlled by how the signal flow is organized and how the Execution order is set. The default Execution order is set to TopDown. This means that when fs, Priority, SchedulingGroup and SchedulingOrder are the same on all components, then the components in the expanded Project tree are executed from top to bottom, in the order they are listed. Example:

The Components in the ExecutionOrderApp above are executed in the order One, Two, Three, Four, Five, Six. For more information about this, see the CDPComponent documentation.

Many Versus Few CDPComponents

If you have a lot of I/O signals and wonder about how to design your application in terms of performance, it is far better to build up your application with fewer CDPComponents containing many CDPSignals than having many CDPComponents containing few CDPSignals. The reason is that every time CDPComponents need to run/be scheduled, CDP and the OS have some task-switch overhead. On the other hand, you should not put too much time-consuming (or blocking) functionality into a few components, as this may negatively impact other components of the same priority.

In general, it is better to focus on the readability, reusability and logical structure of the components, as CPUs tend to become faster and more powerful with each new generation while increasing non-bounded code quantity becomes harder and harder to manage over time.

Safe Value CDPSignals

If you have CDPSignals/Properties in your application Routed from some other CDPSignals/Properties in another application, you can choose what happens with the values of your input signals/properties when the other application disconnects. In YourAppName.CDP.MessengerIOServer component, there is a property called KeepLastValueOnDisconnect. If set, CDPSignals/Properties keep the last known value when the Routing source disappears. If not set, the value is set to 0.

Note: The default value of KeepLastValueOnDisconnect is 0, meaning the value is set to 0 in case of disconnect.

For CDPProperties, KeepLastValueOnDisconnect can be overridden in a model. All CDPProperties have a setting called KeepLastValueOnDisconnect, which can have values Default (or empty), 1 or 0. If set to Default (or left empty), then the global setting from the MessengerIOServer-component is used. If set to 1, then the property will keep the last known value when the routing source disappears, otherwise, the property value is set to 0 on disconnect. This setting is only configurable in the Library (model) configuration, and not in the System configuration.

Note: To be able to see the CDP component under the Application, select the Table Editor, click on the Application, and in the Search Filter (top right), de-select Hide Base Model Items and Hide Internal Items filters. You will now see the CDP component in the Subcomponents table, and be able to navigate into the MessengerIOServer to change/verify the KeepLastValueOnDisconnect setting. See filter help for more information on filtering.

Framework - CDP Core Advanced: CDP Model syntax

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

My account

Follow CDP

  • LinkedIn
  • YouTube
  • GitHub

© Copyright 2025 CDP Technologies. Privacy and cookie policy.

Return to top