open62541交叉编译

     好久没有做嵌入式Arm Linux 的开发了。最近要将open62541 的应用程序移植到i.mx6u 嵌入式控制器。网络上讲解i.mx6 交叉编译的文章太多了。但是都过于复杂,大多数使用虚拟机实现。其实在ubuntu OS 下,开发ARM 嵌入式应用软件相对是相当简单的。这里记录了在ubuntu Linux 下,交叉编译i.mx 应用软件的过程。

 安装交叉编译工具及其基本库

目标设备为两种ARM

NXP i.mx6 基于Arm V7

RK3399

arm-linux-gnueabihf-gcc

imx6 是arm v7 架构,使用arm-linux-gnueabihf-gcc 和 arm-linux-gnueabihf-g++

sudo apt-get update
sudo apt-get install gcc-arm-linux-gnueabihf
sudo apt-get install g++-arm-linux-gnueabihf

   值得注意的是 安装这两个交叉编译器之后,在usr/lib 中自动建立了 /gcc-cross/arm-linux-gnueabihf/11目录,内部包含了gcc 基本的库,例如libc.so 。自己编译的库也copy 到这个目录中。

g++-aarch64-linux-gnu

   对于Arm v8 64位架构的处理器,例如RK3399 的 cortex-A53 ,需要使用gcc-aarch64-linux-gnu和g++-aarch64-linux-gnu

sudo apt-get install gcc-aarch64-linux-gnu
sudo apt-get install gcc-aarch64-linux-gnu

关于与目标机的兼容性

遇到的最大问题是libc.so.6 等动态库不兼容的问题,我部分解决的方法是

1. 将目标机器上的lib 考到编译机上。

2。 应用程序使用静态编译。

测试 gcc

为了测试安装的交叉编译工具,先编写了一个Test 程序

#include 
#include 
int main(){
    int x;
    x=pow(3,2);
    printf("%d\n",x);
}

编译命令

arm-linux-gnueabihf-gcc test1.c -o test1

 编译open62541 的依赖库

1 如果open62541 Enable NodesetLoad ,需要依赖库libxml.so。

编译安装方式:

下载 源码

使用cmake

libxml 的选项比较多,容易出错。我做了一些选择。


2 如果open62541 Enable History ,需要依赖库sqlite3

编译安装方式:

编译 open62541

        由于之前安装了ubuntu open62541 库,include 放置在usr/local/include 中。当交叉编译时,仍然使用它,可能会有点差错,比如Eable pub/sub 时,要UA_ENABLE_AMALGAMATION 打勾。

libxml.so 要指向/gcc-cross/arm-linux-gnueabihf/11。

open62541交叉编译_第1张图片

编译完成后,copy 到/gcc-cross/arm-linux-gnueabihf/11 中:

sudo cp libopen62541.so /usr/lib/gcc-cross/arm-linux-gnueabihf/11/libopen62541.so

编译Opcua 应用程序

编辑最小server

/* 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 

/* Build Instructions (Linux)
 * - g++ server.cpp -lopen62541 -o server */

using namespace std;

int main() {
    UA_Server *server = UA_Server_new();

    // add a variable node to the adresspace
    UA_VariableAttributes attr = UA_VariableAttributes_default;
    UA_Int32 myInteger = 42;
    UA_Variant_setScalarCopy(&attr.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]);
    attr.description = UA_LOCALIZEDTEXT_ALLOC("en-US","the answer");
    attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US","the answer");
    UA_NodeId myIntegerNodeId = UA_NODEID_STRING_ALLOC(1, "the.answer");
    UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME_ALLOC(1, "the answer");
    UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
    UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
    UA_Server_addVariableNode(server, myIntegerNodeId, parentNodeId,
                              parentReferenceNodeId, myIntegerName,
                              UA_NODEID_NULL, attr, NULL, NULL);

    /* allocations on the heap need to be freed */
    UA_VariableAttributes_clear(&attr);
    UA_NodeId_clear(&myIntegerNodeId);
    UA_QualifiedName_clear(&myIntegerName);

    UA_StatusCode retval = UA_Server_runUntilInterrupt(server);

    UA_Server_delete(server);
    return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}

编译命令

aarch64-linux-gnu-g++ server.cpp -o server -lopen62541 -lxml2 -L /home/yao/yao2023/RK3399Project/aarch64-linux-gnu/lib  -static  -I /usr/local/include --std=c++2a

   由于open62541 中包含了xml 动态库。因此要-lxml2.如果将xml编译成为静态库 可能就没有这个问题。

 编译成为静态库,避免libc 等动态库不兼容的问题。

复制到目标机运行

scp ./server [email protected]:/home/application/server

编译 IEC61499 runtime

aarch64-linux-gnu-g++   ./*.cpp ./FunctionBlocks/*.cpp -I ./modbusTCP   -o uaForteA  -lopen62541  -lxml2 -I /usr/local/include --std=c++2a -L /home/yao/yao2023/RK3399Project/aarch64-linux-gnu/lib  -static

复制到目标机运行

Go 语言的交叉编译

在我们的项目中,有Web 实现设备管理,采用Go 语言编写web 相对NodeJS 更精简一些。下面记录了Go 语言应用程序的交叉编译,这是非常简单的。

测试代码

# shared.go
package main

import "C"

//export Sum
func Sum(a, b int) int {
    return a + b
}

func main(){}

 32-bit arm

CGO_ENABLED=1 GOOS=linux GOARCH=arm CC=arm-linux-gnueabihf-gcc go build -buildmode=c-shared -o share.so 

64-bit arm

CGO_ENABLED=1 GOOS=linux GOARCH=arm64 CC=aarch64-linux-gnu-gcc-5.3.1 go build -buildmode=c-shared -o share.so 

构建了一个动态库。 

你可能感兴趣的:(ubuntu,linux,IEC61499,OPCUA)