diff --git a/clients/opal/.gitignore b/clients/opal/.gitignore new file mode 100644 index 000000000..bf0824e59 --- /dev/null +++ b/clients/opal/.gitignore @@ -0,0 +1 @@ +*.log \ No newline at end of file diff --git a/clients/opal/.project b/clients/opal/.project new file mode 100644 index 000000000..b6ea0fd2b --- /dev/null +++ b/clients/opal/.project @@ -0,0 +1,12 @@ + + + villas_udp + + + + + + + com.opalrt.rtlab.ui.rtlabnature + + diff --git a/clients/opal/.settings/com.opalrt.rtlab.ui.application.prefs b/clients/opal/.settings/com.opalrt.rtlab.ui.application.prefs new file mode 100644 index 000000000..908924866 --- /dev/null +++ b/clients/opal/.settings/com.opalrt.rtlab.ui.application.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +rtprojectfile=villas_udp.llp diff --git a/clients/opal/configurations/SyncExchangerRegistry/SyncExchangerRegistry.opal b/clients/opal/configurations/SyncExchangerRegistry/SyncExchangerRegistry.opal new file mode 100644 index 000000000..93697c8b8 --- /dev/null +++ b/clients/opal/configurations/SyncExchangerRegistry/SyncExchangerRegistry.opal @@ -0,0 +1,3 @@ +OPAL-1.0 Object +ListMap> { +} \ No newline at end of file diff --git a/clients/opal/configurations/aliases/Aliases.json b/clients/opal/configurations/aliases/Aliases.json new file mode 100644 index 000000000..059265889 --- /dev/null +++ b/clients/opal/configurations/aliases/Aliases.json @@ -0,0 +1,17 @@ +[ + {"version":2}, + { + "Opal::Simulation::SerializeableAliasList": + { + "copyOnWrite":0, + "locked":0, + "name":"D804207F-3D61-429A-9CBD-659A211EF103", + "versioned":0, + "aliasSets": + [ + ], + "history":"", + "parent":"/" + } + } +] \ No newline at end of file diff --git a/clients/opal/configurations/default.opal b/clients/opal/configurations/default.opal new file mode 100644 index 000000000..ead83b80a --- /dev/null +++ b/clients/opal/configurations/default.opal @@ -0,0 +1,13 @@ +OPAL-1.0 Object +Opal::Simulation::Configuration { + projectID=7B042784-8CF2-444A-92E3-8457E429E28A + copyOnWrite=0 + locked=0 + name=7B042784-8CF2-444A-92E3-8457E429E28A-default + versioned=0 + connectionSets { + } + syncExchangerRegistry=7B042784-8CF2-444A-92E3-8457E429E28A-default/SyncExchangerRegistry + history= + parent=/ +} \ No newline at end of file diff --git a/clients/opal/models/send_receive/.gitignore b/clients/opal/models/send_receive/.gitignore new file mode 100644 index 000000000..f7b9f592e --- /dev/null +++ b/clients/opal/models/send_receive/.gitignore @@ -0,0 +1,8 @@ +*.o +*.d +AsyncIP +Opcommon/ +report/ +*_sm_model/ +*_ss_model/ +*_sc_console.mdl diff --git a/clients/opal/models/send_receive/Makefile.mk b/clients/opal/models/send_receive/Makefile.mk new file mode 100644 index 000000000..3097e25c8 --- /dev/null +++ b/clients/opal/models/send_receive/Makefile.mk @@ -0,0 +1,79 @@ +# Makefile. +# +# @author Steffen Vogel +# @copyright 2017, Institute for Automation of Complex Power Systems, EONERC +# @license GNU General Public License (version 3) +# +# VILLASnode +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +################################################################################### + +TARGET = AsyncIP + +VPATH = src + +RTLAB_INTEL_COMPILER ?= 1 + +# Compiler selection +ifeq ($(RTLAB_INTEL_COMPILER),1) + CC = opicc + LD = opicpc +else + CC = gcc + LD = g++ + + INTEL_LIBS = -limf -lirc + INTEL_OBJS = compat.o +endif + +# Support for debugging symbols +ifeq ($(DEBUG),1) + CC_DEBUG_OPTS = -g -D_DEBUG + LD_DEBUG_OPTS = -g +else + CC_DEBUG_OPTS = -O + LD_DEBUG_OPTS = +endif + +TARGET_LIB = -lpthread -lm -ldl -lutil -lrt $(INTEL_LIBS) + +INCLUDES = -I. $(OPAL_INCPATH) -Iinclude +LIBPATH = -L. $(OPAL_LIBPATH) +CC_OPTS = -m32 -std=c99 -D_GNU_SOURCE -MMD +LD_OPTS = -m32 +OBJS = main.o msg.o utils.o socket.o $(INTEL_OBJS) + +ifneq ($(PROTOCOL),) + CC_OPTS += -DPROTOCOL=$(PROTOCOL) +endif + +ADDLIB = -lOpalCore -lOpalUtils +LIBS = -lOpalAsyncApiCore $(ADDLIB) $(TARGET_LIB) $(OPAL_LIBS) + +CFLAGS = -c $(CC_OPTS) $(CC_DEBUG_OPTS) $(INCLUDES) +LDFLAGS = $(LD_OPTS) $(LD_DEBUG_OPTS) $(LIBPATH) + +all: $(TARGET) + +install: $(TARGET) + install -m 0755 -D -t $(DESTDIR)$(PREFIX)/bin $(TARGET) + +clean: + rm -f $(OBJS) $(OBJS:%.o=%.d) $(TARGET) + +$(TARGET): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +-include $(wildcard *.d) \ No newline at end of file diff --git a/clients/opal/models/send_receive/include/config.h b/clients/opal/models/send_receive/include/config.h new file mode 100644 index 000000000..6a206a659 --- /dev/null +++ b/clients/opal/models/send_receive/include/config.h @@ -0,0 +1,41 @@ +/** Compile-time configuration. + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#define PROGNAME "VILLASnode-OPAL-UDP" +#define VERSION "0.6" + +#define MAX_VALUES 64 + +/* List of protocols */ +#define VILLAS 1 +#define GTNET_SKT 2 + +/* Default protocol */ +#ifndef PROTOCOL + #define PROTOCOL VILLAS +#endif + +#endif /* _CONFIG_H_ */ \ No newline at end of file diff --git a/clients/opal/models/send_receive/include/msg.h b/clients/opal/models/send_receive/include/msg.h new file mode 100644 index 000000000..594662b41 --- /dev/null +++ b/clients/opal/models/send_receive/include/msg.h @@ -0,0 +1,51 @@ +/** Message related functions + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#pragma once + +/* Forward declarations. */ +struct msg; + +/** Swaps the byte-order of the message. + * + * Message are always transmitted in network (big endian) byte order. + * + * @param m A pointer to the message + */ +void msg_hdr_ntoh(struct msg *m); + +void msg_hdr_hton(struct msg *m); + +void msg_ntoh(struct msg *m); + +void msg_hton(struct msg *m); + +/** Check the consistency of a message. + * + * The functions checks the header fields of a message. + * + * @param m A pointer to the message + * @retval 0 The message header is valid. + * @retval <0 The message header is invalid. + */ +int msg_verify(struct msg *m); \ No newline at end of file diff --git a/clients/opal/models/send_receive/include/msg_format.h b/clients/opal/models/send_receive/include/msg_format.h new file mode 100644 index 000000000..0a9ba3202 --- /dev/null +++ b/clients/opal/models/send_receive/include/msg_format.h @@ -0,0 +1,92 @@ +/** Message format + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#pragma once + +#include + +/** The current version number for the message format */ +#define MSG_VERSION 2 + +/** @todo Implement more message types */ +#define MSG_TYPE_DATA 0 /**< Message contains float values */ +#define MSG_TYPE_START 1 /**< Message marks the beginning of a new simulation case */ +#define MSG_TYPE_STOP 2 /**< Message marks the end of a simulation case */ + +/** The total size in bytes of a message */ +#define MSG_LEN(values) (sizeof(struct msg) + MSG_DATA_LEN(values)) + +/** The length of \p values values in bytes. */ +#define MSG_DATA_LEN(values) (sizeof(float) * (values)) + +/** The offset to the first data value in a message. */ +#define MSG_DATA_OFFSET(msg) ((char *) (msg) + offsetof(struct msg, data)) + +/** Initialize a message with default values */ +#define MSG_INIT(len, seq) (struct msg) {\ + .version = MSG_VERSION, \ + .type = MSG_TYPE_DATA, \ + .length = len, \ + .sequence = seq \ +} + +/** The timestamp of a message in struct timespec format */ +#define MSG_TS(msg) (struct timespec) { \ + .tv_sec = (msg)->ts.sec, \ + .tv_nsec = (msg)->ts.nsec \ +} + +/** This message format is used by all clients + * + * @diafile msg_format.dia + **/ +struct msg +{ +#if BYTE_ORDER == BIG_ENDIAN + unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ + unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ + unsigned rsvd1 : 2; /**< Reserved bits */ +#elif BYTE_ORDER == LITTLE_ENDIAN + unsigned rsvd1 : 2; /**< Reserved bits */ + unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ + unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ +#else + #error Invalid byte-order +#endif + + uint8_t rsvd2; /**< Reserved bits */ + uint16_t length; /**< The number of values in msg::data[]. */ + uint32_t sequence; /**< The sequence number is incremented by one for consecutive messages. */ + + /** A timestamp per message. */ + struct { + uint32_t sec; /**< Seconds since 1970-01-01 00:00:00 */ + uint32_t nsec; /**< Nanoseconds of the current second. */ + } ts; + + /** The message payload. */ + union { + float f; /**< Floating point values. */ + uint32_t i; /**< Integer values. */ + } data[]; +} __attribute__((packed)); \ No newline at end of file diff --git a/clients/opal/models/send_receive/include/socket.h b/clients/opal/models/send_receive/include/socket.h new file mode 100644 index 000000000..dd5c633be --- /dev/null +++ b/clients/opal/models/send_receive/include/socket.h @@ -0,0 +1,49 @@ +/** Helper functions for sockets. + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#ifndef _SOCKET_H_ +#define _SOCKET_H_ + +#include + +#define RT +#include "OpalGenAsyncParamCtrl.h" + +#define UDP_PROTOCOL 1 +#define TCP_PROTOCOL 2 + +struct socket { + struct sockaddr_in send_ad; /* Send address */ + struct sockaddr_in recv_ad; /* Receive address */ + int sd; /* socket descriptor */ +}; + +int socket_init(struct socket *s, Opal_GenAsyncParam_Ctrl IconCtrlStruct); + +int socket_send(struct socket *s, char *data, int len); + +int socket_recv(struct socket *s, char *data, int len, double timeout); + +int socket_close(struct socket *s, Opal_GenAsyncParam_Ctrl IconCtrlStruct); + +#endif /* _SOCKET_H_ */ diff --git a/clients/opal/models/send_receive/include/utils.h b/clients/opal/models/send_receive/include/utils.h new file mode 100644 index 000000000..acb8e100f --- /dev/null +++ b/clients/opal/models/send_receive/include/utils.h @@ -0,0 +1,31 @@ +/** Configure scheduler. + * + * @file + * @author Steffen Vogel + * @author Mathieu Dubé-Dallaire + * @copyright 2003, OPAL-RT Technologies inc + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#ifndef _UTILS_H_ +#define _UTILS_H_ + +int AssignProcToCpu0(void); + +#endif /* _UTILS_H_ */ diff --git a/clients/opal/models/send_receive/send_receive.llm b/clients/opal/models/send_receive/send_receive.llm new file mode 100644 index 000000000..0ab591505 --- /dev/null +++ b/clients/opal/models/send_receive/send_receive.llm @@ -0,0 +1,118 @@ +[EnvVars] +ABORT_COMPILE_WHEN_NO_BITSTREAM=0 +ACTION_AFTER_N_OVERRUNS=10 +ACTION_ON_OVERRUNS=0 +AcquisitionMemory=0,2500,24,100 +ActiveGroups=7/0/24/25/26/27/28/29/ +CACHEABLE_DMA_MEMORY_ACCESS=ON +COMM_RT=UDP/IP +ClockPeriodMode=Free-Clock +ClockPeriodTime=10 +DEBUG=0 +DETECT_OVERRUNS=ON +ENABLE_WATCHDOG=ON +EXT_CC_OPTS= +EXT_LD_OPTS= +EXT_LIB= +EXT_LIBPATH= +MODEL_PAUSE_TIME=0.000000 +MODEL_STOP_TIME=0.000000 +MONITORING=ON +MONITORING_BLOCK=OFF +MONITORING_DISPLAY=ALL +MSG_PRECISION_FACTOR=0 +MaxDynamicSignals=2/0/100/24/100/ +NB_STEP_WITHOUT_OVERRUNS=10 +OPAL_DEBUG=OFF +OP_MATLABR2014B=1 +OS_COMPILE_RELEASE=2.6.29.6-opalrt-5 +PRINT_LOG_LEVEL=DEBUG_RUN +RESET_IO_MISSING=ON +SYSNAME=linux +USER_INCS= +USER_SRCS= +WATCHDOG_TIMEOUT=5000 +[EnvVars_REDHAWK_DYN_1] +INTERNAL_IGN_SOURCE_FILE=sfun_gen_async_ctrl.c sfun_recv_async.c sfun_send_async.c +INTERNAL_LIBRARY2=-lOpalAsyncApiR2014b +INTERNAL_LIBRARY3=-lOpalAsyncApiCore +[ExtraGetFilesComp_1_RT_LAB] +AsyncIP=Binary|Async_Proc +[ExtraPutFilesComp] +Makefile.mk=Ascii +include\config.h=Ascii +include\msg.h=Ascii +include\msg_format.h=Ascii +include\socket.h=Ascii +include\utils.h=Ascii +src\compat.c=Ascii +src\main.c=Ascii +src\msg.c=Ascii +src\socket.c=Ascii +src\utils.c=Ascii +[ExtraPutFilesComp_1_RT_LAB] +C:\OPAL-RT\RT-LAB\v11.0.8.13\common\lib\redhawk\libOpalAsyncApiCore.a=Binary|Other +[ExtraPutFilesLoad_1_RT_LAB] +.\send_receive_sm_model\OpREDHAWKtarget\AsyncIP=Binary|Async_Proc +[General] +ATT_CHECKSUM1=2360032266 +ATT_CHECKSUM2=1041833943 +ATT_CHECKSUM3=842695092 +ATT_CHECKSUM4=2435976698 +ATT_CREATED_BY=jwu +ATT_CREATED_ON=Thu Apr 15 08:21:54 1999 +ATT_ENABLE_PTA=OFF +ATT_HANDLE_CONSOLE=ON +ATT_LAST_SAVED_BY=svo +ATT_LAST_SAVED_ON=Tue Jun 27 10:20:09 2017 +ATT_REFERENCE_MDL_PATHS= +ATT_REVISION=1.453 +AutoRetrieveFiles=ON +AutoRetrieveRtlab=ON +CompilerVersion=AUTOMATIC +DESCRIPTION= +DinamoFlag=OFF +FILENAME=C:\Users\svo\workspace\villas\node\clients\opal\villas_udp\models\send_receive\send_receive.mdl +FORCE_RECOMPILE=0 +IMPORTED_GLOBAL_VARIABLES=1 +LastCompileRtlabVersion=v11.0.8.13 +LastMatlabUsed=27 +LastMatlabUsedName=v8.4 +MATLAB_USED_IN_MODEL=21 +Name=send_receive +PETALINUX_LAST_COMPILE_VERSION= +PRINT_CYCLE=OFF +PostBuildCmd= +PreBuildCmd= +QNX_LAST_COMPILE_VERSION= +RH64_LAST_COMPILE_VERSION= +RH_LAST_COMPILE_VERSION=2.6.29.6-opalrt-5 +ReportFileId= +RetrieveBuildTree=ON +RetrieveRootDir= +SimulationMode=2 +TLC=Automatic +TMF=Automatic +TRANSFERFILE_AT_LOAD=ON +TargetCompileCmd=/usr/bin/make -f /usr/opalrt/common/bin/opalmodelmk +TargetPlatform=REDHAWK +TimeFactor=1.000000000000000 +TimeStep=0.000050000000000 +sc_consoleTimeStep=-1.000000000000000 +sm_modelTimeStep=0.000049999998737 +sm_send_receiveTimeStep=0.000049999998737 +[General_1] +TargetPreCompileCmd=make -f /usr/opalrt/common/bin/opalmodelmk +[NodeMapping] +sm_model=ACS_OPAL_RT +sm_model_CORE_ASSIGNATION=1 +sm_model_CPU=-1 +sm_model_DEBUG=OFF +sm_model_XHP_ENABLE=FALSE +sm_send_receive=ACS_OPAL_RT +sm_send_receive_CORE_ASSIGNATION=1 +sm_send_receive_CPU=-1 +sm_send_receive_DEBUG=OFF +sm_send_receive_XHP_ENABLE=FALSE +[UserEnvVars] +PROTOCOL=VILLAS diff --git a/clients/opal/models/send_receive/send_receive.mdl b/clients/opal/models/send_receive/send_receive.mdl new file mode 100644 index 000000000..bb4c0fcd1 --- /dev/null +++ b/clients/opal/models/send_receive/send_receive.mdl @@ -0,0 +1,1703 @@ +# $Revision: 1.1 $ +Model { + Name "send_receive" + Version 8.4 + MdlSubVersion 0 + SavedCharacterEncoding "windows-1252" + GraphicalInterface { + NumRootInports 0 + NumRootOutports 0 + ParameterArgumentNames "" + ComputedModelVersion "1.453" + NumModelReferences 0 + NumTestPointedSignals 0 + } + ScopeRefreshTime 0.035000 + OverrideScopeRefreshTime on + DisableAllScopes off + DataTypeOverride "UseLocalSettings" + DataTypeOverrideAppliesTo "AllNumericTypes" + MinMaxOverflowLogging "UseLocalSettings" + MinMaxOverflowArchiveMode "Overwrite" + FPTRunName "Run 1" + MaxMDLFileLineLength 120 + Object { + $PropName "BdWindowsInfo" + $ObjectID 1 + $ClassName "Simulink.BDWindowsInfo" + Object { + $PropName "WindowsInfo" + $ObjectID 2 + $ClassName "Simulink.WindowInfo" + IsActive [1] + Location [16.0, 52.0, 1452.0, 912.0] + Object { + $PropName "ModelBrowserInfo" + $ObjectID 3 + $ClassName "Simulink.ModelBrowserInfo" + Visible [0] + DockPosition "Left" + Width [50] + Height [50] + Filter [9] + } + Object { + $PropName "ExplorerBarInfo" + $ObjectID 4 + $ClassName "Simulink.ExplorerBarInfo" + Visible [1] + } + Object { + $PropName "EditorsInfo" + $ObjectID 5 + $ClassName "Simulink.EditorInfo" + IsActive [1] + ViewObjType "SimulinkSubsys" + LoadSaveID "13" + Extents [1402.0, 738.0] + ZoomFactor [1.6] + Offset [94.375, -58.375] + } + } + } + Created "Thu Apr 15 08:21:54 1999" + Creator "jwu" + UpdateHistory "UpdateHistoryNever" + ModifiedByFormat "%" + LastModifiedBy "svo" + ModifiedDateFormat "%" + LastModifiedDate "Tue Jun 27 10:20:09 2017" + RTWModifiedTimeStamp 420459603 + ModelVersionFormat "1.%" + ConfigurationManager "none" + SampleTimeColors off + SampleTimeAnnotations off + LibraryLinkDisplay "none" + WideLines off + ShowLineDimensions on + ShowPortDataTypes off + ShowDesignRanges off + ShowLoopsOnError on + IgnoreBidirectionalLines off + ShowStorageClass off + ShowTestPointIcons on + ShowSignalResolutionIcons on + ShowViewerIcons on + SortedOrder off + ExecutionContextIcon off + ShowLinearizationAnnotations on + ShowMarkup on + BlockNameDataTip off + BlockParametersDataTip on + BlockDescriptionStringDataTip off + ToolBar on + StatusBar on + BrowserShowLibraryLinks off + BrowserLookUnderMasks off + SimulationMode "normal" + PauseTimes "5" + NumberOfSteps 1 + SnapshotBufferSize 10 + SnapshotInterval 10 + NumberOfLastSnapshots 0 + LinearizationMsg "none" + Profile off + ParamWorkspaceSource "MATLABWorkspace" + AccelSystemTargetFile "accel.tlc" + AccelTemplateMakefile "accel_default_tmf" + AccelMakeCommand "make_rtw" + TryForcingSFcnDF off + Object { + $PropName "DataLoggingOverride" + $ObjectID 6 + $ClassName "Simulink.SimulationData.ModelLoggingInfo" + model_ "send_receive" + Array { + Type "Cell" + Dimension 1 + Cell "send_receive" + PropName "logAsSpecifiedByModels_" + } + Array { + Type "Cell" + Dimension 1 + Cell "" + PropName "logAsSpecifiedByModelsSSIDs_" + } + } + RecordCoverage off + CovPath "/" + CovSaveName "covdata" + CovMetricSettings "dw" + CovNameIncrementing off + CovHtmlReporting on + CovForceBlockReductionOff on + CovEnableCumulative on + covSaveCumulativeToWorkspaceVar on + CovSaveSingleToWorkspaceVar on + CovCumulativeVarName "covCumulativeData" + CovCumulativeReport off + CovReportOnPause on + CovModelRefEnable "Off" + CovExternalEMLEnable off + CovSFcnEnable off + CovBoundaryAbsTol 0.000010 + CovBoundaryRelTol 0.010000 + CovUseTimeInterval off + CovStartTime 0 + CovStopTime 0 + ExtModeBatchMode off + ExtModeEnableFloating on + ExtModeTrigType "manual" + ExtModeTrigMode "oneshot" + ExtModeTrigPort "1" + ExtModeTrigElement "any" + ExtModeTrigDuration 1000 + ExtModeTrigDurationFloating "auto" + ExtModeTrigHoldOff 0 + ExtModeTrigDelay 0 + ExtModeTrigDirection "rising" + ExtModeTrigLevel 0 + ExtModeArchiveMode "off" + ExtModeAutoIncOneShot off + ExtModeIncDirWhenArm off + ExtModeAddSuffixToVar off + ExtModeWriteAllDataToWs off + ExtModeArmWhenConnect off + ExtModeSkipDownloadWhenConnect off + ExtModeLogAll on + ExtModeAutoUpdateStatusClock on + BufferReuse off + ShowModelReferenceBlockVersion off + ShowModelReferenceBlockIO off + Array { + Type "Handle" + Dimension 1 + Simulink.ConfigSet { + $ObjectID 7 + Version "1.14.3" + Array { + Type "Handle" + Dimension 8 + Simulink.SolverCC { + $ObjectID 8 + Version "1.14.3" + StartTime "0.0" + StopTime "inf" + AbsTol "1e-6" + FixedStep "0.00005" + InitialStep "auto" + MaxNumMinSteps "-1" + MaxOrder 5 + ZcThreshold "auto" + ConsecutiveZCsStepRelTol "10*128*eps" + MaxConsecutiveZCs "1000" + ExtrapolationOrder 4 + NumberNewtonIterations 1 + MaxStep "0.01" + MinStep "auto" + MaxConsecutiveMinStep "1" + RelTol "1e-3" + SolverMode "SingleTasking" + EnableConcurrentExecution off + ConcurrentTasks off + Solver "ode4" + SolverName "ode4" + SolverJacobianMethodControl "auto" + ShapePreserveControl "DisableAll" + ZeroCrossControl "UseLocalSettings" + ZeroCrossAlgorithm "Nonadaptive" + AlgebraicLoopSolver "TrustRegion" + SolverResetMethod "Fast" + PositivePriorityOrder off + AutoInsertRateTranBlk off + SampleTimeConstraint "Unconstrained" + InsertRTBMode "Whenever possible" + } + Simulink.DataIOCC { + $ObjectID 9 + Version "1.14.3" + Decimation "1" + ExternalInput "[]" + FinalStateName "xFinal" + InitialState "[]" + LimitDataPoints off + MaxDataPoints "1000" + LoadExternalInput off + LoadInitialState off + SaveFinalState off + SaveCompleteFinalSimState off + SaveFormat "Array" + SignalLoggingSaveFormat "ModelDataLogs" + SaveOutput off + SaveState off + SignalLogging on + DSMLogging on + InspectSignalLogs off + VisualizeSimOutput on + SaveTime off + ReturnWorkspaceOutputs off + StateSaveName "xout" + TimeSaveName "tout" + OutputSaveName "yout" + SignalLoggingName "sigsOut" + DSMLoggingName "dsmout" + OutputOption "RefineOutputTimes" + OutputTimes "[]" + ReturnWorkspaceOutputsName "out" + Refine "1" + } + Simulink.OptimizationCC { + $ObjectID 10 + Version "1.14.3" + Array { + Type "Cell" + Dimension 4 + Cell "ZeroExternalMemoryAtStartup" + Cell "ZeroInternalMemoryAtStartup" + Cell "NoFixptDivByZeroProtection" + Cell "OptimizeModelRefInitCode" + PropName "DisabledProps" + } + BlockReduction on + BooleanDataType off + ConditionallyExecuteInputs on + InlineParams off + UseDivisionForNetSlopeComputation "Off" + UseFloatMulNetSlope off + DefaultUnderspecifiedDataType "double" + UseSpecifiedMinMax off + InlineInvariantSignals off + OptimizeBlockIOStorage off + BufferReuse off + EnhancedBackFolding off + CachingGlobalReferences off + GlobalBufferReuse off + StrengthReduction off + ExpressionFolding off + BooleansAsBitfields off + BitfieldContainerType "uint_T" + EnableMemcpy on + MemcpyThreshold 64 + PassReuseOutputArgsAs "Structure reference" + ExpressionDepthLimit 2147483647 + FoldNonRolledExpr off + LocalBlockOutputs off + RollThreshold 5 + SystemCodeInlineAuto off + StateBitsets off + DataBitsets off + ActiveStateOutputEnumStorageType "Native Integer" + UseTempVars off + ZeroExternalMemoryAtStartup on + ZeroInternalMemoryAtStartup on + InitFltsAndDblsToZero on + NoFixptDivByZeroProtection off + EfficientFloat2IntCast off + EfficientMapNaN2IntZero on + OptimizeModelRefInitCode off + LifeSpan "inf" + MaxStackSize "Inherit from target" + BufferReusableBoundary on + SimCompilerOptimization "Off" + AccelVerboseBuild off + ParallelExecutionInRapidAccelerator on + } + Simulink.DebuggingCC { + $ObjectID 11 + Version "1.14.3" + RTPrefix "error" + ConsistencyChecking "none" + ArrayBoundsChecking "none" + SignalInfNanChecking "none" + SignalRangeChecking "none" + ReadBeforeWriteMsg "UseLocalSettings" + WriteAfterWriteMsg "UseLocalSettings" + WriteAfterReadMsg "UseLocalSettings" + AlgebraicLoopMsg "warning" + ArtificialAlgebraicLoopMsg "warning" + SaveWithDisabledLinksMsg "warning" + SaveWithParameterizedLinksMsg "none" + CheckSSInitialOutputMsg on + UnderspecifiedInitializationDetection "Classic" + MergeDetectMultiDrivingBlocksExec "none" + CheckExecutionContextPreStartOutputMsg off + CheckExecutionContextRuntimeOutputMsg off + SignalResolutionControl "TryResolveAllWithWarning" + BlockPriorityViolationMsg "warning" + MinStepSizeMsg "warning" + TimeAdjustmentMsg "none" + MaxConsecutiveZCsMsg "error" + MaskedZcDiagnostic "warning" + IgnoredZcDiagnostic "warning" + SolverPrmCheckMsg "none" + InheritedTsInSrcMsg "none" + DiscreteInheritContinuousMsg "warning" + MultiTaskDSMMsg "warning" + MultiTaskCondExecSysMsg "none" + MultiTaskRateTransMsg "error" + SingleTaskRateTransMsg "none" + TasksWithSamePriorityMsg "warning" + SigSpecEnsureSampleTimeMsg "warning" + CheckMatrixSingularityMsg "none" + IntegerOverflowMsg "warning" + Int32ToFloatConvMsg "warning" + ParameterDowncastMsg "error" + ParameterOverflowMsg "error" + ParameterUnderflowMsg "none" + ParameterPrecisionLossMsg "warning" + ParameterTunabilityLossMsg "warning" + FixptConstUnderflowMsg "none" + FixptConstOverflowMsg "none" + FixptConstPrecisionLossMsg "none" + UnderSpecifiedDataTypeMsg "none" + UnnecessaryDatatypeConvMsg "none" + VectorMatrixConversionMsg "none" + InvalidFcnCallConnMsg "error" + FcnCallInpInsideContextMsg "UseLocalSettings" + SignalLabelMismatchMsg "none" + UnconnectedInputMsg "warning" + UnconnectedOutputMsg "warning" + UnconnectedLineMsg "warning" + SFcnCompatibilityMsg "none" + FrameProcessingCompatibilityMsg "warning" + UniqueDataStoreMsg "none" + BusObjectLabelMismatch "warning" + RootOutportRequireBusObject "warning" + AssertControl "UseLocalSettings" + EnableOverflowDetection off + ModelReferenceIOMsg "none" + ModelReferenceMultiInstanceNormalModeStructChecksumCheck "error" + ModelReferenceVersionMismatchMessage "none" + ModelReferenceIOMismatchMessage "none" + ModelReferenceCSMismatchMessage "none" + UnknownTsInhSupMsg "warning" + ModelReferenceDataLoggingMessage "warning" + ModelReferenceSymbolNameMessage "warning" + ModelReferenceExtraNoncontSigs "error" + StateNameClashWarn "warning" + SimStateInterfaceChecksumMismatchMsg "warning" + SimStateOlderReleaseMsg "error" + InitInArrayFormatMsg "warning" + StrictBusMsg "None" + BusNameAdapt "WarnAndRepair" + NonBusSignalsTreatedAsBus "none" + LoggingUnavailableSignals "error" + BlockIODiagnostic "none" + SFUnusedDataAndEventsDiag "warning" + SFUnexpectedBacktrackingDiag "warning" + SFInvalidInputDataAccessInChartInitDiag "warning" + SFNoUnconditionalDefaultTransitionDiag "warning" + SFTransitionOutsideNaturalParentDiag "warning" + SFUnconditionalTransitionShadowingDiag "warning" + SFUndirectedBroadcastEventsDiag "warning" + SFTransitionActionBeforeConditionDiag "warning" + IntegerSaturationMsg "warning" + } + Simulink.HardwareCC { + $ObjectID 12 + Version "1.14.3" + ProdBitPerChar 8 + ProdBitPerShort 16 + ProdBitPerInt 32 + ProdBitPerLong 32 + ProdBitPerLongLong 64 + ProdBitPerFloat 32 + ProdBitPerDouble 64 + ProdBitPerPointer 32 + ProdLargestAtomicInteger "Char" + ProdLargestAtomicFloat "None" + ProdIntDivRoundTo "Undefined" + ProdEndianess "Unspecified" + ProdWordSize 32 + ProdShiftRightIntArith on + ProdLongLongMode off + ProdHWDeviceType "32-bit Generic" + TargetBitPerChar 8 + TargetBitPerShort 16 + TargetBitPerInt 32 + TargetBitPerLong 32 + TargetBitPerLongLong 64 + TargetBitPerFloat 32 + TargetBitPerDouble 64 + TargetBitPerPointer 32 + TargetLargestAtomicInteger "Char" + TargetLargestAtomicFloat "None" + TargetShiftRightIntArith on + TargetLongLongMode off + TargetIntDivRoundTo "Undefined" + TargetEndianess "Unspecified" + TargetWordSize 32 + TargetTypeEmulationWarnSuppressLevel 0 + TargetPreprocMaxBitsSint 32 + TargetPreprocMaxBitsUint 32 + TargetHWDeviceType "Specified" + TargetUnknown on + ProdEqTarget on + } + Simulink.ModelReferenceCC { + $ObjectID 13 + Version "1.14.3" + UpdateModelReferenceTargets "IfOutOfDateOrStructuralChange" + CheckModelReferenceTargetMessage "error" + EnableParallelModelReferenceBuilds off + ParallelModelReferenceErrorOnInvalidPool on + ParallelModelReferenceMATLABWorkerInit "None" + ModelReferenceNumInstancesAllowed "Multi" + PropagateVarSize "Infer from blocks in model" + ModelReferencePassRootInputsByReference on + ModelReferenceMinAlgLoopOccurrences off + PropagateSignalLabelsOutOfModel off + SupportModelReferenceSimTargetCustomCode off + } + Simulink.SFSimCC { + $ObjectID 14 + Version "1.14.3" + SFSimEnableDebug on + SFSimOverflowDetection on + SFSimEcho on + SimBlas on + SimCtrlC on + SimExtrinsic on + SimIntegrity on + SimUseLocalCustomCode off + SimParseCustomCode on + SimBuildMode "sf_incremental_build" + SimGenImportedTypeDefs off + } + Simulink.RTWCC { + $BackupClass "Simulink.RTWCC" + $ObjectID 15 + Version "1.14.3" + Array { + Type "Cell" + Dimension 1 + Cell "IncludeHyperlinkInReport" + PropName "DisabledProps" + } + SystemTargetFile "grt.tlc" + TLCOptions "" + GenCodeOnly off + MakeCommand "make_rtw" + GenerateMakefile on + PackageGeneratedCodeAndArtifacts off + PackageName "" + TemplateMakefile "grt_default_tmf" + PostCodeGenCommand "" + Description "" + GenerateReport off + SaveLog off + RTWVerbose on + RetainRTWFile off + ProfileTLC off + TLCDebug off + TLCCoverage off + TLCAssert off + ProcessScriptMode "Default" + ConfigurationMode "Optimized" + ProcessScript "" + ConfigurationScript "" + ConfigAtBuild off + RTWUseLocalCustomCode off + RTWUseSimCustomCode off + CustomSourceCode "" + CustomHeaderCode "" + CustomInclude "" + CustomSource "" + CustomLibrary "" + CustomInitializer "" + CustomTerminator "" + Toolchain "Automatically locate an installed toolchain" + BuildConfiguration "Faster Builds" + IncludeHyperlinkInReport off + LaunchReport off + PortableWordSizes off + CreateSILPILBlock "None" + CodeExecutionProfiling off + CodeExecutionProfileVariable "executionProfile" + CodeProfilingSaveOptions "SummaryOnly" + CodeProfilingInstrumentation off + SILDebugging off + TargetLang "C" + IncludeBusHierarchyInRTWFileBlockHierarchyMap off + IncludeERTFirstTime on + GenerateTraceInfo off + GenerateTraceReport off + GenerateTraceReportSl off + GenerateTraceReportSf off + GenerateTraceReportEml off + GenerateCodeInfo off + GenerateWebview off + GenerateCodeMetricsReport off + GenerateCodeReplacementReport off + RTWCompilerOptimization "Off" + RTWCustomCompilerOptimizations "" + CheckMdlBeforeBuild "Off" + CustomRebuildMode "OnUpdate" + DataInitializer "" + SharedConstantsCachingThreshold 1024 + Array { + Type "Handle" + Dimension 2 + Simulink.CodeAppCC { + $ObjectID 16 + Version "1.14.3" + Array { + Type "Cell" + Dimension 16 + Cell "IgnoreCustomStorageClasses" + Cell "InsertBlockDesc" + Cell "SFDataObjDesc" + Cell "SimulinkDataObjDesc" + Cell "DefineNamingRule" + Cell "SignalNamingRule" + Cell "ParamNamingRule" + Cell "InlinedPrmAccess" + Cell "CustomSymbolStr" + Cell "CustomSymbolStrGlobalVar" + Cell "CustomSymbolStrType" + Cell "CustomSymbolStrField" + Cell "CustomSymbolStrFcn" + Cell "CustomSymbolStrBlkIO" + Cell "CustomSymbolStrTmpVar" + Cell "CustomSymbolStrMacro" + PropName "DisabledProps" + } + ForceParamTrailComments off + GenerateComments on + CommentStyle "Auto" + IgnoreCustomStorageClasses off + IgnoreTestpoints off + IncHierarchyInIds off + MaxIdLength 31 + PreserveName off + PreserveNameWithParent off + ShowEliminatedStatement on + OperatorAnnotations off + IncAutoGenComments off + SimulinkDataObjDesc off + SFDataObjDesc off + MATLABFcnDesc off + IncDataTypeInIds off + MangleLength 1 + CustomSymbolStrGlobalVar "$R$N$M" + CustomSymbolStrType "$N$R$M_T" + CustomSymbolStrField "$N$M" + CustomSymbolStrFcn "$R$N$M$F" + CustomSymbolStrFcnArg "rt$I$N$M" + CustomSymbolStrBlkIO "rtb_$N$M" + CustomSymbolStrTmpVar "$N$M" + CustomSymbolStrMacro "$R$N$M" + CustomSymbolStrUtil "$N$C" + DefineNamingRule "None" + ParamNamingRule "None" + SignalNamingRule "None" + InsertBlockDesc off + InsertPolySpaceComments off + SimulinkBlockComments on + MATLABSourceComments off + EnableCustomComments off + InternalIdentifier "Shortened" + InlinedPrmAccess "Literals" + ReqsInCode off + UseSimReservedNames off + } + Simulink.GRTTargetCC { + $BackupClass "Simulink.TargetCC" + $ObjectID 17 + Version "1.14.3" + Array { + Type "Cell" + Dimension 11 + Cell "IncludeMdlTerminateFcn" + Cell "GenerateAllocFcn" + Cell "SuppressErrorStatus" + Cell "ERTCustomFileBanners" + Cell "GenerateSampleERTMain" + Cell "GenerateTestInterfaces" + Cell "SupportContinuousTime" + Cell "PurelyIntegerCode" + Cell "SupportNonInlinedSFcns" + Cell "SupportComplex" + Cell "SupportAbsoluteTime" + PropName "DisabledProps" + } + TargetFcnLib "ansi_tfl_tmw.mat" + TargetLibSuffix "" + TargetPreCompLibLocation "" + GenFloatMathFcnCalls "NOT IN USE" + TargetLangStandard "C89/C90 (ANSI)" + CodeReplacementLibrary "None" + UtilityFuncGeneration "Auto" + ERTMultiwordTypeDef "System defined" + ERTMultiwordLength 256 + MultiwordLength 2048 + GenerateFullHeader on + GenerateSampleERTMain off + GenerateTestInterfaces off + ModelReferenceCompliant on + ParMdlRefBuildCompliant on + CompOptLevelCompliant on + ConcurrentExecutionCompliant on + IncludeMdlTerminateFcn on + GeneratePreprocessorConditionals "Disable all" + CombineOutputUpdateFcns off + CombineSignalStateStructs off + SuppressErrorStatus off + ERTFirstTimeCompliant off + IncludeFileDelimiter "Auto" + ERTCustomFileBanners off + SupportAbsoluteTime on + LogVarNameModifier "rt_" + MatFileLogging on + MultiInstanceERTCode off + CodeInterfacePackaging "Nonreusable function" + SupportNonFinite on + SupportComplex on + PurelyIntegerCode off + SupportContinuousTime on + SupportNonInlinedSFcns on + SupportVariableSizeSignals off + EnableShiftOperators on + ParenthesesLevel "Nominal" + CastingMode "Nominal" + MATLABClassNameForMDSCustomization "Simulink.SoftwareTarget.GRTCustomization" + ModelStepFunctionPrototypeControlCompliant off + CPPClassGenCompliant on + AutosarCompliant off + GRTInterface on + GenerateAllocFcn off + GenerateSharedConstants on + UseMalloc off + ExtMode off + ExtModeStaticAlloc off + ExtModeTesting off + ExtModeStaticAllocSize 1000000 + ExtModeTransport 0 + ExtModeMexFile "ext_comm" + ExtModeIntrfLevel "Level1" + RTWCAPISignals off + RTWCAPIParams off + RTWCAPIStates off + RTWCAPIRootIO off + GenerateASAP2 off + MultiInstanceErrorCode "Error" + } + PropName "Components" + } + } + PropName "Components" + } + Name "Configuration" + CurrentDlgPage "Solver" + ConfigPrmDlgPosition [ 326, 217, 1222, 885 ] + } + PropName "ConfigurationSets" + } + Simulink.ConfigSet { + $PropName "ActiveConfigurationSet" + $ObjectID 7 + } + Object { + $PropName "DataTransfer" + $ObjectID 18 + $ClassName "Simulink.GlobalDataTransfer" + DefaultTransitionBetweenSyncTasks "Ensure deterministic transfer (maximum delay)" + DefaultTransitionBetweenAsyncTasks "Ensure data integrity only" + DefaultTransitionBetweenContTasks "Ensure deterministic transfer (minimum delay)" + DefaultExtrapolationMethodBetweenContTasks "None" + AutoInsertRateTranBlk [0] + } + ExplicitPartitioning off + BlockDefaults { + ForegroundColor "black" + BackgroundColor "white" + DropShadow off + NamePlacement "normal" + FontName "Helvetica" + FontSize 10 + FontWeight "normal" + FontAngle "normal" + ShowName on + BlockRotation 0 + BlockMirror off + } + AnnotationDefaults { + HorizontalAlignment "center" + VerticalAlignment "middle" + ForegroundColor "black" + BackgroundColor "white" + DropShadow off + FontName "Helvetica" + FontSize 10 + FontWeight "normal" + FontAngle "normal" + UseDisplayTextAsClickCallback off + } + LineDefaults { + FontName "Helvetica" + FontSize 9 + FontWeight "normal" + FontAngle "normal" + } + MaskDefaults { + SelfModifiable "off" + IconFrame "on" + IconOpaque "on" + RunInitForIconRedraw "off" + IconRotate "none" + PortRotate "default" + IconUnits "autoscale" + } + MaskParameterDefaults { + Evaluate "on" + Tunable "on" + NeverSave "off" + Internal "off" + ReadOnly "off" + Enabled "on" + Visible "on" + ToolTip "on" + } + BlockParameterDefaults { + Block { + BlockType Constant + Value "1" + VectorParams1D on + SamplingMode "Sample based" + OutMin "[]" + OutMax "[]" + OutDataTypeStr "Inherit: Inherit from 'Constant value'" + LockScale off + SampleTime "inf" + FramePeriod "inf" + PreserveConstantTs off + } + Block { + BlockType Demux + Outputs "4" + DisplayOption "none" + BusSelectionMode off + } + Block { + BlockType DiscretePulseGenerator + PulseType "Sample based" + TimeSource "Use simulation time" + Amplitude "1" + Period "2" + PulseWidth "1" + PhaseDelay "0" + SampleTime "1" + VectorParams1D on + } + Block { + BlockType Display + Format "short" + Decimation "10" + Floating off + Lockdown off + SampleTime "-1" + } + Block { + BlockType Inport + Port "1" + OutputFunctionCall off + OutMin "[]" + OutMax "[]" + OutDataTypeStr "Inherit: auto" + LockScale off + BusOutputAsStruct off + PortDimensions "-1" + VarSizeSig "Inherit" + SampleTime "-1" + SignalType "auto" + SamplingMode "auto" + LatchByDelayingOutsideSignal off + LatchInputForFeedbackSignals off + Interpolate on + } + Block { + BlockType Mux + Inputs "4" + DisplayOption "none" + UseBusObject off + BusObject "BusObject" + NonVirtualBus off + } + Block { + BlockType Outport + Port "1" + OutMin "[]" + OutMax "[]" + OutDataTypeStr "Inherit: auto" + LockScale off + BusOutputAsStruct off + PortDimensions "-1" + VarSizeSig "Inherit" + SampleTime "-1" + SignalType "auto" + SamplingMode "auto" + SourceOfInitialOutputValue "Dialog" + OutputWhenDisabled "held" + InitialOutput "[]" + } + Block { + BlockType Scope + ModelBased off + TickLabels "OneTimeTick" + ZoomMode "on" + Grid "on" + TimeRange "auto" + YMin "-5" + YMax "5" + SaveToWorkspace off + SaveName "ScopeData" + DataFormat "Array" + LimitDataPoints on + MaxDataPoints "5000" + Decimation "1" + SampleInput off + SampleTime "-1" + } + Block { + BlockType SignalSpecification + OutMin "[]" + OutMax "[]" + OutDataTypeStr "Inherit: auto" + LockScale off + BusOutputAsStruct off + Dimensions "-1" + VarSizeSig "Inherit" + SampleTime "-1" + SignalType "auto" + SamplingMode "auto" + } + Block { + BlockType SubSystem + ShowPortLabels "FromPortIcon" + Permissions "ReadWrite" + PermitHierarchicalResolution "All" + TreatAsAtomicUnit off + MinAlgLoopOccurrences off + PropExecContextOutsideSubsystem off + CheckFcnCallInpInsideContextMsg off + SystemSampleTime "-1" + RTWSystemCode "Auto" + RTWFcnNameOpts "Auto" + RTWFileNameOpts "Auto" + FunctionInterfaceSpec "void_void" + FunctionWithSeparateData off + RTWMemSecFuncInitTerm "Inherit from model" + RTWMemSecFuncExecute "Inherit from model" + RTWMemSecDataConstants "Inherit from model" + RTWMemSecDataInternal "Inherit from model" + RTWMemSecDataParameters "Inherit from model" + SimViewingDevice off + DataTypeOverride "UseLocalSettings" + DataTypeOverrideAppliesTo "AllNumericTypes" + MinMaxOverflowLogging "UseLocalSettings" + Opaque off + MaskHideContents off + SFBlockType "NONE" + Variant off + GeneratePreprocessorConditionals off + ContentPreviewEnabled off + } + Block { + BlockType Sum + IconShape "rectangular" + Inputs "++" + CollapseMode "All dimensions" + CollapseDim "1" + InputSameDT on + AccumDataTypeStr "Inherit: Inherit via internal rule" + OutMin "[]" + OutMax "[]" + OutDataTypeStr "Inherit: Same as first input" + LockScale off + RndMeth "Floor" + SaturateOnIntegerOverflow on + SampleTime "-1" + } + } + System { + Name "send_receive" + Location [346, 78, 1222, 990] + Open off + ModelBrowserVisibility off + ModelBrowserWidth 247 + ScreenColor "white" + PaperOrientation "landscape" + PaperPositionMode "auto" + PaperType "usletter" + PaperUnits "inches" + TiledPaperMargins [0.500000, 0.500000, 0.500000, 0.500000] + TiledPageScale 1 + ShowPageBoundaries off + ZoomFactor "100" + ReportName "simulink-default.rpt" + SIDHighWatermark "46" + Block { + BlockType SubSystem + Name "sc_console" + SID "3" + Ports [3] + Position [410, 98, 610, 192] + ZOrder -1 + BackgroundColor "lightBlue" + RequestExecContextInheritance off + System { + Name "sc_console" + Location [16, 52, 1715, 1151] + Open off + ModelBrowserVisibility off + ModelBrowserWidth 200 + ScreenColor "white" + PaperOrientation "landscape" + PaperPositionMode "auto" + PaperType "A4" + PaperUnits "centimeters" + TiledPaperMargins [1.270000, 1.270000, 1.270000, 1.270000] + TiledPageScale 1 + ShowPageBoundaries off + ZoomFactor "206" + Block { + BlockType Inport + Name "data recv" + SID "4" + Position [140, 168, 170, 182] + ZOrder -1 + BackgroundColor "yellow" + IconDisplay "Port number" + } + Block { + BlockType Inport + Name "errors_status" + SID "5" + Position [140, 128, 170, 142] + ZOrder -2 + BackgroundColor "yellow" + Port "2" + IconDisplay "Port number" + } + Block { + BlockType Inport + Name "data send" + SID "29" + Position [140, 208, 170, 222] + ZOrder -3 + BackgroundColor "yellow" + Port "3" + IconDisplay "Port number" + } + Block { + BlockType Demux + Name "Demux" + SID "6" + Ports [1, 2] + Position [285, 116, 290, 154] + ZOrder -4 + BackgroundColor "black" + ShowName off + Outputs "[2 1]" + } + Block { + BlockType Demux + Name "Demux1" + SID "32" + Ports [1, 5] + Position [375, 211, 380, 299] + ZOrder -5 + ShowName off + Outputs "5" + DisplayOption "bar" + } + Block { + BlockType Demux + Name "Demux2" + SID "39" + Ports [1, 5] + Position [375, 306, 380, 394] + ZOrder -6 + ShowName off + Outputs "5" + DisplayOption "bar" + } + Block { + BlockType Mux + Name "Mux" + SID "34" + Ports [2, 1] + Position [465, 236, 470, 274] + ZOrder -7 + ShowName off + Inputs "2" + DisplayOption "bar" + } + Block { + BlockType Reference + Name "OpComm" + SID "9" + Ports [3, 3] + Position [225, 135, 255, 215] + ZOrder -8 + LibraryVersion "1.471" + SourceBlock "rtlab/OpComm" + SourceType "RT-LAB OpComm" + ContentPreviewEnabled off + nbport "3" + groupe_acq "1" + subsys_rate "0" + st "0" + Synchronization on + Interpolation on + Threshold "1.0" + Missed_Data off + Offset off + Sim_Time off + Samples off + dynSigOut off + from_console "0" + warning_done off + writeOpCommFile off + } + Block { + BlockType Sum + Name "Subtract" + SID "42" + Ports [2, 1] + Position [510, 312, 540, 343] + ZOrder -31 + Inputs "+-" + InputSameDT off + OutDataTypeStr "Inherit: Inherit via internal rule" + SaturateOnIntegerOverflow off + } + Block { + BlockType Display + Name "errors" + SID "10" + Ports [1] + Position [385, 72, 455, 118] + ZOrder -32 + BackgroundColor "yellow" + FontName "Arial" + FontSize 8 + Decimation "1" + } + Block { + BlockType Scope + Name "message 1" + SID "40" + Ports [1] + Position [590, 159, 620, 191] + ZOrder -33 + BackgroundColor "yellow" + Floating off + Location [826, 517, 1334, 952] + Open off + NumInputPorts "1" + List { + ListType AxesTitles + axes1 "%" + } + List { + ListType ScopeGraphics + FigureColor "[0.5 0.5 0.5]" + AxesColor "[0 0 0]" + AxesTickColor "[1 1 1]" + LineColors "[1 1 0;1 0 1;0 1 1;1 0 0;0 1 0;0 0 1]" + LineStyles "-|-|-|-|-|-" + LineWidths "[0.5 0.5 0.5 0.5 0.5 0.5]" + MarkerStyles "none|none|none|none|none|none" + } + ShowLegends off + YMin "-1.75" + YMax "4" + SaveName "ScopeData1" + DataFormat "StructureWithTime" + SampleTime "0" + ScrollMode off + } + Block { + BlockType Scope + Name "message 2" + SID "33" + Ports [1] + Position [590, 239, 620, 271] + ZOrder -34 + BackgroundColor "yellow" + Floating off + Location [826, 517, 1334, 952] + Open off + NumInputPorts "1" + List { + ListType AxesTitles + axes1 "%" + } + List { + ListType ScopeGraphics + FigureColor "[0.5 0.5 0.5]" + AxesColor "[0 0 0]" + AxesTickColor "[1 1 1]" + LineColors "[1 1 0;1 0 1;0 1 1;1 0 0;0 1 0;0 0 1]" + LineStyles "-|-|-|-|-|-" + LineWidths "[0.5 0.5 0.5 0.5 0.5 0.5]" + MarkerStyles "none|none|none|none|none|none" + } + ShowLegends off + YMin "-1.75" + YMax "4" + DataFormat "StructureWithTime" + SampleTime "0" + ScrollMode off + } + Block { + BlockType Scope + Name "message 3" + SID "41" + Ports [1] + Position [590, 389, 620, 421] + ZOrder -35 + BackgroundColor "yellow" + Floating off + Location [826, 517, 1334, 952] + Open off + NumInputPorts "1" + List { + ListType AxesTitles + axes1 "%" + } + List { + ListType ScopeGraphics + FigureColor "[0.5 0.5 0.5]" + AxesColor "[0 0 0]" + AxesTickColor "[1 1 1]" + LineColors "[1 1 0;1 0 1;0 1 1;1 0 0;0 1 0;0 0 1]" + LineStyles "-|-|-|-|-|-" + LineWidths "[0.5 0.5 0.5 0.5 0.5 0.5]" + MarkerStyles "none|none|none|none|none|none" + } + ShowLegends off + YMin "-1.75" + YMax "4" + SaveName "ScopeData2" + DataFormat "StructureWithTime" + SampleTime "0" + ScrollMode off + } + Block { + BlockType Scope + Name "message 4" + SID "43" + Ports [1] + Position [590, 314, 620, 346] + ZOrder -36 + BackgroundColor "yellow" + Floating off + Location [826, 517, 1334, 952] + Open off + NumInputPorts "1" + List { + ListType AxesTitles + axes1 "%" + } + List { + ListType ScopeGraphics + FigureColor "[0.5 0.5 0.5]" + AxesColor "[0 0 0]" + AxesTickColor "[1 1 1]" + LineColors "[1 1 0;1 0 1;0 1 1;1 0 0;0 1 0;0 0 1]" + LineStyles "-|-|-|-|-|-" + LineWidths "[0.5 0.5 0.5 0.5 0.5 0.5]" + MarkerStyles "none|none|none|none|none|none" + } + ShowLegends off + YMin "-1.75" + YMax "4" + SaveName "ScopeData3" + DataFormat "StructureWithTime" + SampleTime "0" + ScrollMode off + } + Block { + BlockType Display + Name "reception status" + SID "12" + Ports [1] + Position [390, 133, 450, 157] + ZOrder -37 + BackgroundColor "yellow" + FontName "Arial" + FontSize 8 + Decimation "1" + } + Line { + ZOrder 1 + SrcBlock "errors_status" + SrcPort 1 + Points [25, 0; 0, 15] + DstBlock "OpComm" + DstPort 1 + } + Line { + ZOrder 2 + SrcBlock "OpComm" + SrcPort 2 + Points [45, 0; 0, 80] + Branch { + ZOrder 3 + Labels [1, 0] + DstBlock "Demux1" + DstPort 1 + } + Branch { + ZOrder 4 + Points [0, -80] + DstBlock "message 1" + DstPort 1 + } + } + Line { + ZOrder 5 + SrcBlock "data recv" + SrcPort 1 + DstBlock "OpComm" + DstPort 2 + } + Line { + ZOrder 6 + SrcBlock "OpComm" + SrcPort 1 + Points [10, 0] + DstBlock "Demux" + DstPort 1 + } + Line { + ZOrder 7 + SrcBlock "Demux" + SrcPort 1 + Points [45, 0; 0, -30] + DstBlock "errors" + DstPort 1 + } + Line { + ZOrder 8 + SrcBlock "Demux" + SrcPort 2 + DstBlock "reception status" + DstPort 1 + } + Line { + ZOrder 9 + Labels [0, 0] + SrcBlock "Mux" + SrcPort 1 + DstBlock "message 2" + DstPort 1 + } + Line { + ZOrder 10 + SrcBlock "data send" + SrcPort 1 + Points [25, 0; 0, -15] + DstBlock "OpComm" + DstPort 3 + } + Line { + ZOrder 11 + SrcBlock "OpComm" + SrcPort 3 + Points [25, 0; 0, 150] + Branch { + ZOrder 12 + Points [0, 0] + DstBlock "Demux2" + DstPort 1 + } + Branch { + ZOrder 13 + Points [0, 55] + DstBlock "message 3" + DstPort 1 + } + } + Line { + ZOrder 14 + SrcBlock "Subtract" + SrcPort 1 + DstBlock "message 4" + DstPort 1 + } + Line { + ZOrder 15 + SrcBlock "Demux2" + SrcPort 5 + Points [40, 0; 0, -45] + Branch { + ZOrder 16 + Points [0, -70] + DstBlock "Mux" + DstPort 2 + } + Branch { + ZOrder 17 + DstBlock "Subtract" + DstPort 2 + } + } + Line { + ZOrder 18 + SrcBlock "Demux1" + SrcPort 5 + Points [25, 0] + Branch { + ZOrder 19 + Points [0, -40] + DstBlock "Mux" + DstPort 1 + } + Branch { + ZOrder 20 + Points [0, 35] + DstBlock "Subtract" + DstPort 1 + } + } + Annotation { + SID "45" + Name "Simple analysis of round trip time" + Position [273, 42, 535, 61] + InternalMargins [0, 0, 0, 0] + FixedHeight off + FixedWidth off + ZOrder -1 + FontName "Verdana" + FontSize 14 + FontWeight "bold" + } + } + } + Block { + BlockType SubSystem + Name "sm_model" + SID "13" + Ports [0, 3] + Position [55, 97, 235, 193] + ZOrder -2 + BackgroundColor "lightBlue" + RequestExecContextInheritance off + System { + Name "sm_model" + Location [16, 52, 1468, 964] + Open on + ModelBrowserVisibility off + ModelBrowserWidth 200 + ScreenColor "white" + PaperOrientation "landscape" + PaperPositionMode "auto" + PaperType "A4" + PaperUnits "centimeters" + TiledPaperMargins [1.270000, 1.270000, 1.270000, 1.270000] + TiledPageScale 1 + ShowPageBoundaries off + ZoomFactor "160" + Block { + BlockType Mux + Name "Mux" + SID "16" + Ports [3, 1] + Position [870, 140, 875, 190] + ZOrder -1 + ShowName off + Inputs "3" + DisplayOption "bar" + } + Block { + BlockType Mux + Name "Mux1" + SID "17" + Ports [2, 1] + Position [290, 209, 295, 271] + ZOrder -2 + BackgroundColor "yellow" + ShowName off + Inputs "2" + DisplayOption "bar" + } + Block { + BlockType Reference + Name "OpIPSocketCtrl1" + SID "18" + Ports [] + Position [110, 92, 239, 153] + ZOrder -3 + LibraryVersion "1.10" + SourceBlock "rtio_generic_ip/OpIPSocketCtrl" + SourceType "OpAsyncIPCtrl" + ctl_id "1" + proto "UDP/IP" + ip_addr_remote "134.130.169.32" + ip_port_remote "12000" + ip_port_local "12000" + ip_addr_mcast "0.0.0.0" + exe_name "AsyncIP" + } + Block { + BlockType DiscretePulseGenerator + Name "Pulse\nGenerator" + SID "44" + Ports [0, 1] + Position [190, 238, 240, 272] + ZOrder -13 + BackgroundColor "yellow" + PulseType "Time based" + Amplitude "5" + Period "0.1" + PulseWidth "30" + } + Block { + BlockType Constant + Name "constants" + SID "19" + Position [180, 216, 250, 234] + ZOrder -14 + BackgroundColor "yellow" + NamePlacement "alternate" + Value "[1 2 3 4]" + } + Block { + BlockType DiscretePulseGenerator + Name "data ready 2 kHz" + SID "20" + Ports [0, 1] + Position [290, 131, 335, 149] + ZOrder -15 + NamePlacement "alternate" + Period "10" + SampleTime "0.00005" + } + Block { + BlockType Reference + Name "receive message 1" + SID "21" + Ports [1, 3] + Position [625, 159, 800, 201] + ZOrder -16 + LibraryVersion "1.471" + SourceBlock "rtlab/Communication/Asynchronous/OpAsyncRecv" + SourceType "OpAsyncRecv" + ContentPreviewEnabled off + ctl_id "1" + recv_id "1" + enable_param off + fp1 "1" + fp2 "2" + fp3 "3" + fp4 "4" + fp5 "5" + sp1 "string1" + sp2 "string2" + sp3 "string3" + sp4 "string4" + sp5 "string5" + } + Block { + BlockType Reference + Name "send message 1" + SID "22" + Ports [2, 1] + Position [375, 129, 545, 171] + ZOrder -17 + LibraryVersion "1.471" + SourceBlock "rtlab/Communication/Asynchronous/OpAsyncSend" + SourceType "OpAsyncSend" + ContentPreviewEnabled off + ctl_id "1" + send_id "1" + mode "DONT_NEED_REPLY" + enable_param off + fp1 "1" + fp2 "2" + fp3 "3" + fp4 "4" + fp5 "5" + sp1 "string1" + sp2 "string2" + sp3 "string3" + sp4 "string4" + sp5 "string5" + } + Block { + BlockType SignalSpecification + Name "set width" + SID "23" + Position [830, 187, 855, 203] + ZOrder -18 + Dimensions "5" + } + Block { + BlockType Constant + Name "timeout" + SID "25" + Position [580, 173, 610, 187] + ZOrder -19 + Value "2" + } + Block { + BlockType Outport + Name "data recv" + SID "26" + Position [915, 187, 950, 203] + ZOrder -20 + BackgroundColor "yellow" + IconDisplay "Port number" + } + Block { + BlockType Outport + Name "errors_status" + SID "27" + Position [915, 142, 950, 158] + ZOrder -21 + BackgroundColor "yellow" + Port "2" + IconDisplay "Port number" + } + Block { + BlockType Outport + Name "data send" + SID "28" + Position [915, 232, 950, 248] + ZOrder -22 + BackgroundColor "yellow" + Port "3" + IconDisplay "Port number" + } + Line { + ZOrder 1 + SrcBlock "receive message 1" + SrcPort 3 + DstBlock "set width" + DstPort 1 + } + Line { + ZOrder 2 + SrcBlock "receive message 1" + SrcPort 1 + DstBlock "Mux" + DstPort 2 + } + Line { + ZOrder 3 + SrcBlock "receive message 1" + SrcPort 2 + DstBlock "Mux" + DstPort 3 + } + Line { + ZOrder 4 + SrcBlock "timeout" + SrcPort 1 + DstBlock "receive message 1" + DstPort 1 + } + Line { + ZOrder 5 + SrcBlock "send message 1" + SrcPort 1 + DstBlock "Mux" + DstPort 1 + } + Line { + ZOrder 6 + SrcBlock "Mux" + SrcPort 1 + Points [0, -15] + DstBlock "errors_status" + DstPort 1 + } + Line { + ZOrder 7 + SrcBlock "set width" + SrcPort 1 + DstBlock "data recv" + DstPort 1 + } + Line { + ZOrder 8 + SrcBlock "constants" + SrcPort 1 + DstBlock "Mux1" + DstPort 1 + } + Line { + ZOrder 9 + Labels [0, 0] + SrcBlock "Mux1" + SrcPort 1 + Points [45, 0] + Branch { + ZOrder 10 + Points [0, -80] + DstBlock "send message 1" + DstPort 2 + } + Branch { + ZOrder 11 + Labels [1, 0] + DstBlock "data send" + DstPort 1 + } + } + Line { + ZOrder 12 + SrcBlock "data ready 2 kHz" + SrcPort 1 + DstBlock "send message 1" + DstPort 1 + } + Line { + ZOrder 13 + SrcBlock "Pulse\nGenerator" + SrcPort 1 + DstBlock "Mux1" + DstPort 2 + } + Annotation { + SID "46" + Name "Simple VILLASnode to OPAL test using UDP messages" + Position [318, 57, 739, 76] + InternalMargins [0, 0, 0, 0] + FixedHeight off + FixedWidth off + ZOrder -1 + FontName "Verdana" + FontSize 14 + FontWeight "bold" + } + } + } + Line { + ZOrder 1 + SrcBlock "sm_model" + SrcPort 1 + DstBlock "sc_console" + DstPort 1 + } + Line { + ZOrder 2 + SrcBlock "sm_model" + SrcPort 2 + DstBlock "sc_console" + DstPort 2 + } + Line { + ZOrder 3 + Labels [0, 0] + SrcBlock "sm_model" + SrcPort 3 + DstBlock "sc_console" + DstPort 3 + } + } +} diff --git a/clients/opal/models/send_receive/send_receive.probe b/clients/opal/models/send_receive/send_receive.probe new file mode 100644 index 000000000..252156d6e --- /dev/null +++ b/clients/opal/models/send_receive/send_receive.probe @@ -0,0 +1,57 @@ +[General] +ATT_VERSION=6 +FileVersion=6 +numClientsProbe=0 +[Group_1] +condition=0 +decimationFactor=1 +duration=0.010000 +dynSignalsList=0 +fileLimit=1000000 +fixSignalsList=13|1|2|3|4|5|6|7|8|9|10|11|12|13 +level=0.000000 +maxDynSignals=100 +newMemSize=2500 +nodeId=0 +numValues=200 +offset=0 +rearmDelay=0.000000 +repetitive=1 +signalName= +signalNameId=0 +trigSigNameId=339755367 +trigSignalName= +trigType=0 +triggerButton=2 +triggerEnabled=0 +triggerState=0 +valueType=0 +writeEnabled=0 +writeFileName= +writeFileVarName= +[Group_25] +condition=0 +decimationFactor=1 +duration=0.005000 +dynSignalsList=0 +fileLimit=0 +level=0.000000 +maxDynSignals=100 +newMemSize=100 +nodeId=158494572 +numValues=100 +offset=0 +rearmDelay=0.000000 +repetitive=1 +signalName= +signalNameId=1818584175 +trigSigNameId=1866690149 +trigSignalName= +trigType=0 +triggerButton=2 +triggerEnabled=0 +triggerState=0 +valueType=0 +writeEnabled=0 +writeFileName= +writeFileVarName= diff --git a/clients/opal/models/send_receive/src/compat.c b/clients/opal/models/send_receive/src/compat.c new file mode 100644 index 000000000..dd10ada9b --- /dev/null +++ b/clients/opal/models/send_receive/src/compat.c @@ -0,0 +1,46 @@ +/** Compatibility code for GCC + * + * OPAL-RT's libSystem.a links against some Intel + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#include + +size_t __intel_sse2_strlen(const char *s) +{ + return strlen(s); +} + +void * _intel_fast_memset(void *b, int c, size_t len) +{ + return memset(b, c, len); +} + +void * _intel_fast_memcpy(void *restrict dst, const void *restrict src, size_t n) +{ + return memcpy(dst, src, n); +} + +int _intel_fast_memcmp(const void *s1, const void *s2, size_t n) +{ + return memcmp(s1, s2, n); +} diff --git a/clients/opal/models/send_receive/src/main.asv b/clients/opal/models/send_receive/src/main.asv new file mode 100644 index 000000000..ffb726cbd --- /dev/null +++ b/clients/opal/models/send_receive/src/main.asv @@ -0,0 +1,352 @@ +/** Main routine of AsyncIP. + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU Lesser General Public License v2.1 + * + * VILLASnode - connecting real-time simulation equipment + * + * This application is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License. + * + * This application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + *********************************************************************************/ + +/* Standard ANSI C headers needed for this program */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Define RTLAB before including OpalPrint.h for messages to be sent + * to the OpalDisplay. Otherwise stdout will be used. */ +#define RTLAB +#include "OpalPrint.h" +#include "AsyncApi.h" + +/* This is the message format */ +#include "config.h" +#include "socket.h" +#include "utils.h" + +#if PROTOCOL == VILLAS + #include "msg.h" + #include "msg_format.h" +#endif + +/* This is just for initializing the shared memory access to communicate + * with the RT-LAB model. It's easier to remember the arguments like this */ +#define ASYNC_SHMEM_NAME argv[1] +#define ASYNC_SHMEM_SIZE atoi(argv[2]) +#define PRINT_SHMEM_NAME argv[3] + +/* Global Variables */ +struct socket skt; + +static void * SendToIPPort(void *arg) +{ + unsigned int ModelState, SendID = 1, Sequence = 0; + int nbSend = 0, ret, cnt, len; + + /* Data from OPAL-RT model */ + double mdldata[MAX_VALUES]; + int mdldata_size; + +#if PROTOCOL == VILLAS + char buf[MSG_LEN(MAX_VALUES)]; + struct msg *msg = (struct msg *) buf; +#elif PROTOCOL == GTNET_SKT + char buf[MAX_VALUES * sizeof(float)]; + float *msg = (float *) buf; +#endif + + OpalPrint("%s: SendToIPPort thread started\n", PROGNAME); + + OpalGetNbAsyncSendIcon(&nbSend); + if (nbSend < 1) { + OpalPrint("%s: SendToIPPort: No transimission block for this controller. Stopping thread.\n", PROGNAME); + return NULL; + } + + do { + /* This call unblocks when the 'Data Ready' line of a send icon is asserted. */ + ret = OpalWaitForAsyncSendRequest(&SendID); + if (ret != EOK) { + ModelState = OpalGetAsyncModelState(); + if ((ModelState != STATE_RESET) && (ModelState != STATE_STOP)) { + OpalSetAsyncSendIconError(ret, SendID); + OpalPrint("%s: OpalWaitForAsyncSendRequest(), errno %d\n", PROGNAME, ret); + } + + continue; + } + + /* No errors encountered yet */ + OpalSetAsyncSendIconError(0, SendID); + + /* Get the size of the data being sent by the unblocking SendID */ + OpalGetAsyncSendIconDataLength(&mdldata_size, SendID); + cnt = mdldata_size / sizeof(double); + if (cnt > MAX_VALUES) { + OpalPrint("%s: Number of signals for SendID=%d exceeds allowed maximum (%d)\n", + PROGNAME, SendID, MAX_VALUES); + return NULL; + } + + /* Read data from the model */ + OpalGetAsyncSendIconData(mdldata, mdldata_size, SendID); + +#if PROTOCOL == VILLAS + /* Get current time */ + struct timespec now; + clock_gettime(CLOCK_REALTIME, &now); + + msg->length = mdldata_size / sizeof(double); + msg->sequence = Sequence++; + msg->ts.sec = now.tv_sec; + msg->ts.nsec = now.tv_nsec; + + for (int i = 0; i < msg->length; i++) + msg->data[i].f = (float) mdldata[i]; + + msg_hton(msg); + + len = MSG_LEN(msg->length); +#elif PROTOCOL == GTNET_SKT + uint32_t *imsg = (uint32_t *) msg; + for (int i = 0; i < cnt; i++) { + msg[i] = (float) mdldata[i]; + imsg[i] = htonl(imsg[i]); + } + + len = mdldata_size / sizeof(double) * sizeof(float); +#else + #error Unknown protocol +#endif + + /* Perform the actual write to the ip port */ + ret = socket_send(&skt, (char *) msg, len); + if (ret < 0) + OpalSetAsyncSendIconError(errno, SendID); + else + OpalSetAsyncSendIconError(0, SendID); + + /* This next call allows the execution of the "asynchronous" process + * to actually be synchronous with the model. To achieve this, you + * should set the "Sending Mode" in the Async_Send block to + * NEED_REPLY_BEFORE_NEXT_SEND or NEED_REPLY_NOW. This will force + * the model to wait for this process to call this + * OpalAsyncSendRequestDone function before continuing. */ + OpalAsyncSendRequestDone(SendID); + + /* Before continuing, we make sure that the real-time model + * has not been stopped. If it has, we quit. */ + ModelState = OpalGetAsyncModelState(); + } while ((ModelState != STATE_RESET) && (ModelState != STATE_STOP)); + + OpalPrint("%s: SendToIPPort: Finished\n", PROGNAME); + + return NULL; +} + +static void * RecvFromIPPort(void *arg) +{ + unsigned int ModelState, RecvID = 1; + int nbRecv = 0, ret, cnt; + + /* Data from OPAL-RT model */ + double mdldata[MAX_VALUES]; + int mdldata_size; + +#if PROTOCOL == VILLAS + char buf[MSG_LEN(MAX_VALUES)]; + struct msg *msg = (struct msg *) buf; +#elif PROTOCOL == GTNET_SKT + char buf[MAX_VALUES * sizeof(float)]; + float *msg = (float *) buf; +#else + #error Unknown protocol +#endif + + OpalPrint("%s: RecvFromIPPort thread started\n", PROGNAME); + + OpalGetNbAsyncRecvIcon(&nbRecv); + if (nbRecv < 1) { + OpalPrint("%s: RecvFromIPPort: No reception block for this controller. Stopping thread.\n", PROGNAME); + return NULL; + } + + do { + /* Receive message */ + ret = socket_recv(&skt, (char *) msg, sizeof(buf), 1.0); + if (ret < 1) { + ModelState = OpalGetAsyncModelState(); + if ((ModelState != STATE_RESET) && (ModelState != STATE_STOP)) { + if (ret == 0) /* timeout, so we continue silently */ + OpalPrint("%s: Timeout while waiting for data\n", PROGNAME, errno); + if (ret == -1) /* a more serious error, so we print it */ + OpalPrint("%s: Error %d while waiting for data\n", PROGNAME, errno); + + continue; + } + break; + } + + /* Get the number of signals to send back to the model */ + OpalGetAsyncRecvIconDataLength(&mdldata_size, RecvID); + cnt = mdldata_size / sizeof(double); + if (cnt > MAX_VALUES) { + OpalPrint("%s: Number of signals for RecvID=%d (%d) exceeds allowed maximum (%d)\n", + PROGNAME, RecvID, cnt, MAX_VALUES); + return NULL; + } + +#if PROTOCOL == VILLAS + msg_ntoh(msg); + + ret = msg_verify(msg); + if (ret) { + OpalPrint("%s: Skipping invalid packet\n", PROGNAME); + continue; + } + + if (cnt > msg->length) { + OpalPrint("%s: Number of signals for RecvID=%d (%d) exceeds what was received (%d)\n", + PROGNAME, RecvID, cnt, msg->length); + } + + for (int i = 0; i < msg->length; i++) { + mdldata[i] = (double) msg->data[i].f; + printf("Data rcvd from VILLAS %f\n", mdldata[i]); + } + + /* Update OPAL model */ + OpalSetAsyncRecvIconStatus(msg->sequence, RecvID); /* Set the Status to the message ID */ +#elif PROTOCOL == GTNET_SKT + uint32_t *imsg = (uint32_t *) msg; + for (int i = 0; i < cnt; i++) + imsg[i] = ntohl(imsg[i]); + + printf("Protocol GTNET_SKT\n"); + for (int i = 0; i < cnt; i++) { + mdldata[i] = (double) msg[i]; + printf("Data rcvd from GTNET_SKT %f\n", mdldata[i]); + } +#else + #error Unknown protocol +#endif + + OpalSetAsyncRecvIconError(0, RecvID); /* Set the Error to 0 */ + + OpalSetAsyncRecvIconData(mdldata, mdldata_size, RecvID); + + /* Before continuing, we make sure that the real-time model + * has not been stopped. If it has, we quit. */ + ModelState = OpalGetAsyncModelState(); + } while ((ModelState != STATE_RESET) && (ModelState != STATE_STOP)); + + OpalPrint("%s: RecvFromIPPort: Finished\n", PROGNAME); + + return NULL; +} + +int main(int argc, char *argv[]) +{ + /* @todo remove after testing */ + printf("*****************Starting the Application****************\n"); + FILE * testfile = fopen ("testfile.txt","w"); + if (testfile!=NULL) + { + fputs ("test file to check if main runs", testfile); + fclose (testfile); + } + + int ret; + + Opal_GenAsyncParam_Ctrl IconCtrlStruct; + + pthread_t tid_send, tid_recv; + + OpalPrint("%s: This is %s client version %s\n", PROGNAME, PROGNAME, VERSION); + + /* Check for the proper arguments to the program */ + if (argc < 4) { + printf("Invalid Arguments: 1-AsyncShmemName 2-AsyncShmemSize 3-PrintShmemName\n"); + exit(0); + } + + /* Enable the OpalPrint function. This prints to the OpalDisplay. */ + ret = OpalSystemCtrl_Register(PRINT_SHMEM_NAME); + if (ret != EOK) { + printf("%s: ERROR: OpalPrint() access not available\n", PROGNAME); + exit(EXIT_FAILURE); + } + + /* Open Share Memory created by the model. */ + ret = OpalOpenAsyncMem(ASYNC_SHMEM_SIZE, ASYNC_SHMEM_NAME); + if (ret != EOK) { + OpalPrint("%s: ERROR: Model shared memory not available\n", PROGNAME); + exit(EXIT_FAILURE); + } + + AssignProcToCpu0(); + + /* Get IP Controler Parameters (ie: ip address, port number...) and + * initialize the device on the QNX node. */ + memset(&IconCtrlStruct, 0, sizeof(IconCtrlStruct)); + + ret = OpalGetAsyncCtrlParameters(&IconCtrlStruct, sizeof(IconCtrlStruct)); + if (ret != EOK) { + OpalPrint("%s: ERROR: Could not get controller parameters (%d).\n", PROGNAME, ret); + exit(EXIT_FAILURE); + } + + /* Initialize socket */ + ret = socket_init(&skt, IconCtrlStruct); + if (ret != EOK) { + OpalPrint("%s: ERROR: Initialization failed.\n", PROGNAME); + exit(EXIT_FAILURE); + } + + /* Start send/receive threads */ + ret = pthread_create(&tid_send, NULL, SendToIPPort, NULL); + if (ret == -1) + OpalPrint("%s: ERROR: Could not create thread (SendToIPPort), errno %d\n", PROGNAME, errno); + + ret = pthread_create(&tid_recv, NULL, RecvFromIPPort, NULL); + if (ret == -1) + OpalPrint("%s: ERROR: Could not create thread (RecvFromIPPort), errno %d\n", PROGNAME, errno); + + /* Wait for both threads to finish */ + ret = pthread_join(tid_send, NULL); + if (ret != 0) + OpalPrint("%s: ERROR: pthread_join (SendToIPPort), errno %d\n", PROGNAME, ret); + + ret = pthread_join(tid_recv, NULL); + if (ret != 0) + OpalPrint("%s: ERROR: pthread_join (RecvFromIPPort), errno %d\n", PROGNAME, ret); + + /* Close the ip port and shared memories */ + socket_close(&skt, IconCtrlStruct); + + OpalCloseAsyncMem (ASYNC_SHMEM_SIZE, ASYNC_SHMEM_NAME); + OpalSystemCtrl_UnRegister(PRINT_SHMEM_NAME); + + return 0; +} diff --git a/clients/opal/models/send_receive/src/main.c b/clients/opal/models/send_receive/src/main.c new file mode 100644 index 000000000..30f83006e --- /dev/null +++ b/clients/opal/models/send_receive/src/main.c @@ -0,0 +1,340 @@ +/** Main routine of AsyncIP. + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +/* Standard ANSI C headers needed for this program */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Define RTLAB before including OpalPrint.h for messages to be sent + * to the OpalDisplay. Otherwise stdout will be used. */ +#define RTLAB +#include "OpalPrint.h" +#include "AsyncApi.h" + +/* This is the message format */ +#include "config.h" +#include "socket.h" +#include "utils.h" + +#if PROTOCOL == VILLAS + #include "msg.h" + #include "msg_format.h" +#endif + +/* This is just for initializing the shared memory access to communicate + * with the RT-LAB model. It's easier to remember the arguments like this */ +#define ASYNC_SHMEM_NAME argv[1] +#define ASYNC_SHMEM_SIZE atoi(argv[2]) +#define PRINT_SHMEM_NAME argv[3] + +/* Global Variables */ +struct socket skt; + +static void * SendToIPPort(void *arg) +{ + unsigned int ModelState, SendID = 1, Sequence = 0; + int nbSend = 0, ret, cnt, len; + + /* Data from OPAL-RT model */ + double mdldata[MAX_VALUES]; + int mdldata_size; + +#if PROTOCOL == VILLAS + char buf[MSG_LEN(MAX_VALUES)]; + struct msg *msg = (struct msg *) buf; +#elif PROTOCOL == GTNET_SKT + char buf[MAX_VALUES * sizeof(float)]; + float *msg = (float *) buf; +#endif + + OpalPrint("%s: SendToIPPort thread started\n", PROGNAME); + + OpalGetNbAsyncSendIcon(&nbSend); + if (nbSend < 1) { + OpalPrint("%s: SendToIPPort: No transimission block for this controller. Stopping thread.\n", PROGNAME); + return NULL; + } + + do { + /* This call unblocks when the 'Data Ready' line of a send icon is asserted. */ + ret = OpalWaitForAsyncSendRequest(&SendID); + if (ret != EOK) { + ModelState = OpalGetAsyncModelState(); + if ((ModelState != STATE_RESET) && (ModelState != STATE_STOP)) { + OpalSetAsyncSendIconError(ret, SendID); + OpalPrint("%s: OpalWaitForAsyncSendRequest(), errno %d\n", PROGNAME, ret); + } + + continue; + } + + /* No errors encountered yet */ + OpalSetAsyncSendIconError(0, SendID); + + /* Get the size of the data being sent by the unblocking SendID */ + OpalGetAsyncSendIconDataLength(&mdldata_size, SendID); + cnt = mdldata_size / sizeof(double); + if (cnt > MAX_VALUES) { + OpalPrint("%s: Number of signals for SendID=%d exceeds allowed maximum (%d). Limiting...\n", + PROGNAME, SendID, MAX_VALUES); + cnt = MAX_VALUES; + } + + /* Read data from the model */ + OpalGetAsyncSendIconData(mdldata, mdldata_size, SendID); + +#if PROTOCOL == VILLAS + /* Get current time */ + struct timespec now; + clock_gettime(CLOCK_REALTIME, &now); + + msg->version = MSG_VERSION; + msg->type = MSG_TYPE_DATA; + msg->rsvd1 = 0; + msg->rsvd2 = 0; + msg->length = cnt; + msg->sequence = Sequence++; + msg->ts.sec = now.tv_sec; + msg->ts.nsec = now.tv_nsec; + + for (int i = 0; i < msg->length; i++) + msg->data[i].f = (float) mdldata[i]; + + len = MSG_LEN(msg->length); + + msg_hton(msg); +#elif PROTOCOL == GTNET_SKT + uint32_t *imsg = (uint32_t *) msg; + for (int i = 0; i < cnt; i++) { + msg[i] = (float) mdldata[i]; + imsg[i] = htonl(imsg[i]); + } + + len = cnt * sizeof(float); +#else + #error Unknown protocol +#endif + + /* Perform the actual write to the ip port */ + ret = socket_send(&skt, (char *) msg, len); + if (ret < 0) + OpalSetAsyncSendIconError(errno, SendID); + else + OpalSetAsyncSendIconError(0, SendID); + + /* This next call allows the execution of the "asynchronous" process + * to actually be synchronous with the model. To achieve this, you + * should set the "Sending Mode" in the Async_Send block to + * NEED_REPLY_BEFORE_NEXT_SEND or NEED_REPLY_NOW. This will force + * the model to wait for this process to call this + * OpalAsyncSendRequestDone function before continuing. */ + OpalAsyncSendRequestDone(SendID); + + /* Before continuing, we make sure that the real-time model + * has not been stopped. If it has, we quit. */ + ModelState = OpalGetAsyncModelState(); + } while ((ModelState != STATE_RESET) && (ModelState != STATE_STOP)); + + OpalPrint("%s: SendToIPPort: Finished\n", PROGNAME); + + return NULL; +} + +static void * RecvFromIPPort(void *arg) +{ + unsigned int ModelState, RecvID = 1; + int nbRecv = 0, ret, cnt; + + /* Data from OPAL-RT model */ + double mdldata[MAX_VALUES]; + int mdldata_size; + +#if PROTOCOL == VILLAS + char buf[MSG_LEN(MAX_VALUES)]; + struct msg *msg = (struct msg *) buf; +#elif PROTOCOL == GTNET_SKT + char buf[MAX_VALUES * sizeof(float)]; + float *msg = (float *) buf; +#else + #error Unknown protocol +#endif + + OpalPrint("%s: RecvFromIPPort thread started\n", PROGNAME); + + OpalGetNbAsyncRecvIcon(&nbRecv); + if (nbRecv < 1) { + OpalPrint("%s: RecvFromIPPort: No reception block for this controller. Stopping thread.\n", PROGNAME); + return NULL; + } + + do { + /* Receive message */ + ret = socket_recv(&skt, (char *) msg, sizeof(buf), 1.0); + if (ret < 1) { + ModelState = OpalGetAsyncModelState(); + if ((ModelState != STATE_RESET) && (ModelState != STATE_STOP)) { + if (ret == 0) /* timeout, so we continue silently */ + OpalPrint("%s: Timeout while waiting for data\n", PROGNAME, errno); + if (ret == -1) /* a more serious error, so we print it */ + OpalPrint("%s: Error %d while waiting for data\n", PROGNAME, errno); + + continue; + } + break; + } + + /* Get the number of signals to send back to the model */ + OpalGetAsyncRecvIconDataLength(&mdldata_size, RecvID); + cnt = mdldata_size / sizeof(double); + if (cnt > MAX_VALUES) { + OpalPrint("%s: Number of signals for RecvID=%d (%d) exceeds allowed maximum (%d)\n", + PROGNAME, RecvID, cnt, MAX_VALUES); + return NULL; + } + +#if PROTOCOL == VILLAS + msg_ntoh(msg); + + ret = msg_verify(msg); + if (ret) { + OpalPrint("%s: Skipping invalid packet\n", PROGNAME); + continue; + } + + if (cnt > msg->length) { + OpalPrint("%s: Number of signals for RecvID=%d (%d) exceeds what was received (%d)\n", + PROGNAME, RecvID, cnt, msg->length); + } + + for (int i = 0; i < msg->length; i++) + mdldata[i] = (double) msg->data[i].f; + + /* Update OPAL model */ + OpalSetAsyncRecvIconStatus(msg->sequence, RecvID); /* Set the Status to the message ID */ +#elif PROTOCOL == GTNET_SKT + uint32_t *imsg = (uint32_t *) msg; + for (int i = 0; i < cnt; i++) { + imsg[i] = ntohl(imsg[i]); + mdldata[i] = (double) msg[i]; + } +#else + #error Unknown protocol +#endif + + OpalSetAsyncRecvIconError(0, RecvID); /* Set the Error to 0 */ + + OpalSetAsyncRecvIconData(mdldata, mdldata_size, RecvID); + + /* Before continuing, we make sure that the real-time model + * has not been stopped. If it has, we quit. */ + ModelState = OpalGetAsyncModelState(); + } while ((ModelState != STATE_RESET) && (ModelState != STATE_STOP)); + + OpalPrint("%s: RecvFromIPPort: Finished\n", PROGNAME); + + return NULL; +} + +int main(int argc, char *argv[]) +{ + int ret; + + Opal_GenAsyncParam_Ctrl IconCtrlStruct; + + pthread_t tid_send, tid_recv; + + OpalPrint("%s: This is %s client version %s\n", PROGNAME, PROGNAME, VERSION); + + /* Check for the proper arguments to the program */ + if (argc < 4) { + printf("Invalid Arguments: 1-AsyncShmemName 2-AsyncShmemSize 3-PrintShmemName\n"); + exit(0); + } + + /* Enable the OpalPrint function. This prints to the OpalDisplay. */ + ret = OpalSystemCtrl_Register(PRINT_SHMEM_NAME); + if (ret != EOK) { + printf("%s: ERROR: OpalPrint() access not available\n", PROGNAME); + exit(EXIT_FAILURE); + } + + /* Open Share Memory created by the model. */ + ret = OpalOpenAsyncMem(ASYNC_SHMEM_SIZE, ASYNC_SHMEM_NAME); + if (ret != EOK) { + OpalPrint("%s: ERROR: Model shared memory not available\n", PROGNAME); + exit(EXIT_FAILURE); + } + + AssignProcToCpu0(); + + /* Get IP Controler Parameters (ie: ip address, port number...) and + * initialize the device on the QNX node. */ + memset(&IconCtrlStruct, 0, sizeof(IconCtrlStruct)); + + ret = OpalGetAsyncCtrlParameters(&IconCtrlStruct, sizeof(IconCtrlStruct)); + if (ret != EOK) { + OpalPrint("%s: ERROR: Could not get controller parameters (%d).\n", PROGNAME, ret); + exit(EXIT_FAILURE); + } + + /* Initialize socket */ + ret = socket_init(&skt, IconCtrlStruct); + if (ret != EOK) { + OpalPrint("%s: ERROR: Initialization failed.\n", PROGNAME); + exit(EXIT_FAILURE); + } + + /* Start send/receive threads */ + ret = pthread_create(&tid_send, NULL, SendToIPPort, NULL); + if (ret == -1) + OpalPrint("%s: ERROR: Could not create thread (SendToIPPort), errno %d\n", PROGNAME, errno); + + ret = pthread_create(&tid_recv, NULL, RecvFromIPPort, NULL); + if (ret == -1) + OpalPrint("%s: ERROR: Could not create thread (RecvFromIPPort), errno %d\n", PROGNAME, errno); + + /* Wait for both threads to finish */ + ret = pthread_join(tid_send, NULL); + if (ret != 0) + OpalPrint("%s: ERROR: pthread_join (SendToIPPort), errno %d\n", PROGNAME, ret); + + ret = pthread_join(tid_recv, NULL); + if (ret != 0) + OpalPrint("%s: ERROR: pthread_join (RecvFromIPPort), errno %d\n", PROGNAME, ret); + + /* Close the ip port and shared memories */ + socket_close(&skt, IconCtrlStruct); + + OpalCloseAsyncMem (ASYNC_SHMEM_SIZE, ASYNC_SHMEM_NAME); + OpalSystemCtrl_UnRegister(PRINT_SHMEM_NAME); + + return 0; +} diff --git a/clients/opal/models/send_receive/src/msg.c b/clients/opal/models/send_receive/src/msg.c new file mode 100644 index 000000000..4794634f4 --- /dev/null +++ b/clients/opal/models/send_receive/src/msg.c @@ -0,0 +1,70 @@ +/** Message related functions. + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#include + +#include "msg.h" +#include "msg_format.h" + +void msg_ntoh(struct msg *m) +{ + msg_hdr_ntoh(m); + + for (int i = 0; i < m->length; i++) + m->data[i].i = ntohl(m->data[i].i); +} + +void msg_hton(struct msg *m) +{ + for (int i = 0; i < m->length; i++) + m->data[i].i = htonl(m->data[i].i); + + msg_hdr_hton(m); +} + +void msg_hdr_hton(struct msg *m) +{ + m->length = htons(m->length); + m->sequence = htonl(m->sequence); + m->ts.sec = htonl(m->ts.sec); + m->ts.nsec = htonl(m->ts.nsec); +} + +void msg_hdr_ntoh(struct msg *m) +{ + m->length = ntohs(m->length); + m->sequence = ntohl(m->sequence); + m->ts.sec = ntohl(m->ts.sec); + m->ts.nsec = ntohl(m->ts.nsec); +} + +int msg_verify(struct msg *m) +{ + if (m->version != MSG_VERSION) + return -1; + else if (m->type != MSG_TYPE_DATA) + return -2; + else if ((m->rsvd1 != 0) || (m->rsvd2 != 0)) + return -3; + else + return 0; +} \ No newline at end of file diff --git a/clients/opal/models/send_receive/src/socket.c b/clients/opal/models/send_receive/src/socket.c new file mode 100644 index 000000000..c32ea1344 --- /dev/null +++ b/clients/opal/models/send_receive/src/socket.c @@ -0,0 +1,190 @@ +/** Helper functions for sockets. + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Define RTLAB before including OpalPrint.h for messages to be sent + * to the OpalDisplay. Otherwise stdout will be used. */ +#define RTLAB +#include "OpalPrint.h" +#include "AsyncApi.h" + +#include "config.h" +#include "socket.h" + +int socket_init(struct socket *s, Opal_GenAsyncParam_Ctrl IconCtrlStruct) +{ + struct ip_mreq mreq; /* Multicast group structure */ + unsigned char TTL = 1, LOOP = 0; + int rc, proto, ret; + + proto = (int) IconCtrlStruct.FloatParam[0]; + if (proto != UDP_PROTOCOL) { + OpalPrint("%s: This version of %s only supports UDP\n", PROGNAME, PROGNAME); + return EIO; + } + + + OpalPrint("%s: Version : %s\n", PROGNAME, VERSION); + OpalPrint("%s: Remote Address : %s\n", PROGNAME, IconCtrlStruct.StringParam[0]); + OpalPrint("%s: Remote Port : %d\n", PROGNAME, (int) IconCtrlStruct.FloatParam[1]); + + /* Initialize the socket */ + s->sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (s->sd < 0) { + OpalPrint("%s: ERROR: Could not open socket\n", PROGNAME); + return EIO; + } + + /* Set the structure for the remote port and address */ + memset(&s->send_ad, 0, sizeof(s->send_ad)); + s->send_ad.sin_family = AF_INET; + s->send_ad.sin_addr.s_addr = inet_addr(IconCtrlStruct.StringParam[0]); + s->send_ad.sin_port = htons((u_short) IconCtrlStruct.FloatParam[1]); + + /* Set the structure for the local port and address */ + memset(&s->recv_ad, 0, sizeof(s->recv_ad)); + s->recv_ad.sin_family = AF_INET; + s->recv_ad.sin_addr.s_addr = INADDR_ANY; + s->recv_ad.sin_port = htons((u_short) IconCtrlStruct.FloatParam[2]); + + /* Bind local port and address to socket. */ + ret = bind(s->sd, (struct sockaddr *) &s->recv_ad, sizeof(struct sockaddr_in)); + if (ret == -1) { + OpalPrint("%s: ERROR: Could not bind local port to socket\n", PROGNAME); + return EIO; + } + else + OpalPrint("%s: Local Port : %d\n", PROGNAME, (int) IconCtrlStruct.FloatParam[2]); + + /* If sending to a multicast address */ + if ((inet_addr(IconCtrlStruct.StringParam[0]) & inet_addr("240.0.0.0")) == inet_addr("224.0.0.0")) { + ret = setsockopt(s->sd, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &TTL, sizeof(TTL)); + if (ret == -1) { + OpalPrint("%s: ERROR: Could not set TTL for multicast send (%d)\n", PROGNAME, errno); + return EIO; + } + + ret = setsockopt(s->sd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&LOOP, sizeof(LOOP)); + if (ret == -1) { + OpalPrint("%s: ERROR: Could not set loopback for multicast send (%d)\n", PROGNAME, errno); + return EIO; + } + + OpalPrint("%s: Configured socket for sending to multicast address\n", PROGNAME); + } + + /* If receiving from a multicast group, register for it. */ + if (inet_addr(IconCtrlStruct.StringParam[1]) > 0) { + if ((inet_addr(IconCtrlStruct.StringParam[1]) & inet_addr("240.0.0.0")) == inet_addr("224.0.0.0")) { + mreq.imr_multiaddr.s_addr = inet_addr(IconCtrlStruct.StringParam[1]); + mreq.imr_interface.s_addr = INADDR_ANY; + + /* Have the multicast socket join the multicast group */ + ret = setsockopt(s->sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof(mreq)); + if (ret == -1) { + OpalPrint("%s: ERROR: Could not join multicast group (%d)\n", PROGNAME, errno); + return EIO; + } + + OpalPrint("%s: Added process to multicast group (%s)\n", + PROGNAME, IconCtrlStruct.StringParam[1]); + } + else { + OpalPrint("%s: WARNING: IP address for multicast group is not in multicast range. Ignored\n", + PROGNAME); + } + } + + return EOK; +} + +int socket_close(struct socket *s, Opal_GenAsyncParam_Ctrl IconCtrlStruct) +{ + if (s->sd < 0) { + shutdown(s->sd, SHUT_RDWR); + close(s->sd); + } + + return 0; +} + +int socket_send(struct socket *s, char *data, int len) +{ + if (s->sd < 0) + return -1; + + /* Send the packet */ + return sendto(s->sd, data, len, 0, (struct sockaddr *) &s->send_ad, sizeof(s->send_ad)); +} + +int socket_recv(struct socket *s, char *data, int len, double timeout) +{ + int ret; + struct sockaddr_in client_ad; + struct timeval tv; + socklen_t client_ad_size = sizeof(client_ad); + fd_set sd_set; + + if (s->sd < 0) + return -1; + + /* Set the descriptor set for the select() call */ + FD_ZERO(&sd_set); + FD_SET(s->sd, &sd_set); + + /* Set the tv structure to the correct timeout value */ + tv.tv_sec = (int) timeout; + tv.tv_usec = (int) ((timeout - tv.tv_sec) * 1000000); + + /* Wait for a packet. We use select() to have a timeout. This is + * necessary when reseting the model so we don't wait indefinitely + * and prevent the process from exiting and freeing the port for + * a future instance (model load). */ + ret = select(s->sd + 1, &sd_set, (fd_set *) 0, (fd_set *) 0, &tv); + switch (ret) { + case -1: /* Error */ + return -1; + case 0: /* We hit the timeout */ + return 0; + default: + if (!(FD_ISSET(s->sd, &sd_set))) { + /* We received something, but it's not on "sd". Since sd is the only + * descriptor in the set... */ + OpalPrint("%s: RecvPacket: God, is that You trying to reach me?\n", PROGNAME); + return -1; + } + } + + /* Clear the data array (in case we receive an incomplete packet) */ + memset(data, 0, len); + + /* Perform the reception */ + return recvfrom(s->sd, data, len, 0, (struct sockaddr *) &client_ad, &client_ad_size); +} \ No newline at end of file diff --git a/clients/opal/models/send_receive/src/utils.c b/clients/opal/models/send_receive/src/utils.c new file mode 100644 index 000000000..6e9ebf3e3 --- /dev/null +++ b/clients/opal/models/send_receive/src/utils.c @@ -0,0 +1,52 @@ +/** Configure scheduler. + * + * @author Steffen Vogel + * @author Mathieu Dubé-Dallaire + * @copyright 2003, OPAL-RT Technologies inc + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#include +#include + +/* Define RTLAB before including OpalPrint.h for messages to be sent + * to the OpalDisplay. Otherwise stdout will be used. */ +#define RTLAB +#include "OpalPrint.h" + +#include "config.h" +#include "utils.h" + +int AssignProcToCpu0(void) +{ + int ret; + cpu_set_t bindSet; + + CPU_ZERO(&bindSet); + CPU_SET(0, &bindSet); + + /* Changing process cpu affinity */ + ret = sched_setaffinity(0, sizeof(cpu_set_t), &bindSet); + if (ret) { + OpalPrint("Unable to bind the process to CPU 0: %d\n", errno); + return EINVAL; + } + + return 0; +} diff --git a/clients/opal/villas_udp.llp b/clients/opal/villas_udp.llp new file mode 100644 index 000000000..934645867 --- /dev/null +++ b/clients/opal/villas_udp.llp @@ -0,0 +1,20 @@ + + + + villas_udp + This is a project! + 134.130.169.120:25251 + FC70D2D4-2B11-40E7-8317-6C0EB3BB3182 + ON + C:\Users\svo\workspace\villas\node\clients\opal\villas_udp\villas_udp.llp + + + + + models/send_receive/send_receive.mdl + C:/Users/svo/workspace/villas/node/clients/opal/villas_udp/models/send_receive/send_receive.mdl + C:/Users/svo/workspace/villas/node/clients/opal/villas_udp/models/send_receive/send_receive.mdl + + + +