# HG changeset patch # User Edouard Tisserant <edouard.tisserant@gmail.com> # Date 1717446295 -7200 # Node ID 792ae5ff01ca9fa924d1b7fb6cb7b9bf6255b644 # Parent fe7c5e8b20bbeac4f7a80a9c28284ca12e029b84 Tests: Add minimal C runtime test diff -r fe7c5e8b20bb -r 792ae5ff01ca tests/Makefile --- a/tests/Makefile Sat May 25 16:45:38 2024 +0200 +++ b/tests/Makefile Mon Jun 03 22:24:55 2024 +0200 @@ -71,7 +71,7 @@ # SOURCE and BUILD # -BUILT_PROJECTS=beremiz matiec open62541 Modbus +BUILT_PROJECTS=beremiz matiec open62541 Modbus erpc tar_opts=--absolute-names --exclude=.hg --exclude=.git --exclude=.*.pyc --exclude=.*.swp @@ -109,8 +109,11 @@ cd $(build_dir)/Modbus && \ make - -built_apps: $(build_dir)/matiec/iec2c $(build_dir)/beremiz/$(beremiz_checksum).sha1 $(build_dir)/open62541/build/bin/libopen62541.a $(build_dir)/Modbus/libmb.a +$(build_dir)/beremiz/C_runtime/beremiz_runtime: | $(build_dir)/erpc/$(erpc_checksum).sha1 + cd $(build_dir)/beremiz/C_runtime && \ + make + +built_apps: $(build_dir)/matiec/iec2c $(build_dir)/beremiz/$(beremiz_checksum).sha1 $(build_dir)/open62541/build/bin/libopen62541.a $(build_dir)/Modbus/libmb.a $(build_dir)/beremiz/C_runtime/beremiz_runtime touch $@ define log_command diff -r fe7c5e8b20bb -r 792ae5ff01ca tests/cli_tests/C_runtime.bash --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/cli_tests/C_runtime.bash Mon Jun 03 22:24:55 2024 +0200 @@ -0,0 +1,55 @@ +#!/bin/bash + +rm -f ./PLC_OK ./CLI_OK + +# Run C runtime +$BEREMIZPATH/C_runtime/beremiz_runtime -v -t tcp -p 61131 -h localhost > >( + echo "Start PLC stdout reader loop" + while read line; do + # Wait for server to print modified value + echo "PLC>> $line" + if [[ "$line" == "C runtime OK #3" ]]; then + echo "$line" + touch ./PLC_OK + fi + done + echo "End PLC stdout reader loop" +) & +PLC_PID=$! + +# Start PLC with C runtime test +setsid $BEREMIZPYTHONPATH $BEREMIZPATH/Beremiz_cli.py -k \ + --project-home $BEREMIZPATH/tests/projects/c_runtime build transfer run > >( +echo "Start CLI loop" +while read line; do + # Wait for CLI to output expected PLC log message on stdout + echo "CLI>> $line" + if [[ $line =~ .*C\ runtime\ log\ OK\ #3$ ]]; then + echo "$line" + touch ./CLI_OK + fi +done +echo "End CLI loop" +) & +CLI_PID=$! + +echo all subprocess started, start polling results +res=110 # default to ETIMEDOUT +c=45 +while ((c--)); do + if [[ -a ./PLC_OK && -a ./CLI_OK ]]; then + echo got results. + res=0 # OK success + break + else + echo waiting.... $c + sleep 1 + fi +done + +# Kill PLC and subprocess +echo will kill CLI:$CLI_PID and PLC:$PLC_PID +pkill -s $CLI_PID +kill $PLC_PID + +exit $res diff -r fe7c5e8b20bb -r 792ae5ff01ca tests/projects/c_runtime/beremiz.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/projects/c_runtime/beremiz.xml Mon Jun 03 22:24:55 2024 +0200 @@ -0,0 +1,5 @@ +<?xml version='1.0' encoding='utf-8'?> +<BeremizRoot URI_location="ERPC://localhost:61131"> + <TargetType/> + <Libraries Enable_Native_Library="true" Enable_Python_Library="false"/> +</BeremizRoot> diff -r fe7c5e8b20bb -r 792ae5ff01ca tests/projects/c_runtime/plc.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/projects/c_runtime/plc.xml Mon Jun 03 22:24:55 2024 +0200 @@ -0,0 +1,399 @@ +<?xml version='1.0' encoding='utf-8'?> +<project xmlns="http://www.plcopen.org/xml/tc6_0201" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xsi:schemaLocation="http://www.plcopen.org/xml/tc6_0201"> + <fileHeader companyName="Unknown" productName="Generic PLC" productVersion="1" creationDateTime="2013-01-29T14:01:00" contentDescription="This example shows logging functionality in Beremiz. Here are shown two ways of logging: - from IEC PLC program; - from python extension. "/> + <contentHeader name="Logging example" modificationDateTime="2024-06-03T22:15:34"> + <coordinateInfo> + <fbd> + <scaling x="0" y="0"/> + </fbd> + <ld> + <scaling x="0" y="0"/> + </ld> + <sfc> + <scaling x="0" y="0"/> + </sfc> + </coordinateInfo> + </contentHeader> + <types> + <dataTypes/> + <pous> + <pou name="C_Pragma" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="TRIG"> + <type> + <BOOL/> + </type> + </variable> + <variable name="IN"> + <type> + <INT/> + </type> + </variable> + </inputVars> + <localVars> + <variable name="rtrig"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[rtrig(CLK := TRIG); +IF rtrig.Q THEN +{{ + short inval = GetFbVar(IN); + printf("C runtime OK #%d\n", inval); + fflush(stdout); +}} +END_IF; +]]></xhtml:p> + </ST> + </body> + </pou> + <pou name="program0" pouType="program"> + <interface> + <localVars> + <variable name="beat"> + <type> + <BOOL/> + </type> + </variable> + <variable name="count"> + <type> + <INT/> + </type> + </variable> + <variable name="LOGGER0"> + <type> + <derived name="LOGGER"/> + </type> + </variable> + <variable name="lvl"> + <type> + <derived name="LOGLEVEL"/> + </type> + <initialValue> + <simpleValue value="INFO"/> + </initialValue> + </variable> + <variable name="Timer"> + <type> + <derived name="TOF"/> + </type> + </variable> + <variable name="C_Pragma0"> + <type> + <derived name="C_Pragma"/> + </type> + </variable> + </localVars> + </interface> + <body> + <FBD> + <inVariable localId="2" height="30" width="218" executionOrderId="0" negated="false"> + <position x="859" y="365"/> + <connectionPointOut> + <relPosition x="218" y="15"/> + </connectionPointOut> + <expression>'C runtime log OK #'</expression> + </inVariable> + <block localId="3" width="59" height="40" typeName="NOT" executionOrderId="0"> + <position x="241" y="287"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="14" formalParameter="Q"> + <position x="241" y="317"/> + <position x="197" y="317"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="59" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inOutVariable localId="4" height="30" width="60" executionOrderId="0" negatedOut="false" negatedIn="false"> + <position x="57" y="302"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="3" formalParameter="OUT"> + <position x="57" y="317"/> + <position x="37" y="317"/> + <position x="37" y="390"/> + <position x="314" y="390"/> + <position x="314" y="317"/> + <position x="300" y="317"/> + </connection> + </connectionPointIn> + <connectionPointOut> + <relPosition x="60" y="15"/> + </connectionPointOut> + <expression>beat</expression> + </inOutVariable> + <block localId="5" width="68" height="98" typeName="ADD" executionOrderId="0"> + <position x="463" y="403"/> + <inputVariables> + <variable formalParameter="IN1"> + <connectionPointIn> + <relPosition x="0" y="39"/> + <connection refLocalId="10" formalParameter="OUT"> + <position x="463" y="442"/> + <position x="455" y="442"/> + <position x="439" y="442"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN2"> + <connectionPointIn> + <relPosition x="0" y="78"/> + <connection refLocalId="6"> + <position x="463" y="481"/> + <position x="438" y="481"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="68" y="39"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inOutVariable localId="6" height="30" width="103" executionOrderId="0" negatedOut="false" negatedIn="false"> + <position x="335" y="466"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="5" formalParameter="OUT"> + <position x="335" y="481"/> + <position x="320" y="481"/> + <position x="320" y="518"/> + <position x="544" y="518"/> + <position x="544" y="442"/> + <position x="531" y="442"/> + </connection> + </connectionPointIn> + <connectionPointOut> + <relPosition x="103" y="15"/> + </connectionPointOut> + <expression>count</expression> + </inOutVariable> + <block localId="8" width="67" height="144" typeName="CONCAT" executionOrderId="0"> + <position x="1127" y="329"/> + <inputVariables> + <variable formalParameter="IN1"> + <connectionPointIn> + <relPosition x="0" y="51"/> + <connection refLocalId="2"> + <position x="1127" y="380"/> + <position x="1077" y="380"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN2"> + <connectionPointIn> + <relPosition x="0" y="113"/> + <connection refLocalId="9" formalParameter="OUT"> + <position x="1127" y="442"/> + <position x="1080" y="442"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="67" y="51"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="9" width="119" height="40" typeName="INT_TO_STRING" executionOrderId="0"> + <position x="961" y="412"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="5" formalParameter="OUT"> + <position x="961" y="442"/> + <position x="531" y="442"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="119" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="10" width="106" height="40" typeName="BOOL_TO_INT" executionOrderId="0"> + <position x="333" y="412"/> + <inputVariables> + <variable formalParameter="IN" edge="rising"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="3" formalParameter="OUT"> + <position x="333" y="442"/> + <position x="314" y="442"/> + <position x="314" y="317"/> + <position x="300" y="317"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="106" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="11" width="65" height="209" typeName="LOGGER" instanceName="LOGGER0" executionOrderId="0"> + <position x="1307" y="266"/> + <inputVariables> + <variable formalParameter="TRIG"> + <connectionPointIn> + <relPosition x="0" y="51"/> + <connection refLocalId="3" formalParameter="OUT"> + <position x="1307" y="317"/> + <position x="300" y="317"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="MSG"> + <connectionPointIn> + <relPosition x="0" y="114"/> + <connection refLocalId="8" formalParameter="OUT"> + <position x="1307" y="380"/> + <position x="1194" y="380"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="LEVEL"> + <connectionPointIn> + <relPosition x="0" y="177"/> + <connection refLocalId="12"> + <position x="1307" y="443"/> + <position x="1280" y="443"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables/> + </block> + <inVariable localId="12" height="30" width="79" executionOrderId="0" negated="false"> + <position x="1201" y="428"/> + <connectionPointOut> + <relPosition x="79" y="15"/> + </connectionPointOut> + <expression>lvl</expression> + </inVariable> + <block localId="14" typeName="TOF" instanceName="Timer" executionOrderId="0" height="98" width="47"> + <position x="150" y="278"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="39"/> + <connection refLocalId="4"> + <position x="150" y="317"/> + <position x="117" y="317"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="PT"> + <connectionPointIn> + <relPosition x="0" y="78"/> + <connection refLocalId="1"> + <position x="150" y="356"/> + <position x="117" y="356"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="Q"> + <connectionPointOut> + <relPosition x="47" y="39"/> + </connectionPointOut> + </variable> + <variable formalParameter="ET"> + <connectionPointOut> + <relPosition x="47" y="78"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inVariable localId="1" executionOrderId="0" height="30" width="61" negated="false"> + <position x="56" y="341"/> + <connectionPointOut> + <relPosition x="61" y="15"/> + </connectionPointOut> + <expression>T#1s</expression> + </inVariable> + <block localId="15" typeName="C_Pragma" instanceName="C_Pragma0" executionOrderId="0" width="74" height="60"> + <position x="594" y="336"/> + <inputVariables> + <variable formalParameter="TRIG"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="3" formalParameter="OUT"> + <position x="594" y="366"/> + <position x="447" y="366"/> + <position x="447" y="317"/> + <position x="300" y="317"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="50"/> + <connection refLocalId="5" formalParameter="OUT"> + <position x="594" y="386"/> + <position x="562" y="386"/> + <position x="562" y="442"/> + <position x="531" y="442"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables/> + </block> + </FBD> + </body> + </pou> + </pous> + </types> + <instances> + <configurations> + <configuration name="config"> + <resource name="resource1"> + <task name="task0" priority="0" interval="T#100ms"> + <pouInstance name="prg" typeName="program0"/> + </task> + </resource> + </configuration> + </configurations> + </instances> +</project>