4diac runtime Fort source code analysis (1)-execution environment of function block applications

4diac is an open source project of IEC61499, which consists of the development environment 4diac-ide, runtime forte, function block library (LIB) and system examples. This project has been continuously developed for more than ten years, but it is still only used for academic research. If it is to be applied to the industrial field, it needs further expansion and improvement. And it is mainly 4diac's runtime that Forte's expansion and improvement work is particularly important. If you plan to do secondary development work such as improvement and expansion. Reading and analyzing Forte's source code is an essential and difficult task. There are very few introductory articles on the forte software architecture on the Internet. We intend to begin to try to analyze and read the source code of forte, and introduce to readers one after another.

Overview

The latest version of Forte is version 1.12.0, which can be downloaded from the 4diac website

https://www.eclipse.org/4diac/en_dow.php

The forte software package is a program written in C++, which uses a large number of C++ classes to define the function blocks, models, communication interfaces, process interfaces, and operating environment of IEC61499. Analysis of Forte source code requires familiarity with many features of C++ programming.

The forte software includes the following main folders

Core

As the name suggests, this directory contains the core programs of forte.

 It also includes the following subdirectories

Communication function block cominfra

Input and output program IO

Datatypes

take

fmi

Utils

Module

Contains various extension modules, such as extended communication protocols http, modbus, MQTT, opc_ua, tsn, wagokbu, etc., as well as various specific process interfaces, such as the process interface programs of the Raspberry Pi PiFace and raspberry_sps interface board. The function block types written by users are also placed in the module directory.

Standard function block library stdfblib

Implementation of standard function library.

Adaptation program (arch)

 Adaptation programs with different operating systems

Core program

The most important thing in IEC61499 runtime is the execution of IEC61499 applications based on the event network. Study the core program of Forte from the context of how Forte implements IEC61499 applications

Implementation of Function Block Network (FBN)

When we analyze the source code of the IEC611499 runtime, perhaps the most urgent thing to understand is how the application of the function block network (FBN) is executed. There can be many implementation methods, the key is to realize the real-time (Realtime Execution) execution of the system. In the computer operating system, there are many methods for real-time scheduling. For example, we can call the IEC61499 function block to perform the conversion as the cyclic scanning method in PLC. Arrange a task for each resource. The task cyclically scans each function block to see if it is triggered by an input event. Once the function block is triggered by an input event, it executes the internal state diagram and algorithm, and outputs the corresponding output according to the execution result. Output events and data. Repeat the cycle until there is no new triggered function block in the system, then temporarily suspend the task. This method of blindly scanning all function blocks adds a lot of useless overhead.

Here we introduce forte's real-time execution function block algorithm using event chain.

Event Chain (EventChain)

Before introducing the event chain scheduling algorithm, first analyze the behavior of the IEC61499 function block network and some basic concepts.

ES-FB and ESK

The function block that sends events through the event connection is called: Event-Source Function Blocks (ESFB). The function block that does not generate further output events is called Event-Sink (ESK)

The time chain starts from an event generated by an ESFB and ends with an ESK.

responder-FB

The function block that can be triggered by the service (hardware) is called the response function block

 

Event Chain (EventChain)

With the concepts of ES-FB and ESK, let's define the event chain. The event chain is the FB execution chain from an ES-FB generating event to the ESK.

 

When an external event occurs, it will trigger the execution of ES-FB, then it generates an event, triggers the execution of FB1, and finally triggers the execution of ESK-FB, it no longer generates output events, so the EC execution is completed.

The basic behavior of the event chain (EC)

  -EC can have real-time restrictions (such as deadline)

-Different ECs can trigger the same FB

-EC can split and execute branches in parallel

-ECs with real-time restrictions can include branches without real-time restrictions

-The length of EC can be changed according to internal state and trigger FB input data

 

The following figure is an example of an event chain.

 

In the above figure, there are three ES-FBs, so there will be three independent event chains EC1, EC2 and EC3.

 

When implementing the IEC61499 operating environment, in order to realize the real-time operating environment, we encountered a major question: what kind of computing unit is a task (TASK)? This is the most basic concept in computer concurrent computing. We can regard a device as a task, a resource, a task, or even a function block. What kind of algorithm can be used to balance real-time and efficiency? This is an important issue that must be considered when designing a real-time operating environment.

 

We can observe by analyzing the execution of FB and the event notification flow that all execution paths originate from ES-FB, so it is a suitable way to assign a task to each ES-FB.

 

There are two important parts in the picture:

EEM-External Event Management

As the name implies, it responds to and handles external events. Such as requests from digital IO, timers and network

  ECX- Event Chain Execution Program

Scheduling Algorithm

When an FB receives an external event, when it is established, it must be registered in the EEM through management commands. In this case, the EEM can throw the incoming external event to the registered FB

After an external event is triggered, it will be executed through an ECX, and each ECX retains an EC-Execution-List (EC-EL). This list is a FIFO type queue that stores all FBs (references) that have events waiting to be executed at the event input, so they are waiting to be executed. A FB will be added to the end of EC-EL under the following circumstances

When an external event occurs, EEM adds ES_FB to EC-EL.

When an FB in the EC queue sends an output event. He will add receiving FB (receiver-FB) to EC-EL

 When EC-EL is empty, this task is suspended. This indicates that all the original external events and all subsequent events have been submitted, the triggered FB is executed, and all ECs have reached the ESK.

