无心飞扬 发表于 昨天 08:56

【Codesys-Runtime】-PLC下位机固件内容分析

在上篇文章中,给大家介绍了Codesys平台开发中的【下位机固件安装】过程,Codesys 按照 Linux 系统中的常规部署模式,把Runtime 的启动脚本、可执行文件、配置文件分别放在/opt, /etc/ 等目录下面。今天,我们对这些文件(俗称:固件)进行小小的整理,以方便以后进一步的开发、调试,然后再稍微认识一下固件中都有哪些文件,看一下其中重要的内容,作用是什么。
01 Runtime(运行时)是什么在软件开发中,很多不同的行业、领域中都会有【Runtime】这个叫法,就像【内核】这个名词一样,并不仅仅表示Linux操作系统中最核心的代码,在其它领域也经常提到内核这个名词。在PLC领域,或者说 Codesys 方案中,Runtime 的最简单理解就是:Runtime是运行在操作系统中的一个进程,在这个进程中,可以执行用户编写的程序(梯形图、ST语言、以及其它语言等)。当然了,上面这样的理解仍然有小问题:因为 Codesys 的下位机固件可以部署在很多平台上,包括没有操作系统的嵌入式平台。因为咱们目前主要是在 Linux 系统下来学习,所以这样来理解最简单。在基于 PC 的 PLC 方案之前的嵌入式平台上,各生产厂家 PLC 的上、下位机开发技术都是私有的,彼此各显神通、各不相同。但是在用户使用层面,为了便于理解和使用,很多 PLC 指令设计上比较类似。但是本质上来讲,各家的软件实现方式是各不相同的,如下图所示:上图中的嵌入式系统中,一般只运行一个程序,就是【周期扫描任务】,可以把它理解为是Runtime。【用户程序 App】是被【周期扫描任务】执行的一部分。在上图中,只有一个 App,这是大多数的情况。因为大部分的上位机软件不允许存在多个应用程序。从宏观上看,【周期扫描任务】处理内容主要分为 3 个阶段:到了基于 PC 的平台,PLC 的本质没有变,仍然是上图这三个阶段。不过在 Linux 操作系统中,除了 Runtime 所属的程序之外(就是 CodesysControl 进程),还会同时运行着多个其它程序,例如:各种系统服务程序、运控算法程序、视觉算法程序等等。因为在 PC 平台中,大部分都是有多个 CPU 核心,这样就可以真正的并行来执行很多个程序。在上图中,用户写的程序可以有很多个(App1,App2,AppN),这些程序是用户在上位机开发环境中(即:IDE)使用梯形图、ST等语言编写的。编译之后被下载到下位机中,然后被 Codesys Runtime 来加载到内存中执行。在 Codesys 的官网中,下面这段话描述了 Runtime 需要完成的任务(https://codesys.cn/show-812.html):

另外,英特尔发布了一篇文章,里面介绍了在工控领域的工控机产品情况,内容比较实用。这里贴一个封面和目录,具体的内容可以自行下载查阅。

综上:基于 Codesys 方案来学习 PLC 的下位机开发更加方便了,直接部署在一台普通的 Linux 系统中就可以了,甚至是一台虚拟机中(例如:我们使用的Ubuntu发行版)。Windows 系统中的情况有些特殊,Codesys 提供了一个实时系统,就是把其中的一个 CPU 核心进行隔离,专门用来执行 Runtime。在上面英特尔这篇文章中,对 Windows 系统中的一些解决方案也进行了一些介绍。另外,免费下载的 Codesys Runtime 固件只能连续执行两个小时,超时之后需要手动重新启动。
这里再说一个概念:软实时和硬实时。在普通的 PC 平台中,多个应用程序的并发执行,依赖于操作系统中的调度器,这个调度器在面向不同的目标时会有不同的调度算法。对于普通用户的需求来说,调度目标是:吞吐量最大化,追求不同用户、程序执行时间的公平性(Linux 是多用户系统)。但是在 PLC 中,最重要的目标是及时响应,因此普通的Linux操作系统(例如:Ubuntu)并不能满足这个目标,具体的原因包括:调度算法、自旋锁、信号量、中断处理等方面的影响。因此,一般的做法是在 Linux 内核中打补丁(例如:Preempt-RT或者Xenomai),这些是比较高级些的主题,了解一下即可。基于以上的原因,一般把基于工控机 + Linux 系统的这个方案称作软实时系统。
02 Codesys-Runtime 固件整理在上一篇文章中,安装好之后的 Runtime 固件分布在 Linux 系统的不同目录中。在开机启动的时候,/etc/init.d下面的几个脚本会自动被加载、执行:
[*]codemeter
[*]codesyscontrol
[*]codesysedge
我们以 codesyscontrol 脚本文件为例,打开其中的内容,可以看到核心的语句是:启动了 /opt/codesys/bin/codesyscontrol.bin 这个可执行文件。在本文中,Runtime 就约等于 codesyscontrol,在不同的上下文场景中称呼可能不同,但都是一个意思,没有严格区分。
但是,我们在学习、调试的时候,这些分散在不同目录中的文件,操作起来特别不方便,因此我把上面这 3 个程序中使用到的所有文件重新整理一下,全部汇总在 /opt/ 目录下。以 codesyscontrol 为例:所做的整理工作如下:
[*]目录名称改为:/opt/codesyscontrol/
[*]新建目录 config,并且把 /etc/codesyscontrol/目录下的三个文件移动过来;
[*]删除 /etc/init.d/ 下面的几个启动脚本文件;
[*]新增了两个 shell 脚本,方便启动和停止;
这里看一下最后两个脚本的内容:这样整理之后,启动或者关闭 codesyscontrol,只需要直接执行两个脚本文件即可。在实际的开发过程中,为了调试程序,可能会需要使用 gdb 工具来单步调试,例如:gdb ./bin/codesyscontrol.bin /opt/codesyscontrol/config/CODESYSControl.cfg另外一方面,把 codesyscontrol 所有的固件集中放在一个目录中,也方便了下位机部署。例如:新建了一个 Ubuntu 虚拟机,只需要把这个目录直接复制过去就相当于部署好了,操作更方便。
03 Codesys-Runtime 固件内容一览接下来,简单探索一下固件中的相关文件及其内容,可以分为 4 类:可执行程序,库文件,配置文件,用户程序。【可执行程序】也就是 bin 目录下的 codesyscontrol.bin 文件,这是 Codesys 官方提前编译好的(编译器针对:x86 Linux 环境),这是二进制文件,看不到有意义的内容,只能看一下该文件属性信息:如果你对 ELF 格式比较熟悉,可以使用 readelf 命令来看一下其中的内容,由于显示内容太多,这里就不贴图了。
【库文件】即 lib 目录下的文件,这是 Codesys 方案中下位机开发工作的重点文件。上图中几个 .so 文件都是标准的动态链接库,每一个库文件都用来完成一定的功能。例如:libCmpXMLParser.so 从字面上理解,就是对 XML 格式的文件进行解析处理。整个 Runtime 需要完成的功能有很多,每个功能的代码可以直接被编译在可执行文件 codesyscontrol 中,也可以编译成独立的动态链接库文件,然后放在 lib 目录下。codesyscontrol 进程在启动阶段会根据配置文件中提供的信息,到 lib 目录下查找指定的 .so 动态库文件,然后加载到内存中执行。在 Codesys 解决方案中,这里的每一个 .so 动态库文件,都称之为:组件。如果我们想编写自己的组件来完成特定的功能,就需要按照 Codesys 提供的组件模板来编写代码,然后编译成 .so 动态链接库文件,放到 lib 目录下,并且在配置文件中进行登记,这部分内容也是下位机开发的主要工作。
【配置文件】在上面的启动脚本中可以看到:在程序启动时,指定了配置文件的路径:/opt/codesyscontrol/CODESYSControl.cfg这个文件中又引用了另一个 .cfg 配置文件:/opt/codesyscontrol/CODESYSControl_User.cfg这里挑几个重要的配置信息来看一下:1. 引用其它配置文件
FileReference.1=/opt/codesyscontrol/config/CODESYSControl_User.cfg2. 配置日志文件的大小、个数
Logger.0.Name=codesyscontrol.log
;Logger.0.Filter=0x0000000F
Logger.0.Enable=1
Logger.0.MaxEntries=100000
Logger.0.MaxFileSize=1000000
Logger.0.MaxFiles=1
Logger.0.Backend.0.ClassId=0x00000104 3. 登记动态加载的组件(就是 /lib 目录下的动态链接库文件)
Component.1=CmpBACnet
Component.2=CmpBACnet2
Component.3=CmpPLCHandler
Component.4=CmpGwClient
Component.5=CmpXMLParser
Component.6=CmpGwClientCommDrvTcp
;Component.7=CmpGwClientCommDrvShm
;Component.8=SysPci
;Component.9=CmpHilscherCIFX4. 登记用户下载的程序
Bootproject.RetainMismatch.Init=1
Application.1=Application用户每次下载的用户程序都会登记在这里,在 Runtime 启动阶段会从配置文件中读取登记的所有 Application 程序(Application.1,Application.2,...),然后加载、执行。【用户程序】固件刚安装完成之后,是没有用户程序的。只有通过上位机 IDE 编写程序、编译程序、然后下载到下位机中之后,才能看到 .app 格式的文件,如下:.crc 文件是对 .app 文件的校验,在加载阶段会检查文件是否完整、有效。.app 文件是 Codessys 的私有格式,里面的内容比较复杂,基本上包括了我们在上位机中的所有操作,例如:编写的程序、设备组态、参数配置等等。具体的内容我也没有研究过,但是感觉是比较复杂的,这部分内容以后再说。以上就是固件中比较重要的一些文件,其它的一些内容以后遇到了再一起学习、讨论。




页: [1]
查看完整版本: 【Codesys-Runtime】-PLC下位机固件内容分析