... | @@ -1287,24 +1287,16 @@ On a 12 core host with 16 GB RAM, a parallelism of 8 may be a good choice. Try d |
... | @@ -1287,24 +1287,16 @@ On a 12 core host with 16 GB RAM, a parallelism of 8 may be a good choice. Try d |
|
The default set of compiler flags applied by the build system consume significant memory.
|
|
The default set of compiler flags applied by the build system consume significant memory.
|
|
We recommend using "-O2 -flto -pipe" (_to be confirmed_) instead. This is how you pass custom compiler flags for your ICD-module:
|
|
We recommend using "-O2 -flto -pipe" (_to be confirmed_) instead. This is how you pass custom compiler flags for your ICD-module:
|
|
|
|
|
|
In the module wscript:
|
|
In your project wscript:
|
|
~~~python
|
|
~~~python
|
|
# module-wscipt
|
|
from wtools import project
|
|
from wtools import module
|
|
[...]
|
|
def configure(cnf):
|
|
|
|
cnf.env.CXXFLAGS_MALPYTHON = '-O2 -flto -pipe'
|
|
|
|
module.declare_malicd()
|
|
|
|
~~~
|
|
|
|
|
|
|
|
or for a whole package:
|
|
|
|
~~~python
|
|
|
|
from wtools import package
|
|
|
|
def configure(cnf):
|
|
def configure(cnf):
|
|
cnf.env.CXXFLAGS_MALPYTHON = '-O2 -flto -pipe'
|
|
cnf.env.CXXFLAGS_MALPYTHON = '-O2 -flto -pipe'
|
|
package.declare_package(recurse='m4lcsif m4amlcsif m4cslcsif m4kslcsif')
|
|
[...]
|
|
~~~
|
|
~~~
|
|
|
|
|
|
4 Refactor your ICD
|
|
4. Refactor your ICD
|
|
|
|
|
|
Reduce the memory need by splitting the big ICDs up into 2 or more smaller ICD modules.
|
|
Reduce the memory need by splitting the big ICDs up into 2 or more smaller ICD modules.
|
|
|
|
|
... | @@ -1314,7 +1306,7 @@ Reduce the memory need by splitting the big ICDs up into 2 or more smaller ICD m |
... | @@ -1314,7 +1306,7 @@ Reduce the memory need by splitting the big ICDs up into 2 or more smaller ICD m |
|
1. Find RAM consumers and stop them, at least temporarily. For example, ElasticSearch uses a significant amount of RAM: `sudo cii-services stop elasticsearch`
|
|
1. Find RAM consumers and stop them, at least temporarily. For example, ElasticSearch uses a significant amount of RAM: `sudo cii-services stop elasticsearch`
|
|
|
|
|
|
2. Add temporary swap space to your host
|
|
2. Add temporary swap space to your host
|
|
```
|
|
```bash
|
|
# As root:
|
|
# As root:
|
|
fallocate -l 8G /swapfile
|
|
fallocate -l 8G /swapfile
|
|
dd if=/dev/zero of=/swapfile bs=1024 count=8388608
|
|
dd if=/dev/zero of=/swapfile bs=1024 count=8388608
|
... | @@ -1363,7 +1355,7 @@ The first warning message indicates that your client has received a piece of dat |
... | @@ -1363,7 +1355,7 @@ The first warning message indicates that your client has received a piece of dat |
|
|
|
|
|
**Example of topic definition with port-clash**
|
|
**Example of topic definition with port-clash**
|
|
|
|
|
|
```
|
|
```xml
|
|
<pubsub_topic>
|
|
<pubsub_topic>
|
|
<topic_name>sm:current_pos</topic_name>
|
|
<topic_name>sm:current_pos</topic_name>
|
|
<topic_type>sm_current_pos</topic_type>
|
|
<topic_type>sm_current_pos</topic_type>
|
... | @@ -1548,7 +1540,7 @@ Examples are easily found in the "Fast DDS" documentation and user forums. |
... | @@ -1548,7 +1540,7 @@ Examples are easily found in the "Fast DDS" documentation and user forums. |
|
|
|
|
|
Example (C++):
|
|
Example (C++):
|
|
|
|
|
|
```
|
|
```cpp
|
|
auto publisher = factory.getPublisher<elt::telem::Temperature>(uri, {
|
|
auto publisher = factory.getPublisher<elt::telem::Temperature>(uri, {
|
|
std::make_shared<mal::ps::qos::Latency>(std::chrono::milliseconds(100)),
|
|
std::make_shared<mal::ps::qos::Latency>(std::chrono::milliseconds(100)),
|
|
std::make_shared<mal::ps::qos::Deadline>(std::chrono::seconds(1)) }, {
|
|
std::make_shared<mal::ps::qos::Deadline>(std::chrono::seconds(1)) }, {
|
... | @@ -1654,25 +1646,17 @@ The CII MAL Pub/Sub API utilizes OPC/UA Data Access Reads and Writes, as well OP |
... | @@ -1654,25 +1646,17 @@ The CII MAL Pub/Sub API utilizes OPC/UA Data Access Reads and Writes, as well OP |
|
|
|
|
|
- If the subscriber CII URI contains multiple nodes (i.e. the XML ICD type contains multiple attributes) then the Subscriber launches a thread to perform periodic polling of data from the OPC/UA server. The rate is based on the properties passed in creating the subscriber. e.g.
|
|
- If the subscriber CII URI contains multiple nodes (i.e. the XML ICD type contains multiple attributes) then the Subscriber launches a thread to perform periodic polling of data from the OPC/UA server. The rate is based on the properties passed in creating the subscriber. e.g.
|
|
|
|
|
|
```
|
|
```java
|
|
try {
|
|
try {
|
|
|
|
|
|
subscriber = factory.getSubscriber\<T>(opcua_uri, ::elt::mal::ps::qos::QoS::DEFAULT,
|
|
subscriber = factory.getSubscriber\<T>(opcua_uri, ::elt::mal::ps::qos::QoS::DEFAULT,
|
|
|
|
|
|
{{"opc.ps.outstandingPublishRequests","5"},{"opc.asyncLoopExecutionPeriodMs","50"},
|
|
{{"opc.ps.outstandingPublishRequests","5"},{"opc.asyncLoopExecutionPeriodMs","50"},
|
|
|
|
|
|
{"opc.asyncCallSubmitTimeoutMs","1000"},
|
|
{"opc.asyncCallSubmitTimeoutMs","1000"},
|
|
|
|
|
|
{"opc.ps.pollingPeriodMs","20000"},
|
|
{"opc.ps.pollingPeriodMs","20000"},
|
|
|
|
|
|
{"opc.asyncCallRetryPeriodMs","250"}});
|
|
{"opc.asyncCallRetryPeriodMs","250"}});
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
catch(...) {
|
|
catch(...) {
|
|
|
|
|
|
throw;
|
|
throw;
|
|
|
|
|
|
}
|
|
}
|
|
```
|
|
```
|
|
|
|
|
... | @@ -1689,37 +1673,23 @@ The ICD is termed "virtual" in CII nomenclature as it does not require definitio |
... | @@ -1689,37 +1673,23 @@ The ICD is termed "virtual" in CII nomenclature as it does not require definitio |
|
|
|
|
|
This approach means OPC/UA Data Access read (and write) are synchronous, and may be called as needed by the application.
|
|
This approach means OPC/UA Data Access read (and write) are synchronous, and may be called as needed by the application.
|
|
|
|
|
|
```
|
|
```cpp
|
|
namespace mal {
|
|
namespace mal {
|
|
namespace rr {
|
|
namespace rr {
|
|
namespace da {
|
|
namespace da {
|
|
|
|
|
|
class DataAccess : public ::elt::mal::rr::RrEntity {
|
|
class DataAccess : public ::elt::mal::rr::RrEntity {
|
|
|
|
|
|
public:
|
|
public:
|
|
|
|
|
|
[...]
|
|
[...]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
template <typename T>
|
|
|
|
|
|
void read(::elt::mal::ps::DataEntity\<T>& value) {
|
|
void read(::elt::mal::ps::DataEntity\<T>& value) {
|
|
|
|
|
|
readUnsafe(&value);
|
|
readUnsafe(&value);
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
template <typename T>
|
|
|
|
|
|
void write(const ::elt::mal::ps::DataEntity\<T>& value) {
|
|
void write(const ::elt::mal::ps::DataEntity\<T>& value) {
|
|
|
|
|
|
writeUnsafe(&value);
|
|
writeUnsafe(&value);
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
... | | ... | |