学习open62541 --- [1] 初始

80 篇文章 481 订阅

open62541是OPC UA的开源C(C99)实现,license是Mozilla Public License v2.0,可以免费用于个人和商业用途,其网站为https://open62541.org/

本文主要讲述如何编译open62541,并运行简单的demo,运行环境是ubuntu16.04。Windows下的使用方法请查看这篇文章


一 下载源码

使用以下命令去下载源码,本文写作时最新release版本是1.1.6版,

git clone -b v1.1.6  https://github.com/open62541/open62541.git

open62541还有一些子模块,当enable一些特殊功能时就需要他们了,例如自定义namespace等,这个需要使用以下命令去下载(在上面下载源码后的源码根目录下操作)

git submodule update --init --recursive

如果遇到问题,先看下这个避坑指南


二 官方文档

可以去官方网站上下载,也可以点击这里下载,提取码是huru,本人下载好后上传到百度云。


三 编译

cd到源码根目录下,创建build目录,然后cd到build目录下,输入以下命令去调用cmake,

cmake .. -DUA_ENABLE_AMALGAMATION=ON

接着再运行make,生成以下文件,
在这里插入图片描述
这里解释下cmake的命令行中的UA_ENABLE_AMALGAMATION选项,这是open62541的CMakeLists.txt提供的选项,专门用于生成single distribution版本的open62541,即open62541.c 和 open62541.h文件,方便用于集成到其它程序里。

在bin目录下生成的是open62541的静态库,可以用于和别的程序进行链接。
在这里插入图片描述
也就是说open62541的CMakeLists.txt提供了2种调用方式:

  1. open62541.h + libopen62541.a
  2. open62541.h + open62541.c

这样我们就可以很方便的把open62541集成到自己代码里来了,这2种方式下面都会讲下,

PS:有些同学在Ubuntu18.04及以上的版本里编译后,在链接时会出现问题,这个和CMake版本有关系,如果CMake版本高于3.9,那么可以在CMakeLists.txt里找到CMAKE_INTERPROCEDURAL_OPTIMIZATION,把其值设置为OFF就可以了。
另外,本人觉得这个和Ubuntu自身也是有关系的,我后来改用Debian,CMake版本是3.13,也不会遇到问题。


四 运行demo (第1种方法)

我们在别的地方建立一个目录runDemoOpen62541,然后把libopen62541.a 和open62541.h拷贝进来,然后在这个目录下创建bin和build目录,创建server.c,client.c和CMakeLists.txt,整体结构如下,
在这里插入图片描述
server.c,client.c和CMakeLists.txt内容分别如下,

// server.c

/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */

#include "open62541.h"

#include <signal.h>
#include <stdlib.h>

UA_Boolean running = true;

static void stopHandler(int sign) {
    UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "received ctrl-c");
    running = false;
}

int main(void) 
{
    signal(SIGINT, stopHandler);
    signal(SIGTERM, stopHandler);

    UA_Server *server = UA_Server_new();
    UA_ServerConfig_setDefault(UA_Server_getConfig(server));
    UA_StatusCode retval = UA_Server_run(server, &running);
    
    UA_Server_delete(server);
    
    return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}

// client.c,功能主要是从server那里获取时间

#include <stdlib.h>
#include "open62541.h"

int main(void) 
{
    UA_Client *client = UA_Client_new();
    UA_ClientConfig_setDefault(UA_Client_getConfig(client));
    UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
    if(retval != UA_STATUSCODE_GOOD) {
        UA_Client_delete(client);
        return (int)retval;
    }
    
    /* Read the value attribute of the node. UA_Client_readValueAttribute is a
    * wrapper for the raw read service available as UA_Client_Service_read. */
    UA_Variant value; /* Variants can hold scalar values and arrays of any type */
    UA_Variant_init(&value);
    
    /* NodeId of the variable holding the current time */
    const UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);
    retval = UA_Client_readValueAttribute(client, nodeId, &value);
    
    if(retval == UA_STATUSCODE_GOOD && UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_DATETIME])) 
    {
        UA_DateTime raw_date = *(UA_DateTime *) value.data;
        UA_DateTimeStruct dts = UA_DateTime_toStruct(raw_date);
        UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "date is: %u-%u-%u %u:%u:%u.%03u\n",
            dts.day, dts.month, dts.year, dts.hour, dts.min, dts.sec, dts.milliSec);
    }
    
    /* Clean up */
    UA_Variant_clear(&value);
    UA_Client_delete(client); /* Disconnects the client internally */
    
    return EXIT_SUCCESS;
}

CMakeLists.txt内容如下,

cmake_minimum_required(VERSION 3.5)

project(demoOpen62541)

set (EXECUTABLE_OUTPUT_PATH  ${PROJECT_SOURCE_DIR}/bin)

add_definitions(-std=c99)

include_directories(${PROJECT_SOURCE_DIR}/open62541)

find_library(OPEN62541_LIB libopen62541.a HINTS ${PROJECT_SOURCE_DIR}/open62541/bin)

add_executable(server ${PROJECT_SOURCE_DIR}/src/server.c)
target_link_libraries(server ${OPEN62541_LIB})

add_executable(client ${PROJECT_SOURCE_DIR}/src/client.c)
target_link_libraries(client ${OPEN62541_LIB})

然后cd到build目录下,运行cmake .. && make,就会在bin目录下生成server和client这2个bin,
在这里插入图片描述
client的功能是从server那里获取时间,下面就先运行server,./server
在这里插入图片描述
然后运行client,./client,可以看到打印出来的server时间,
在这里插入图片描述
这样server和client之间就通信成功了!


五 运行demo (第2种方法)

我们在别的地方建立一个目录runDemoOpen62541,然后把open62541.c 和open62541.h拷贝进来,然后在这个目录下创建bin和build目录,创建server.c,client.c和CMakeLists.txt,整体结构如下,
在这里插入图片描述
server.c和client.c的代码和上面讲第1种方法的内容一样,CMakeLists.txt不一样,内容如下,

cmake_minimum_required(VERSION 3.5)

project(demoOpen62541)

set (EXECUTABLE_OUTPUT_PATH  ${PROJECT_SOURCE_DIR}/bin)

add_definitions(-std=c99)

include_directories(${PROJECT_SOURCE_DIR}/open62541)

add_executable(server ${PROJECT_SOURCE_DIR}/src/server.c ${PROJECT_SOURCE_DIR}/open62541/open62541.c)

add_executable(client ${PROJECT_SOURCE_DIR}/src/client.c ${PROJECT_SOURCE_DIR}/open62541/open62541.c)

然后cd到build目录下,运行cmake .. && make,就会在bin目录下生成server和client这2个bin,
在这里插入图片描述
client的功能是从server那里获取时间,下面就先运行server,./server
在这里插入图片描述
然后运行client,./client,可以看到打印出来的server时间,
在这里插入图片描述
这样server和client之间就通信成功了!


六 小结

本文主要讲述open62541的编译和相关demo的运行,当然这里讲述的仅仅是个入门,详细内容可以看相关的文档(在open62541的网站上)。

如果有写的不对的地方,希望能留言指正,谢谢阅读。

评论 62
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值