OpenPLC源码分析(三)具体实践

前面已经将OpenPLC runtime的源码分模块分解了,现打算分模块分阶段执行runtime的源码,以期对runtime的执行有更深的理解。

模拟的整体思路:

①本机Windows:安装OpenPLC Editor,编写源文件

②虚拟机Ubuntu:分模块执行OpenPLC runtime,实现针对.st文件的编译、链接

③本机和虚拟机之间通过Xftp传递数据,模拟下装过程

 

1、在虚拟机和本机之间利用Xftp传输文件

(1)在虚拟机上安装Xftp的有关文件

sudo apt install net-tools # 安装后才可以查看虚拟机的ip信息

sudo apt-get install openssh-server # 为了与本机交互,虚拟机要作为SSH服务器

(2)在本机安装Xfpt

网站https://www.xshell.com/zh/free-for-home-school/

(3)在虚拟机输入有关命令查看用户名以及网络ip

ifconfig # 查看ip

 whoami # 查看用户名

(4)在虚拟机设置SSH服务支持密码登录

sudo nano /etc/ssh/sshd_config # 打开SSH服务器的配置文件

在配置文件中确保以下行没有被注释掉

AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication yes
PermitEmptyPasswords no

然后重启SSH服务

sudo service ssh restart

(5)在本机利用SSH进行登录

(6)随后,即可成功利用Xftp在本机和虚拟机之间传输文件了

 2、在本机安装OpenPLC Editor

Editor的下载链接:https://autonomylogic.com/download-windows

(网站的下载速度很慢……)

3、利用OpenPLC Editor写第一个项目

具体参考:https://autonomylogic.com/docs/3-2-creating-your-first-project-on-openplc-editor/

【以下内容是以上网站的翻译】

这是一个关于开关的简单项目,需要以下硬件:

  • 一个安装了OpenPLC runtime的硬件设备
  • 两个开关
  • 一个LED

如果您正在这些工业电路板(UniPi、PiXtend 等)中运行 OpenPLC,您可能需要将 LED 升级为工业 24V 灯。它的工作原理是一样的。首先,像这样为电路布线:

重要注意事项:

  • +V 是设备的正电压电平。例如,Arduino 板通常为 +5V,Raspberry Pi 为 +3.3V,工业板为 +24V。
  • PB1 和 PB2 是按钮,R1 和 R2 是下拉电阻。从 1K 到 10K 的电阻都可以。如果您使用的是工业电路板或内部带有下拉电阻器的电路板,那么电路中很可能不需要 R1 或 R2。在这种情况下,您可以将 PB1 和 PB2 直接连接到 %IX0.0 和 %IX0.1。
  • 在 Raspberry Pi 电路板上,前两个输入(%IX0.0 和 %IX0.1)在硬件上是反相的。这可能会给您带来问题,因为这就像按钮被不断按下一样。您可以在 PLC 程序中使用负触点反转输入(如果您知道如何操作),或者使用其他输入,如 %IX0.2 和 %IX0.3。

 首先在 OpenPLC 编辑器上创建一个新项目。为此,只需点击文件 -> 新建。

此时会出现一个保存对话框,让您选择项目的存储位置。OpenPLC Editor 项目实际上是文件夹,而不是单个文件。如果文件夹中已经有文件,则无法将项目存储在其中。为项目创建一个新文件夹,打开该文件夹并选择其作为项目位置。

选定位置后,OpenPLC Editor 将使用默认设置和配置为您创建项目,并打开一个新对话框,要求您创建一个新的 POU。POU 是 Program Organization Unit(程序组织单元)的缩写,用于存储您在项目中编写的所有代码。您可以创建三种类型的 POU

  • 程序(Program) - 结合输入、输出、功能和功能块的应用代码。

  • 函数(Function) - 有返回值的可重用的用户代码。
  • 功能块(Function Block) - 可保留状态(实例)的可重用用户代码。

在本教程中,我们只创建一个Program POU。因此,只需填写程序名称,确保 POU 类型为 "程序",语言为 "LD"。此外,请注意程序名称不能包含空格或特殊字符。

当您创建一个新程序时,OpenPLC Editor 会自动为您创建一个配置、一个资源、一个任务和一个实例。这些项目告诉 OpenPLC 如何处理您的程序(例如,何时调用函数、如何循环运行等)。您可以双击左侧面板上的 Res0 来编辑这些项目。

 

