1.前言

假如我们需要在CodeSys的编程环境中使用我们自己的功能,比如:用第三方的IO板卡通讯、PDF文件生成、相机采集图像并处理等等一些复杂的功能,那就可以使用CodeSys提供的【Extension SDK】功能,通过C语言动态库接口来实现。
这里简单记录一下如何创建能够被CodeSys识别的C语言动态库。

2.前期准备

这里我运行codesys runtime的环境是一个arm64板子,板子上已经安装好了gcc等编译工具链。(一开始我是打算直接在本地的win x64上搞得,但是官方提供的例子是在linux上操作的,那我只好用arm开发板了)
在这里插入图片描述
通过CodeSys开发环境安装的runtime
在这里插入图片描述

3.创建CodeSys库工程

参考这里【CodeSys V3.5创建一个编译库】,创建一个Library工程。
需要注意的是,一定要按照上面例程的流程:先创建标准工程–》工程另存为*.Library文件。只有这样才不会在将工程另存为编译库时报错(会报文档生成库未安装之类的错误),具体我也不知道为啥。
假如直接创建Library工程,然后在工程另存为编译库时报错,就需要安装CODESYS Library Documentation Support:
在这里插入图片描述

在程序组织单元页面中添加POU(函数),注意我们目前是只能通过C的库调用函数,暂时还不能实例化C++的类,但是C的库里面可以包含C++的内容,只要导出到库的函数是C的形式就行,这个可以等下看看我的C文件就知道什么意思了。
在这里插入图片描述

3.1.函数名必须包含_cext

创建函数的时候,函数名必须要包含_cext,否则在后面编译时会报错。
在这里插入图片描述创建好函数并且定义好输入变量、返回值后,在函数节点上右键-》属性-》编译中勾选外部实现。

在这里插入图片描述

3.2.生成m4、c文件

创建好函数后,就可以根据函数导出m4、c文件了。
点击编译-》生成运行时系统文件
在这里插入图片描述

然后选择好文件夹、勾选M4、C,然后点击确定,就可以得到m4、c文件了。
在这里插入图片描述在这里插入图片描述

4.搭建编译环境,编译出动态库*.so

根据【Extension SDK】的指导,
在这里插入图片描述

4.1.将ExtensionSDK文件夹拷贝到板子的一个目录中。

我的这个文件夹是在【C:\Program Files\CODESYS 3.5.19.60\CODESYS\CODESYS Control SL Extension Package\4.10.0.0】里面,具体要看你的CodeSys的安装目录在哪里。
在这里插入图片描述假如你没有这个文件夹,那就需要先安装【CodeSys C Code Integration】及【Extension Pakage】插件包,安装步骤如下:
点击 工具–》CODESYS安装程序,然后在打开的CodeSys installer窗口中,选择CodeSys C Code Integration插件进行安装。安装完应该就有那个ExtensionSDK文件夹了。
在这里插入图片描述在这里插入图片描述

在这里插入图片描述

然后我将其拷贝到板子的一个目录下:

在这里插入图片描述

4.2.创建工程目录,且将前面生成的m4、c文件拷贝到这个工程目录下

我在板子的目录下创建的myPrj文件夹,然后将m4、c文件拷贝到了里面,如下图所示:
在这里插入图片描述

4.3.执行make

cd 到myPrj目录,然后执行

make -f ../ExtensionSDK/makefile newproject

然后就会在此文件夹中生成makefile文件
在这里插入图片描述

4.4.实现函数

打开c文件,对函数进行实现。
在这里插入图片描述

4.5.执行编译

在对C文件进行实现后,便可以进行编译了。

make all

此时会报错
在这里插入图片描述因为它默认使用的编译器是gcc,是c语言的编译器,而我们在C文件中用到了C++的东西string,所以就报错了。
因此我们还需要改一下make文件,将CC = gcc改成 CC = g++。假如你对make语法熟悉,也可以改一下其他的。
在这里插入图片描述再编译就没问题了。
在这里插入图片描述于是,便在out文件夹中得到了*.so文件。在这里插入图片描述

5.将*.so文件导入到库工程中

将在板子上编译得到的so文件,拷贝到我们的windows电脑上,然后在工程中导入。
在这里插入图片描述点击C实现库-》添加-》选择so文件。
在这里插入图片描述但是此时一般会报错:
在这里插入图片描述
库命名空间可以在这里看:
工程信息-》标题
在这里插入图片描述比如我这里是ZY1,那么,so文件就要改成以这个进行结尾:
在这里插入图片描述其他参数与安装后的对应:
在这里插入图片描述

好,没问题了,记得要选择正确的设备。
在这里插入图片描述
这样,函数的实现就有了。
在这里插入图片描述

6. 将库工程另存为编译库

在这里插入图片描述

然后就得到了我们适用于ARM64的库了
在这里插入图片描述

7.安装并使用编译好的库

我们新建一个标准工程、并且安装、调用刚才的库
在这里插入图片描述在这里插入图片描述在这里插入图片描述执行并查看一下函数有没按照预期运行:
我们的C函数实现的是:a、将传递进来的字符串加上"Hello World and ZY"后保存到返回值b中;b、对返回值a赋值17909;c、对返回值c赋值1.23456.

#include "CmpStd.h"
#include "CmpErrors.h"
#include "CmpItf.h"
#include "FileTransferDep.h"

#include <string>

void CDECL CDECL_EXT myfunction_cext(myfunction_cext_struct *p)
{
    using namespace cv;

    memcpy(p->b, "123456", 7);
    memcpy(p->c, "123456", 7);
    
    std::string aStr = p->a;
    aStr += "Hello World and ZY";

    p->MyFunction_cext.a = 17909;
    
    memcpy(p->MyFunction_cext.b, aStr.c_str(), aStr.length() + 1);
    
    p->MyFunction_cext.c = 1.23456;


    cv::Mat mat(480, 640, CV_8UC1);
    imwrite("abcd.bmp", mat);
    
    cv::Mat img = imread("1.png");
    imwrite("1_saved.png", img);
}

可以看到,与预期效果一致。

在这里插入图片描述而且在我们的板子上,可以看到刚才包含进来的库文件已经被上传到板子的特定文件夹中了:
在这里插入图片描述

8.结语

有了这个接口,只要我们对OpenCV、相机驱动库等进行封装,然后提供对应的操作函数给接口,就可以实现PLC的视觉检测功能。完美。

参考:
【CodeSys V3.5创建一个编译库】
【Extension SDK】

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