Implementation of the event chain execution algorithm in Fort

Equipment, containers and resources

We know that the device in IEC61499 contains one or more resources. If the class is not explicitly declared, the device has the characteristics of resources. Resource is a unit that can run independently. No interference between each other. This concept is similar to the container in software technology.

 

We also start from the structured hierarchical model model to study the relationship between C++ classes.

In Forte, the related classes are not completely defined in accordance with the device and resource architecture classes, but the resource class CResource class is derived from the container CResource class. In addition, the characteristics of the device are added to the CResource class, so CDevice is a derived class of CResource.

 A device class is a resource class with device characteristics. The relationship among the three categories of equipment, resources, and containers is as follows:

 

CFBContainer类(core/fbcontainer.h/CFBContainer)

The container has the following characteristics

-Get the name

-Get the function block in the container

-Add functional blocks to the container

-Get a list of function blocks

-Build function blocks

-Delete function block

-Get function block container

CResource class (core/resource.h/CResource)

As a derived class of CFBContainer, the CResource class adds the following characteristics

  • Execute management command (executeMGMCommand)
  • Get the device containing the resource (getDevice)
  • Event chain executor thread for obtaining resources (getResourceEventExecution)
  • Change actuator state
  • Input write value to the specified function block data (writeValue)
  • Get the monitor processor (getMonitorHandle)
  • Get lua engine
  • ExecuteEvent
  • Establish a connection (createConnection)
  •  

CDevice类(core/device.h/CDevice)

As a derived class of CResource, CDevice adds the following features:

-Get function block type ID

-Start the device (startDevice)

-Execute management command (executeMGMCommand)

-Change the actuator state (changeFBExecutionState)

-Get device execution program (getDeviceExecution)

-Get the clock (getTimer)

Event chain data structure

Event list item (conn.h/ CConnectionPoint class)

The event port of the recording function block has two important parameters

  • Pointer to function block (CFunctionBlock) *mFB
  • Port ID (TPortId) mportId

Event list (ecet.h/EventList)

  List of all event ports in the function block network.

 

 

Event chain execution thread (CEventChainExecutionThread) class

The thread that executes the event chain. It is referenced in the resource class and CDeviceExecution class. It maintains a data structure of an event list internally.

 

The event chain execution thread is a derived class of thread and has the following characteristics

-Start event chain (startEventChain)

-Add event entry (addEventEntry)

-Change execution status

-Execute thread, wait for completion (joinEventChainExecutionThread)

-Set Deadline

-Main loop mainRun

mainRun is the main loop, which reads EventList cyclically and calls the receiveInputEvent function of the function block class.

Device execution class (devexec.h/CDeviceExecution)

 

This is the class referenced in the class in CDevice, this class handles the processing of external events. It is equivalent to the EEM discussed earlier.

It maintains a data structure of external event information internally

  struct SEventHandlerElement {

        bool mOccured; //!<flag indicating that the external event has occurred between the last invocation.

        CExternalEventHandler *mHandler; //!< pointer to the external event handler instance.

};

SEventHandlerElement   mRegisteredEventHandlers[cg_unNumberOfHandlers];

All external event function blocks will register external event handlers. When an external event occurs, the external event is sent through the startNewEventChain(pointerToTargetFB) method of the CDeviceExecution class. Start a CEventChainExecutionThread thread in this method, and start running the event chain starting with this external event.

 

Classes related to external events

External events are hidden events inside forte and cannot be seen in 4DIAC IDE. It is usually used for communication between communication hardware and functional blocks. For example, the E_CYCLE function block will use such a function. It is registered to the CTimerHandle class to obtain external events periodically.

CEventSourceFB class

CExternalEventHandler class

  Handle incoming interrupts and similar external events. It is the base class of all Forte network and IO modules,

Receive external events

The function block that receives external events is not derived from the CFunctionBlock class, but from the CEventSourceFB class. CEventFB can respond to external events. Register the external event in the executeEvent method of accessing the external event class (for example, a timing trigger FORTE_SIBF_T_FF3):

void FORTE_SIBF_T_FF3::executeEvent(int pa_nEIID){

  switch(pa_nEIID){

       case cg_nExternalEventID:

              Q() = !Q();

         sendOutputEvent(scm_nEventEOID);

         break;

       case scm_nEventSTOPID:

         if(m_bActive){

              CTimerHandler::sm_poFORTETimer->unregisterTimedFB(this);

              m_bActive = false;

         }

         break;

       case scm_nEventSTARTID:

         if(!m_bActive){

              CTimerHandler::sm_poFORTETimer->registerTimedFB(&m_stTimeListEntry, DT());

              m_bActive = true;

         }

         break;

       default:

         break;

  }

}

Send external events

 If you design a communication/IO function block class that needs to send external events, your class needs to be derived from CExternalEventHandler. In the constructor, you need to register your class:

m_nExtEvHandID = sm_poDeviceExecution->registerExternalEventHandler(this);

Then, you can use the following methods to send external events

if (sm_poDeviceExecution->extEvHandlerIsAllowed(m_nExtEvHandID)) {

sm_poDeviceExecution->startNewEventChain(pointerToTargetFB);

}

Guess you like

Origin blog.csdn.net/yaojiawan/article/details/107215807