The generated code itself is identical for Windows and Linux; hence code that was generated under Windows can be used in a Linux SDK and vice versa. The integration of the generated code into your application strongly depends on the build environment you are using, e.g. Visual Studio, Eclipse, CMake, etc. This example will describe how to integrate the generated code into the delivered CMake files of the Unified Automation Ansi C SDK in six simple steps.
- Note
- There are three different files called CMakeLists.txt involved in the following HowTo. Pay attention to the respective folders given in the text.
Step 1: Adding the Generated Provider to CMakeLists.txt
First of all you have to add the CMake option of the newly generated provider to the CMakeLists.txt file of the Ansi C SDK in ([SDK Installation Directory]/src/CMakeLists.txt). Add the marked line:
###############################################################################
# Project Options
OPTION( UASTACK "Set to ON to build the UaStack library" ON )
OPTION( BUILD_UASERVERC "Set to ON to build the UaServer library for Ansi C" ON )
OPTION( BUILD_UASERVERC_APP "Set to ON to build the UaServer Ansi C application" ON )
OPTION( BUILD_SERVER_PROVIDER "Set to ON to build the UaServer Ansi C with server provider" ON )
OPTION( BUILD_DEMO_PROVIDER "Set to ON to build the UaServer Ansi C with sample provider" ON )
OPTION( BUILD_EXAMPLEPROJECT_PROVIDER "Set to ON to build the UaServer Ansi C with generated exampleproject provider" ON )
OPTION( BUILD_DI_PROVIDER "Set to ON to build the UaServer Ansi C with di provider" ON )
OPTION( BUILD_PLCOPEN_PROVIDER "Set to ON to build the UaServer Ansi C with plcopen provider" ON )
OPTION( BUILD_EXAMPLES "Set to ON to build the UaServer Ansi C with examples" OFF )
###############################################################################
In addition to that, add the include directories of the generated provider to the file [SDK Installation Directory]/src/uaserver/uaserverc/CMakeLists.txt of the server module as shown below.
####################################### Different Provider ########################################
...
IF (BUILD_DEMO_PROVIDER)
include_directories(${serverlib_SOURCE_DIR}/providers/demo)
add_subdirectory(providers/demo)
ENDIF (BUILD_DEMO_PROVIDER)
IF (BUILD_EXAMPLEPROJECT_PROVIDER)
include_directories(${serverlib_SOURCE_DIR}/providers/exampleproject)
add_subdirectory(providers/exampleproject)
ENDIF (BUILD_EXAMPLEPROJECT_PROVIDER)
...
Step 2: Adding the Generated Provider into the Server Application’s CMakeLists.txt
In the previous step, the generated provider is only added into the server’s main library, but you also have to add the provider into the server application’s CMakeLists.txt ([SDK Installation Directory]/src/applications/uaserverc/linux/CMakeLists.txt) and set the include directory path to the generated code.
####################################### DIFferent Configurations ########################################
...
IF (BUILD_DEMO_PROVIDER)
add_definitions(-DHAVE_DEMOPROVIDER)
include_directories(${UA_SRC}/uaserver/uaserverc/providers/demo)
set(PROVIDER_LIST ${PROVIDER_LIST} demoprovider)
ENDIF (BUILD_DEMO_PROVIDER)
IF (BUILD_EXAMPLEPROJECT_PROVIDER)
add_definitions(-DHAVE_EXAMPLEPROJECTPROVIDER)
include_directories(${UA_SRC}/uaserver/uaserverc/providers/exampleproject)
set(PROVIDER_LIST ${PROVIDER_LIST} exampleprojectprovider)
ENDIF (BUILD_EXAMPLEPROJECT_PROVIDER)
...
Step 3: Implementing the Example Method of the Generated Provider
Now, we implement the method in the generated file [SDK Installation Directory]/src/uaserver/uaserverc/providers/exampleproject/uaprovider_exampleproject_myobjecttype_methods.c as shown below.
OpcUa_StatusCode UaProvider_ExampleProject_MyObjectType_fktSum(
UaServer_ProviderCallContext *a_pCallContext ,
OpcUa_NodeId *pObjectId ,
OpcUa_UInt32 in1,
OpcUa_UInt32 in2,
OpcUa_UInt32 *out1)
{
OpcUa_StatusCode ret = OpcUa_Good;
OpcUa_ReferenceParameter(a_pCallContext);
OpcUa_ReferenceParameter(pObjectId);
OpcUa_UInt32_Initialize(out1);
*out1 = in1 + in2;
return ret;
}
Step 4: Adding Code to the Server Applications Source File
Then, locate the source file of the application ([SDK Installation Directory]/src/applications/uaserverc/linux/uaserver.c) and include the generated provider.
...
#ifdef HAVE_DEMOPROVIDER
# include <uaprovider_demo.h>
#endif
#include <uaprovider_exampleproject.h>
For enabling the server to start up the provider, it has to be added to the server’s provider list.
...
memset( &Provider, 0, sizeof( Provider ) );
#ifdef HAVE_DEMOPROVIDER
# ifdef UAPROVIDER_STATIC
Provider.pfInit = UaProvider_Demo_Initialize;
# else
Provider.sProviderLibrary = "demoprovider";
# endif
UaServer_ProviderList_AddProvider( &g_UaServer, &Provider );
#endif
#ifdef HAVE_EXAMPLEPROJECTPROVIDER
# ifdef UAPROVIDER_STATIC
Provider.pfInit = UaProvider_ExampleProject_Initialize;
# else
Provider.sProviderLibrary = "exampleprojectprovider";
# endif
UaServer_ProviderList_AddProvider( &g_UaServer, &Provider );
#endif
// New code ends
Step 5: Compiling and Running the Server Application
After completing the previous steps, you can compile the whole project with the delivered script buildSdk.sh.
If everything went well, you can find the applications uaserverc and uaservercd in the folder [SDK Installation Directory]/bin.
Step 6: Connect to the Server Application via UaExpert
The last step is to check if the generated provider and its method is correctly implemented. Just connect to the server with Unified Automation’s UaExpert, browse to your generated object type (Root → Types → ObjectTypes → BaseObjectType → MyObjectType) and call the method.