Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
531 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# open62541 Realtime OPC UA PubSub Publisher | ||
|
||
This example is a self-contained PubSub publisher over raw Ethernet. It | ||
showcases the realtime-capabilities of OPC UA PubSub. The core idea is that the | ||
publisher callback can be triggered from a time-triggered system interrupt and | ||
sends out the PubSub message within the interrupt. | ||
|
||
The publisher retrieves its configuration and the payload data from the | ||
information model of an OPC UA server. (It could also be run in a standalone | ||
mode without an OPC UA server.) Since the publisher interrupt preempts the | ||
execution of the normal OPC UA server, the information model needs to be | ||
consistent at every time (reentrant). The specific techniques used to make the | ||
OPC UA server reentrant are described in this publication: | ||
|
||
``` | ||
@inproceedings{pfrommer2018open, | ||
title={Open source OPC UA PubSub over TSN for realtime industrial communication}, | ||
author={Pfrommer, Julius and Ebner, Andreas and Ravikumar, Siddharth and Karunakaran, Bhagath}, | ||
booktitle={2018 IEEE 23rd International Conference on Emerging Technologies and Factory Automation (ETFA)}, | ||
pages={1087--1090}, | ||
year={2018}, | ||
organization={IEEE} | ||
} | ||
``` | ||
|
||
Please cite if you use this work. | ||
|
||
OPC UA PubSub for open62541 is funded by an industry consortium in the context | ||
of an OSADL project (Open Source Automation Development Lab). Technical | ||
development is conducted by Fraunhofer IOSB and Kalycito Infotech. | ||
|
||
https://www.osadl.org/OPC-UA-TSN.opcua-tsn.0.html | ||
|
||
## Realtime communication with Time-Sensitive Networking (TSN) | ||
|
||
OPC UA PubSub can be used together with TSN for hard-realtime Ethernet-based | ||
communication. Vendor-specific APIs are commonly used for TSN capabilities. This | ||
example only uses the standard Linux API for raw Ethernet. Vendor-specific | ||
examples may be added at a later time. | ||
|
||
## Building the RT Publisher | ||
|
||
The main open62541 library needs to be built with the following build options | ||
enabled for the realtime PubSub example. Note that some of the examples supplied | ||
with open62541 will not link against the library with these build options. For | ||
good timings, ensure that the `CMAKE_BUILD_TYPE` is set to `Release`. | ||
|
||
- UA_ENABLE_PUBSUB | ||
- UA_ENABLE_PUBSUB_ETH_UADP | ||
- UA_ENABLE_PUBSUB_CUSTOM_PUBLISH_HANDLING | ||
- UA_ENABLE_MALLOC_SINGLETON | ||
- UA_ENABLE_IMMUTABLE_NODES | ||
|
||
The publisher contains some hard-coded values that need to be adjusted to | ||
specific systems. Please check the top definitions in | ||
`pubsub_interrupt_publish.c` and `start_rt_publish.sh`. | ||
|
||
The publisher code is built and linked against the main open62541 library as follows: | ||
|
||
`gcc -O2 ../examples/pubsub_realtime/pubsub_interrupt_publish.c ../examples/pubsub_realtime/bufmalloc.c -I../include -I../plugins/include -Isrc_generated -I../arch/posix -I../arch -I../plugins/networking bin/libopen62541.a -lrt -o rt_publisher` | ||
|
||
## Running the RT Publisher | ||
|
||
The publisher must be run as root for direct access to the Ethernet interface. | ||
|
||
`# ./rt_publisher` | ||
|
||
The example contains a script to be used with RT-Preempt Linux Kernel. The | ||
following command starts the publisher, locks the process to a specific CPU, and | ||
sets the scheduling policy. | ||
|
||
`# start_rt_publish.sh ./rt_publisher` | ||
|
||
The measurements are written to a file (publisher_measurement.csv) with the | ||
following fields for every publish callback: | ||
|
||
- Counter | ||
- Publication Interval | ||
- Nominal time for the current publish | ||
- Start delay from the nominal time | ||
- Duration of the publish callback |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. | ||
* See http://creativecommons.org/publicdomain/zero/1.0/ for more information. | ||
* | ||
* Copyright 2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) | ||
*/ | ||
|
||
#include "bufmalloc.h" | ||
|
||
#define MALLOCMEMBUFSIZE 16384 | ||
|
||
/* Every element has the memory layout [length (size_t) | buf (length * sizeof(char)) ... ]. | ||
* The pointer to buf is returned. */ | ||
static char membuf[MALLOCMEMBUFSIZE]; | ||
static size_t pos; | ||
|
||
static void * membufMalloc(size_t size) { | ||
if(pos + size + sizeof(size_t) > MALLOCMEMBUFSIZE) | ||
return NULL; | ||
char *begin = &membuf[pos]; | ||
*((size_t*)begin) = size; | ||
pos += size + sizeof(size_t); | ||
return &begin[sizeof(size_t)]; | ||
} | ||
|
||
static void membufFree(void *ptr) { | ||
/* Don't do anyting */ | ||
} | ||
|
||
static void * membufCalloc(size_t nelem, size_t elsize) { | ||
size_t total = nelem * elsize; | ||
void *mem = membufMalloc(total); | ||
if(!mem) | ||
return NULL; | ||
memset(mem, 0, total); | ||
return mem; | ||
} | ||
|
||
static void * (membufRealloc)(void *ptr, size_t size) { | ||
size_t orig_size = ((size_t*)ptr)[-1]; | ||
if(size <= orig_size) | ||
return ptr; | ||
void *mem = membufMalloc(size); | ||
if(!mem) | ||
return NULL; | ||
memcpy(mem, ptr, orig_size); | ||
return mem; | ||
} | ||
|
||
void resetMembuf(void) { | ||
pos = 0; | ||
} | ||
|
||
void useMembufAlloc(void) { | ||
pos = 0; | ||
UA_globalMalloc = membufMalloc; | ||
UA_globalFree = membufFree; | ||
UA_globalCalloc = membufCalloc; | ||
UA_globalRealloc = membufRealloc; | ||
} | ||
|
||
void useNormalAlloc(void) { | ||
UA_globalMalloc = malloc; | ||
UA_globalFree = free; | ||
UA_globalCalloc = calloc; | ||
UA_globalRealloc = realloc; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. | ||
* See http://creativecommons.org/publicdomain/zero/1.0/ for more information. | ||
* | ||
* Copyright 2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) | ||
*/ | ||
|
||
#include <open62541/config.h> | ||
|
||
void resetMembuf(void); | ||
void useMembufAlloc(void); | ||
void useNormalAlloc(void); |
Binary file not shown.
Oops, something went wrong.