主窗口顶部会显示一个全局变量输入框(允许你为程序创建全局变量)、一个任务窗口和一个实例窗口。点击任务窗口内的绿色加号,即可创建新任务。我们不会为本项目创建新任务。不过,您可能需要根据运行 OpenPLC 的硬件来更改任务的时间间隔。PLC 程序是循环运行的,这意味着它们从第一条指令开始,到最后一条指令结束,稍等片刻,然后从第一条指令到最后一条指令重新开始。任务间隔意味着程序循环调用的频率。默认值为 20ms,这意味着程序将每 20ms 执行一次。如果您需要更频繁地运行程序,可以随意调整时间。但请注意,如果您选择的循环时间很低(如 1ms),您的程序可能会消耗设备 100% 的 CPU,而设备仍可能无法正常运行您的程序。对于所有平台来说,安全的循环时间通常为 20 毫秒。有底层操作系统的平台(例如 Windows 和 Linux)响应速度较慢,周期时间较短时可能表现不佳。这是因为操作系统会根据操作系统内核的优先级干扰 PLC 周期调度。另一方面,像 Arduino 板这样的裸机平台在保持精确的周期时间方面非常出色,并且可以在较低的周期时间内保持较高的响应速度。

项目创建完成后,就可以开始绘制梯形逻辑图了。点击左侧面板上的程序名称,打开梯形图逻辑编辑器。屏幕的上半部分用于放置变量。中间部分用于绘制图表。因此,我们先添加几个变量。点击绿色加号,添加三个变量:

 

我们想通过这个程序实现的是:每当按下 PB1,LAMP 就会打开,并一直保持打开状态,直到按下 PB2。我们需要这样一个简单的梯形逻辑锁存电路:

 在OpenPLC中创建的过程为:

(1)首先,点击工具栏上的电源轨图标,添加左侧电源轨。

将左侧电源轨的引脚数量调整为 2(如果以后想在程序中添加更多的梯级,这是一个合理的数字)。添加另一个电源轨,针数为1,但这次要在属性中选择 "右电源轨"。将其放置在屏幕右侧。这样就可以为梯形图设置梯级了。

(2)现在可以开始添加梯形图元素了

单击工具栏上的联系人按钮或在空白编辑器窗口上单击右键并选择添加->接触点(contact),即可添加接触点。在出现的窗口中,在 "变量 "参数下选择 PB1,将新contact与变量 PB1 关联。

(3)重复该过程,再添加两个触点,一个与 PB2 相关,另一个与 LAMP 相关。对于 PB2 触点,选择 Negated 作为修改器。最后,点击工具栏上的线圈按钮或右键点击空白编辑器窗口并选择添加->线圈,添加一个线圈。将新线圈与 LAMP 变量相关联,并添加右侧电源轨以闭合电路。将元件摆放到位,使其看起来如图所示:

(4)最后一步是拖动所有元件的末端将其连接成一条线。将 PB1 和 LAMP 触点的左侧与左侧电源轨连接。将 PB1 的右侧与 PB2 连接,PB2 的右侧与 LAMP 线圈连接,LAMP 线圈的右侧与右电源轨连接。将 LAMP 触点的右侧与 PB2 的左侧连接,绘制并联 LAMP 触点电路。您的最终项目应与本教程的第一张梯形图相似。

该电路最初关闭了 LAMP 的电源。当您按下 PB1 时,哪怕只是一小会儿,电路也会打开 LAMP(前提是 PB2 也没有按下)。一旦 LAMP 打开,它就会绕过电路上的 PB1 按钮,即使在松开 PB1 后也会持续打开。这在梯形图逻辑中是一个很好的技巧,你实际上可以将输出作为触点来使用!现在,关闭 LAMP 的唯一方法是按下 PB2。由于 PB2 是一个负触点,一旦按下就会打开电路,从而关闭 LAMP。

现在您的项目已经创建完成,在将其上传到 OpenPLC Runtime 之前,是对其进行测试的好时机。单击工具栏上的 "Start PLC Simulation(开始 PLC 仿真)",即可模拟程序的行为。

这将打开一个新窗口,您可以看到程序的电子流。绿色的线路被激活,黑色的线路未被激活。右键单击触点或线圈,选择 "强制为真 "或 "强制为假",即可强制其激活或停用。尝试强制 PB1 为真,观察流向 LAMP 线圈的路径。然后将 PB1 强制为假,并验证 LAMP 是否仍然由于锁存电路而激活。

除了在图表上以图形方式查看电子流之外,您还可以在屏幕右侧的调试器面板上跟踪程序中每个变量的数据。点击左侧面板中每个变量前面的眼镜图标,即可在调试器面板中添加变量。此外,双击调试器面板上的变量,还可以看到显示变量当前值的实时图表。这在程序计步或操作数据时非常有用。

最后,在创建并测试完程序后,最后一步就是以 OpenPLC Runtime 可以理解的格式生成程序。为此,只需点击工具栏上的为 OpenPLC Runtime 生成程序,然后将 .st 文件保存到计算机上。该文件是以 OpenPLC Runtime 可以理解的语言编写的梯形图逻辑程序。随后,您可以按照 2.2 将程序上传到 OpenPLC Runtime 的说明,将此文件上传到 OpenPLC Runtime。

4、OpenPLC Editor的作用

在Editor编译之前,具有的文件为:

在Editor编译之后

新产生了两个文件夹

 其中build文件夹是.c文件, .o文件, .h文件,extra_files文件夹为空

停止PLC Simulation后,再产生OpenPLC runtime需要的文件,如下操作:

从而生成了一个.st文件(具体保存位置可以自己设置)

 5、在虚拟机上分模块测试OpenPLC runtime的编译过程

主要参考前面的博客:https://www.cnblogs.com/Daemon17/p/17946478

(1)在虚拟机上进行runtime的安装

在OpenPLC的文件夹执行以下命令,进行runtime的安装

sudo bash install.sh linux

发现会报以下错误:

但好像没有影响?因为我们不需要Libmodbus(后来发现的确有影响)

background_installer.sh中第161行,162行附近的代码为:

于是直接人为安装,如下所示:

cd ./utils/libmodbus_src

./autogen.sh

使用sudo也有些命令,于是直接运行autogen.sh中的命令

 autoreconf --install --symlink --force

成功安装!

提示说明:

同时,企图执行configure,发现文件里只有configure.ac文件。检索后发现应该利用autoconf工具,生成configure脚本,然后再执行。

于是在命令行中执行

autoconf --version

发现已经安装了autoconf

在当前目录(utils/libmodbus_src)中运行autoconf,发现以下结果

 这个提示说明宏AC_PROG_CC_STDC过时了,需要使用autoupdate命令进行更新

 在命令行输入:

autoupdate

结果如下:

 但依旧没有生成configure.sh文件……

 

安装完成后webserver文件夹中的文件如下图所示:

(2)分阶段执行OpenPLC-Webserver-scripts文件夹中的compile_program.sh文件代码进行编译

① 记录待编译文件名称

cd webserver # 进入OpenPLC-Webserver文件夹

 

cp ~/Desktop/hello.st st_files/hello.st # 将待编译的文件复制到st_files文件夹中

echo "/st_files/hello.st" > active_program # 将待编译的文件记录到active_program文件中,"/st_files/hello.st"是我待编译的文件位置

结果如下所示:

② 将ST文件编译成C文件

./st_optimizer st_files/hello.st st_files/hello.st # 利用可执行文件st_optimizer进行优化代码,由于优化代码主要是针对循环进行优化,所以这里没有改变

./iec2c -f -l -p -r -R -a ./st_files/hello.st # 编译成C文件

结果如下:

 然后webserver文件夹中的文件如下图所示:

 

 ③ 链接库文件,生成objective files

cd core # 进入core文件夹

如果接着直接输入

g++ -std=gnu++11 -I ./lib -c Config0.c -lasiodnp3 -lasiopal -lopendnp3 -lopenpal -w # 试图编译Config0.c

会报错,但实际上webserver文件夹中有Config0.c文件

 转为在命令行输入

g++ -std=gnu++11 -I ./lib -c ../Config0.c -lasiodnp3 -lasiopal -lopendnp3 -lopenpal -w

#具体解释如下: 

  • -std=gnu++11:指定使用C++11标准进行编译。
  • -I ./lib:指定头文件的搜索路径,其中./lib代表当前目录下的lib文件夹。
  • -c:指定只编译源文件,而不进行链接操作。
  • ../Config0.c:指定要编译的源文件的路径,../表示上一级目录。
  • -lasiodnp3 -lasiopal -lopendnp3 -lopenpal:指定要链接的库文件,这些库文件分别是asiodnp3asiopalopendnp3openpal
  • -w:禁用所有警告信息的输出。

没有报错,并且在当前目录下生成了一个Config0.o的目标文件

 在当前文件夹利用可执行文件glue_generator,将Config0.o的目标文件和多个cpp文件进行链接,并生成名为openplc的可执行文件

在命令行输入:

./glue_generator

发现报以下错误:

发现问题应该是因为LOCATED_VARIABLES.h不在当前文件夹所致。实际上LOCATED_VARIABLES.h在webserver文件夹(当前文件夹是core文件夹),如下图所示。

于是将LOCATED_VARIABLES.h复制到core文件夹中,在命令行中执行如下命令:

cp ../LOCATED_VARIABLES.h ./

再输入:

./glue_generator

 发现执行成功,结果如下:

会生成一个glueVars.cpp文件,如下:

再在命令行输入:

g++ -std=gnu++11 *.cpp *.o -o openplc -I ./lib -pthread -fpermissive `pkg-config --cflags --libs libmodbus` -lasiodnp3 -lasiopal -lopendnp3 -lopenpal -w $ETHERCAT_INC

发现报错:

 这个报错应该是,在安装runtime的时候,安装Libmodbus失败导致的。

posted @ 2024-01-17 23:33  碳酸钾K2CO3  阅读(289)  评论(0编辑  收藏  举报