Documentation Home Page RT-LAB Home Page
Pour la documentation en FRANÇAIS, utilisez l'outil de traduction de votre navigateur Chrome, Edge ou Safari. Voir un exemple.

Profibus Master

Description

The Profibus master driver is controlling a CIFX 50E-DP PC card designed by Hilscher. This card family is the unified standard supporting all Real-Time Ethernet and Fieldbus systems for PC based automation. In order to use the Profibus master communication interface, this card must be connected to the target through the PCI express link. The complete protocol stack is executed on the CIFX card and data exchange with the target is done via Dual-Port-Memory or DMA.

Then, the Profibus master driver is responsible for initializing the CIFX card and loading the appropriate kernel module to achieve typical Profibus master device operations, according to the user requirements.

A connection file must be used to bind the model signals to the driver variables. This file is a text file named 'connections.opal'.Three other configuration files are needed for the functioning of the Profibus master. These are Opal-RT's proprietary configuration file (named profibus_master_cfg.opal) and two files created and exported with SYCON.net.

The SYCON.net tool is provided by Hilscher (further provided by Opal-RT alongside the CIFX board). It is a Windows application. With the help of its GUI, one can configure the Profibus network according to requirements. Once configured, the network and card configuration must be exported in two formats. Both formats are needed for the correct functioning of the driver. The first file is a .nxd (database). This file will be downloaded by the driver onto the CIFX card in order to configure its inputs and outputs. The second file is a .xml file. This file is parsed by the driver in order to create connections between the inputs and outputs of the card and model signals.

According to the Profibus protocol specifications, the Profibus master is required to know the topology of the network prior to the start of the operation. Therefore, configuring the master device is synonymous with configuring the Profibus network. In this context, it is necessary to insert a Profibus slave into the network in order to validate the correct functioning of the master. For the purpose of this document, the slave used is a Hilscher CIFX 50E-DP (same type of card) running the Profibus slave firmware. However, it is important to keep in mind that the user can insert the slave of his/her choice into the network. For more information on how to inport another slave device's .gsd file or other general uses of SYCON.net, please consult SYCON.net's user manual, provided by Hilscher.

Before running the Profibus Master model, please ensure that the CIFX 50E-DP card that you are using was received with the Profibus master license installed.

As shown in the picture above, the CIFX card has a Profibus interface (DSub female connector, 9 pins) port. The connection to the slave is done with the help of an RS-485 cable.

For more information about the Profibus protocol itself, please refer to the PROFIBUS and PROFINET International website.



Note: RT-LAB offers a driver for the Profibus slave running on the same Hilscher card.


Driver Configuration

As mentioned above, the driver requires three files in order to function correctly.

These files are as follows for the DPV0 functions : profibus_master_cfg.opal, master_all_data_types_config.nxd and test_xml_master.xml.

These files are as follows for the DPV1 functions : profibus_dpv1_master_cfg.opal, profibus_dpv1_master.nxd and profibus_dpv1_master.xml.

profibus_master_cfg.opal

The profibus_master_cfg.opal file contains the following information:

OPAL-1.0 Object
ProfibusMaster::Configuration {
    board_id=0
    cifx_path=/Hilscher/ProfibusMaster
    nxd_file=profibus_dpv1_master.nxd
    xml_file=profibus_dpv1_master.xml
    DPV1_enabled=0
}

profibus_dpv1_master_cfg.opal

The profibus_dpv1_master_cfg.opal file contains the following information:

OPAL-1.0 Object
ProfibusMaster::Configuration {
    board_id=0
    cifx_path=/Hilscher/ProfibusMaster
    nxd_file=profibus_dpv1_master.nxd
    xml_file=profibus_dpv1_master.xml
    DPV1_enabled=1
}

The following table explains each driver parameter:

ParameterDescription
board_idIndex of the board. In the current implementation, this parameter must be set to 0 but it will be used when multiple-board support will be added.
cifx_pathPath where the firmware files of the CIFX board are located. By default, they are installed in '/Hilscher/ProfibusMaster'.
nxd_fileName of the .nxd file to download onto the CIFX board. In the example model provided, this file is called master_all_data_types_config.nxd
xml_fileName of the configuration .xml file to be used by the driver to create connections. In the example model provided, this file is called test_xml_master.xml
DPV1_enabledActivation of the DPV1 functions. 'DPV1_enabled' has to be set to 0 if the card does not support the feature or if you only want to use the DPV0 functions.

Files exported from SYCON.net: 'master_all_data_types.nxd' and 'test_xml_master.xml' (DPV0) or 'profibus_dpv1_master.nxd' and 'profibus_dpv1_master.xml' (DPV1)

As mentioned above, in order to create and export the two configuration files, SYCON.net needs to be used. The setup for the steps below assumes the use of the Hilscher CIFX 50E-DP Profibus slave card. The steps will take you through all the configuration tabs:

  • Start SYCON.net. Select your user name and enter your password.
  • Create a new project by selecting File -> New.
  • Expand the folder Profibus DPV0 or Profibus DPV1 depending upon your decision in the Fieldbus tab of the rightmost panel.

Next, expand the Master folder as seen below:

  • Click on the CIFX DP/DPM device in the list of Profibus masters. Drag and drop the device onto the main bus line. The end result should look as such:

  • Next, expand the Gateway/Stand-Alone Slave section of Profibus DPV0 or Profibus DPV1 in the Fieldbus tab:

  • Click on the CIFX DP/DPS device in the list of Profibus gateway/stand-alone slaves. Drag and drop the device onto the master's bus line. The end result should look as such:

  • Double click on the slave device. Its configuration window will pop up.

Nothing has to be changed in the 'Settings' or the 'Device Description' sections of the configuration.

In the 'Configuration' section, the following sub-tabs will require the user's attention: 'Modules', 'Signal Configuration', 'DPV1' and 'Device Settings'. The 'Parameters' section might be used as well, if a real slave device is used. In the case of the example being presented here, it is not.

If the user feels proficient in his/her Profibus knowledge, then the other sections can be explored as well. For the purpose of the example model included in the current RT-LAB installation, the tabs enumerated above should suffice.

  • Click on the 'Modules' tab.

The modules offered by the used slave are found in the list of available modules. By double-clicking them, or by clicking 'Insert' or 'Append', the user can add them to the list of 'Configured Modules', as seen in the image above. It is important to note that the direction of data is from the master's point of view. Hence, module '16 Bytes In' represents a data flow of 16 bytes entering the master and leaving the slave currently being configured.

It is important to note that the modules do not create a physical separation of the data. A module is simply a set of bytes. When transmitting or receiving, the modules will not be taken into account. What will, however, be taken into account, are the signals defined in each module. The signals are described at the next point. The order in which the signals in the in or out modules are added must be reflected in the connections.opal file. This will be explained in more detail further down in this document.

  • Click on the 'Signal Configuration' tab.

Expand each module in order to configure its signals. By default, all signals are named 'Input_XX' or 'Output_XX' and are of type 'Boolean'. Customize the mapping so that the signals have a representative but unique name. Make sure that these names match up with the ones provided in the connections.opal file (more details further down). As seen in the screenshot above, the maximum number of bytes has been reached after assigning a data type to each of the signals in the module. In this case, remove the extra input signals by clicking on them and clicking the 'Remove' button.

Due to a limitation in SYCON.net, the removal of extra signals can only be done one at a time.

The end result should look similar to the image below (i.e. without the red warning signs on the side of the signals):

Similarly, if you wish to add more signals, click on the 'Add Signal' button.

The configuration of the output modules is done in the same way.



Note: by SYCON.net definitions, the type 'Boolean' requires 8 bits.



  • (optional) The 'Parameters' section can be used when configuring a real slave device.
  • (optional) The 'Groups' section can be used if the user wishes to assign the slave being configured to a group.
  • (optional) The 'Extensions' section can be used to further configure the Profibus slave.
  • Click on the 'DPV1' tab.

The master driver supports DPV0 (cyclical communication) and DPV1 (acyclical communication). On the one hand, uncheck the 'Enable DPV1' check box if you want to use only cyclical communication (DPV0). Moreover, if it so happens that you receive a warning/error pop-up message when trying to switch to other configuration tabs or when clicking on 'Apply' or 'OK', then do the following: check 'Enable DPV1', set 'Max. channel data length' to 244 and 'Max. alarm PDU length' to 64. Then, uncheck again the 'Enable DPV1' box.

This is a limitation of SYCON.net. The setting of data will not change anything in the configuration, however, due to an internal setting of the SYCON.net, advancing is not possible without taking these steps.

On the other hand, check the 'Enable DPV1' check box if you want to use the acyclical communication. Then, choose the maximum channel data length you desire between 4 and 244 along with the maximum alarm PDU length between 4 and 64. Therefore, you can check the different types of alarm and choose the number of alarms in total that you require.

Moreover, you can select if you want to acknowledge alarms via SAP 50 or SAP51.

When SAP 50 is selected, the master uses SAP 50 for the alarm acknowledge to this slave, but the master still uses SAP 51 for DPV1 read/write services. This setting may cause a higher performance because SAP 50 is used exclusively for the alarm acknowledge and cannot be delayed by a running DPV1 read/write service. Using this feature requires that the slave supports it.

When SAP 51 is selected, The master uses SAP 51 for DPV1 read/write and for alarm acknowledge to this slave.

  • (optional) The 'Address Table' section can be used to confirm the order and configuration of the input and output modules in the DPM. Also, the configuration can be exported as a CSV file, if so required.
  • Click on the 'Device Settings' tab.

It is very important to select 'Controlled by application' for the 'Start of bus communication' setting because the bus communication is controlled by the driver.

Please keep 'Configuration data flag' at 'Fixed configuration'. A configuration from the master requires DPV1.

  • Click on 'Apply' and then 'OK'. This will close the window. The network is now configured and the information about its flow of data can be exported for the use of the driver. Therefore, back in the main window of the application (where the network was constructed by dropping the master onto the main bus line), right-click on the master device and navigate to Additional Functions > Export > DBM/nxd... as seen in the image below:

Name the file and place it in your model's Simulink folder.

  • Similarly, for the .xml file: right-click on the master device and navigate to Additional Functions > Export > XML... as seen in the image below:


Name the file and place it in your model's Simulink folder.

RT-LAB Usage

In RT-LAB, four configuration files need to transferred to the target before the model loads. The first two are the ones whose export is detailed above (namely the .nxd and the .xml files); These files need to be transferred in Binary mode. The other two files are the first configuration file described above ('profibus_master_cfg.opal' or 'profibus_dpv1_master_cfg.opal') and the connections.opal files; their transfer mode will have to be set to ASCII.

If the project where the Profibus master communication interface has to be integrated already contains a 'connections.opal' file, the main 'item {}' information of the file must be simply copied and added to the existing 'connections.opal' file. In other words, all 'connections.opal' files must be merged into a single file for a given simulation to use many drivers simultaneously.

The screenshot below shows the setup for the DPV0 model:

The 'connections.opal' file is required to bind model signals to driver variables. This is how all drivers implemented within the Data Interchange Layer work. In RT-LAB, model signals thatneed to reach the driver have to be connected to 'OpOutput' blocks. It is the case for the data sent by the Profibus master to the Profibus slave, defined by the signal items in the output modules of the configuration file described above.

Signals travelling from the driver to the simulation model have to be connected to 'OpInput' blocks. It is the case for the data received by the Profibus master from the slave, defined by the signal items in the input modules of the configuration file described above and the transmission status connections.

Below you can see the typical connections for the Profibus DPV1 master. you can note that all the connections typed in bold are additions of the Profibus DPV0 master connection file to make it work for the DPV1 example model. You can remove them to make it work with the DPV0 example model.
For the example model in RT-LAB, the entire available bandwidth per slave has been configured for cyclic messages, namely 244 bytes per slave per direction. Therefore, the last 25 double values in each direction were added to demonstrate communication with a full payload transmission, once all data types were covered.

Moreover, the example model in RT-LAB for the DPV1 functions have been configured for reading/writing acyclic messages, namely 240 bytes per slave per direction. We added all the connections to specify the common parameters to do a write or read request between the master and one or more slave. Also, the DPV1 model is configured to handle alarms request from the slave.

The configuration matches the one created above using SYCON.net. Please keep in mind that the names that the signals received in SYCON.net must match with the names provided in the third field of dataInExchanger. The order in which signals were added in SYCON.net must also match the order in which the connections are created for them in connections.opal. As an example, it can be seen above that the first two signals defined in the input modules are the in_boolean and the in_uint8. As it can be seen in the connections.opal file presented below, those two signals are the first two added to connect to master_inputs_slave_0 in the inputs section.

OPAL-1.0 Object
List {
	item {
		id {
			ProfibusMaster
			profibus_dpv1_master_cfg.opal
		}
		outputs {
			item {
				dataInProcess=OpOutput:read_request[0]
				dataInExchanger=profibus_0.rd_slave_addr[0]
			}	
			item {
				dataInProcess=OpOutput:read_request[1]
				dataInExchanger=profibus_0.rd_slot[0]
			}
			item {
				dataInProcess=OpOutput:read_request[2]
				dataInExchanger=profibus_0.rd_index[0]
			}	  
			item {
				dataInProcess=OpOutput:read_request[3]
				dataInExchanger=profibus_0.rd_len[0]
			}	  
			item {
				dataInProcess=OpOutput:read_request[4]
				dataInExchanger=profibus_0.rd_trigger[0]
			}	  
			item {
				dataInProcess=OpOutput:write_request[0]
				dataInExchanger=profibus_0.wr_slave_addr[0]
			}	
			item {
				dataInProcess=OpOutput:write_request[1]
				dataInExchanger=profibus_0.wr_slot[0]
			}
			item {
				dataInProcess=OpOutput:write_request[2]
				dataInExchanger=profibus_0.wr_index[0]
			}	
			item {
				dataInProcess=OpOutput:write_request[3]
				dataInExchanger=profibus_0.wr_length[0]
			}
			item {
				dataInProcess=OpOutput:write_request[4]
				dataInExchanger=profibus_0.wr_trigger[0]
			}	 	  
			item {
				dataInProcess=OpOutput:write_data[0:239]
				dataInExchanger=profibus_0.wr_data[0:239]
			}	  
			item {
				dataInProcess=OpOutput:alarm_ack_req[0]
				dataInExchanger=profibus_0.alarm_ack_slave_addr[0]
			}	
			item {
				dataInProcess=OpOutput:alarm_ack_req[1]
				dataInExchanger=profibus_0.alarm_ack_type[0]
			}
			item {
				dataInProcess=OpOutput:alarm_ack_req[2]
				dataInExchanger=profibus_0.alarm_ack_slot_number[0]
			}	  
			item {
				dataInProcess=OpOutput:alarm_ack_req[3]
				dataInExchanger=profibus_0.alarm_ack_specifier[0]
			}		
			item {
				dataInProcess=OpOutput:alarm_ack_req[4]
				dataInExchanger=profibus_0.alarm_ack_trigger[0]
			}	  
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[0]
				dataInExchanger=profibus_0.Addr_2.out_boolean[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[1]
				dataInExchanger=profibus_0.Addr_2.out_uint8[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[2]
				dataInExchanger=profibus_0.Addr_2.out_uint16[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[3]
				dataInExchanger=profibus_0.Addr_2.out_uint32[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[4]
				dataInExchanger=profibus_0.Addr_2.out_uint64[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[5]
				dataInExchanger=profibus_0.Addr_2.out_byte[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[6]
				dataInExchanger=profibus_0.Addr_2.out_int8[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[7]
				dataInExchanger=profibus_0.Addr_2.out_int16[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[8]
				dataInExchanger=profibus_0.Addr_2.out_int32[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[9]
				dataInExchanger=profibus_0.Addr_2.out_int64[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[10]
				dataInExchanger=profibus_0.Addr_2.out_float[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[11]
				dataInExchanger=profibus_0.Addr_2.out_double[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[12]
				dataInExchanger=profibus_0.Addr_2.out_double1[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[13]
				dataInExchanger=profibus_0.Addr_2.out_double2[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[14]
				dataInExchanger=profibus_0.Addr_2.out_double3[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[15]
				dataInExchanger=profibus_0.Addr_2.out_double4[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[16]
				dataInExchanger=profibus_0.Addr_2.out_double5[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[17]
				dataInExchanger=profibus_0.Addr_2.out_double6[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[18]
				dataInExchanger=profibus_0.Addr_2.out_double7[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[19]
				dataInExchanger=profibus_0.Addr_2.out_double8[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[20]
				dataInExchanger=profibus_0.Addr_2.out_double9[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[21]
				dataInExchanger=profibus_0.Addr_2.out_double10[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[22]
				dataInExchanger=profibus_0.Addr_2.out_double11[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[23]
				dataInExchanger=profibus_0.Addr_2.out_double12[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[24]
				dataInExchanger=profibus_0.Addr_2.out_double13[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[25]
				dataInExchanger=profibus_0.Addr_2.out_double14[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[26]
				dataInExchanger=profibus_0.Addr_2.out_double15[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[27]
				dataInExchanger=profibus_0.Addr_2.out_double16[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[28]
				dataInExchanger=profibus_0.Addr_2.out_double17[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[29]
				dataInExchanger=profibus_0.Addr_2.out_double18[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[30]
				dataInExchanger=profibus_0.Addr_2.out_double19[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[31]
				dataInExchanger=profibus_0.Addr_2.out_double20[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[32]
				dataInExchanger=profibus_0.Addr_2.out_double21[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[33]
				dataInExchanger=profibus_0.Addr_2.out_double22[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[34]
				dataInExchanger=profibus_0.Addr_2.out_double23[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[35]
				dataInExchanger=profibus_0.Addr_2.out_double24[0]
			}
			item {
				dataInProcess=OpOutput:master_outputs_slave_0[36]
				dataInExchanger=profibus_0.Addr_2.out_double25[0]
			}	  
		}
		inputs {
			item {
				dataInExchanger=profibus_0_status.init[0]
				dataInProcess=OpInput:init_status[0]
			}
			item {
				dataInExchanger=profibus_0_status.tx[0]
				dataInProcess=OpInput:tx_status[0]
			}
			item {
				dataInExchanger=profibus_0_status.rx[0]
				dataInProcess=OpInput:rx_status[0]
			}
			item {
				dataInExchanger=profibus_0.rd_status-0[0]
				dataInProcess=OpInput:read_req_status[0]
			}	 
			item {
				dataInExchanger=profibus_0.rd_status-1[0]
				dataInProcess=OpInput:read_req_errorDecode[0]
			}	  
			item {
				dataInExchanger=profibus_0.rd_status-2[0]
				dataInProcess=OpInput:read_req_errorCode1[0]
			}	 	
			item {
				dataInExchanger=profibus_0.rd_status-3[0]
				dataInProcess=OpInput:read_req_errorCode2[0]
			}	 
			item {
				dataInExchanger=profibus_0.rd_data[0:239]
				dataInProcess=OpInput:read_req_data[0:239]
			}	 	  
			item {
				dataInExchanger=profibus_0.wr_status-0[0]
				dataInProcess=OpInput:write_req_status[0]
			}	 
			item {
				dataInExchanger=profibus_0.wr_status-1[0]
				dataInProcess=OpInput:write_req_errorDecode[0]
			}	  
			item {
				dataInExchanger=profibus_0.wr_status-2[0]
				dataInProcess=OpInput:write_req_errorCode1[0]
			}	 	
			item {
				dataInExchanger=profibus_0.wr_status-3[0]
				dataInProcess=OpInput:write_req_errorCode2[0]
			}		
			item {
				dataInExchanger=profibus_0.alarm_info_slave_addr[0]
				dataInProcess=OpInput:alarm_info_slave_addr[0]
			}	 
			item {
				dataInExchanger=profibus_0.alarm_info_type[0]
				dataInProcess=OpInput:alarm_info_type[0]
			}	  
			item {
				dataInExchanger=profibus_0.alarm_info_slot[0]
				dataInProcess=OpInput:alarm_info_slot[0]
			}	 	
			item {
				dataInExchanger=profibus_0.alarm_info_specifier[0]
				dataInProcess=OpInput:alarm_info_specifier[0]
			}		
			item {
				dataInExchanger=profibus_0.alarm_info_data[0:58]
				dataInProcess=OpInput:alarm_info_data[0:58]
			}			  
			item {
				dataInExchanger=profibus_0.alarm_ack_status[0]
				dataInProcess=OpInput:alarm_ack_status[0]
			}	 
			item {
				dataInExchanger=profibus_0.alarm_ack_errorDecode[0]
				dataInProcess=OpInput:alarm_ack_errorDecode[0]
			}	  
			item {
				dataInExchanger=profibus_0.alarm_ack_errorCode1[0]
				dataInProcess=OpInput:alarm_ack_errorCode1[0]
			}	 	
			item {
				dataInExchanger=profibus_0.alarm_ack_errorCode2[0]
				dataInProcess=OpInput:alarm_ack_errorCode2[0]
			}		  
			item {
				dataInExchanger=profibus_0.Addr_2.in_boolean[0]
				dataInProcess=OpInput:master_inputs_slave_0[0]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_uint8[0]
				dataInProcess=OpInput:master_inputs_slave_0[1]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_uint16[0]
				dataInProcess=OpInput:master_inputs_slave_0[2]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_uint32[0]
				dataInProcess=OpInput:master_inputs_slave_0[3]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_uint64[0]
				dataInProcess=OpInput:master_inputs_slave_0[4]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_byte[0]
				dataInProcess=OpInput:master_inputs_slave_0[5]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_int8[0]
				dataInProcess=OpInput:master_inputs_slave_0[6]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_int16[0]
				dataInProcess=OpInput:master_inputs_slave_0[7]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_int32[0]
				dataInProcess=OpInput:master_inputs_slave_0[8]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_int64[0]
				dataInProcess=OpInput:master_inputs_slave_0[9]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_float[0]
				dataInProcess=OpInput:master_inputs_slave_0[10]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double[0]
				dataInProcess=OpInput:master_inputs_slave_0[11]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double1[0]
				dataInProcess=OpInput:master_inputs_slave_0[12]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double2[0]
				dataInProcess=OpInput:master_inputs_slave_0[13]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double3[0]
				dataInProcess=OpInput:master_inputs_slave_0[14]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double4[0]
				dataInProcess=OpInput:master_inputs_slave_0[15]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double5[0]
				dataInProcess=OpInput:master_inputs_slave_0[16]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double6[0]
				dataInProcess=OpInput:master_inputs_slave_0[17]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double7[0]
				dataInProcess=OpInput:master_inputs_slave_0[18]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double8[0]
				dataInProcess=OpInput:master_inputs_slave_0[19]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double9[0]
				dataInProcess=OpInput:master_inputs_slave_0[20]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double10[0]
				dataInProcess=OpInput:master_inputs_slave_0[21]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double11[0]
				dataInProcess=OpInput:master_inputs_slave_0[22]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double12[0]
				dataInProcess=OpInput:master_inputs_slave_0[23]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double13[0]
				dataInProcess=OpInput:master_inputs_slave_0[24]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double14[0]
				dataInProcess=OpInput:master_inputs_slave_0[25]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double15[0]
				dataInProcess=OpInput:master_inputs_slave_0[26]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double16[0]
				dataInProcess=OpInput:master_inputs_slave_0[27]
			} 
			item {
				dataInExchanger=profibus_0.Addr_2.in_double17[0]
				dataInProcess=OpInput:master_inputs_slave_0[28]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double18[0]
				dataInProcess=OpInput:master_inputs_slave_0[29]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double19[0]
				dataInProcess=OpInput:master_inputs_slave_0[30]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double20[0]
				dataInProcess=OpInput:master_inputs_slave_0[31]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double21[0]
				dataInProcess=OpInput:master_inputs_slave_0[32]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double22[0]
				dataInProcess=OpInput:master_inputs_slave_0[33]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double23[0]
				dataInProcess=OpInput:master_inputs_slave_0[34]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double24[0]
				dataInProcess=OpInput:master_inputs_slave_0[35]
			}
			item {
				dataInExchanger=profibus_0.Addr_2.in_double25[0]
				dataInProcess=OpInput:master_inputs_slave_0[36]
			}	  
		}
	} 
}

It is important that the second field of the 'id' item contains the name of the driver configuration file described above. Also, each string used as 'dataInExchanger' tags must have the same prefix defined by the name of the board 'profibus_', concatenated with the board index '0'. Next, if the point is data, the tag continues with a dot '.' followed by the address of the slave the data is meant for. In our example, there is only one slave connected, at station address 2; hence, what follows after the dot is 'Addr_2'. After that comes another dot '.' followed by the name of the element as defined when configuring the network in SYCON.net.

Finally, in the case of status connections, the tag containing the concatenation of the name of the board and its ID ('profibus_0') continues with '_status' concatenated with a dot '.' and the name of the status flag.

To receive the data from the Profibus slave in the DPV0 model, four 'OpInput' block are required. In the case of the example above, the first block must be named 'master_inputs_slave_0' because this is the name given in the connections file for the 'dataInProcess' fields. The name includes '_slave_0' to simplify incorporating the future support of multi-slave communication for the master. The next three blocks must be named 'init_status', 'tx_status' and 'rx_status', as seen in the above connections file. To send data to the Profibus slave through the connection points, one 'OpOutput' block must be used. In the case of the example above, it must be named 'master_outputs_slave_0'. Again, the name contains '_slave_0' for future use.

To write data to the Profibus slave in the DPV1 model, four 'OpInput' block are required. In the case of the example above, the first block must be named 'write_req' because this is the name given in the connections file for the 'dataInProcess' fields.

To read data from the Profibus slave in the DPV1 model, five 'OpInput' block are required. In the case of the example above, the first block must be named 'read_req' because this is the name given in the connections file for the 'dataInProcess' fields.

To handle alarms from the Profibus Slave in the DPV1 model, nine 'OpInput' block are required. In the case of the example above, the first block must be named 'alarm_info' in order to retrieve information of a received alarm such as the slave address, the alarm type, the alarm slot and the alarm specifier. The next blocks must be named 'alarm_ack' to received all the information.

As shown in the connections file example, three connections points can be used in the inputs section to receive status information from the CIFX card (status.init, status.tx and statux.rx). The table below describes each initialization status value that might be returned by the driver.

status.initDescription
0Initialization is successful.
-1The RT-LAB license for the Profibus master driver on the target is invalid. Contact Opal-RT support.
-2Failed to load uio_netx module. Validate your RT-LAB installation or contact Opal-RT support.
-3Invalid driver configuration. Validate that the names of the .nxd and the .xml files match with the ones provided in the profibus_master_config.opal file. Check for missing '{' and '}' brackets in the configuration and connections files.
-4There has been an error while the driver was parsing the .xml file provided. Try exporting the file from SYCON.net again, re-add it in the files section as described above and re-run your simulation. If the problem persists, contact Opal-RT support.
-5There was an error while copying the .nxd file. Try exporting the file from SYCON.net again, re-add it in the files section as described above and re-run your simulation. If the problem persists, contact Opal-RT support.
-6The Profibus board firmware is not found. Please validate that RT-LAB has been installed properly.
-7The amount of bytes configured to be sent exceeds the limit of 244 bytes per slave. Change the configuration file to accommodate this limit.
-8The amount of bytes configured to be received exceeds the limit of 244 bytes per slave. Change the configuration file to accommodate this limit.
-9Both the amount of bytes to send (outputs) and the amount of bytes to receive (inputs) exceed the limit of 244 bytes per direction, per slave. Change the configuration file to accommodate this limit.
-10The Profibus master license for the card is missing. Verify that you received a card with the license installed. If the problem persists, contact Opal-RT support.
-11The Profibus master application failed to register to receive acyclic packets. Try to restart your simulation. If the problem persists, contact Opal-RT support.
otherAny other initialization status is returned directly from the CIFX card driver API. The hexadecimal value of this status must be used to find the corresponding description in the CIFX API documentation, CIFX error codes documentation or in the Profibus master API.


The table below describes each transmission status value that might be returned by the driver.

status.txDescription
0No error. The Profibus master is successfully transmitting the configured data to the connected Profibus slave.
-1No Profibus slave is connected (or not yet connected) to the Profibus master.
otherAny other transmission status is returned directly from the CIFX card driver API. The hexadecimal value of this status must be used to find the corresponding description in the CIFX API documentation, CIFX error codes documentation or in the Profibus master API.


The table below describes each reception status value that might be returned by the driver.

status.rxDescription
0No error. The Profibus master is successfully receiving the configured data from the connected Profibus slave.
-1No Profibus slave is connected (or not yet connected) to the Profibus master.
otherAny other reception status is returned directly from the CIFX card driver API. The hexadecimal value of this status must be used to find the corresponding description in the CIFX API documentation, CIFX error codes documentation or in the Profibus master API.

The table below describes the acyclic read request status value that might be returned by the driver.

rd_status-0Description
0No error. The Profibus slave is successfully receiving the acyclic message from the connected Profibus master.
0xC0380025An error occurred when sending an acyclic read request to the slave.
If Read request bErrorCode1 value is equal to 13, it means it is a user-defined error:
Then, if Read request bErrorCode2 value is 1, it means that the slave address is out of range. The correct range value for this is between 2 and 125.
If Read request bErrorCode2 value is 2, it means that the slot number is incorrect and the slave doesn't recognize it.
If Read request bErrorCode2 value is 3, it means that the index number is incorrect and is not found in the corresponding slot.
Or if Read request bErrorCode2 value is 4, it means that the length of the requested data is incorrect. The maximum data length is 240 bytes.

If Read request bErrorCode1 value is different from 13, this error is explained in section 5.3.2.2 of Profibus master API.
otherAny other status is returned directly from the CIFX card driver API. The hexadecimal value of this status must be used to find the corresponding description in the CIFX API documentation, CIFX error codes documentation or in the Profibus master API.

The table below describes the acyclic write request status value that might be returned by the driver.

wr_status-0Description
0No error. The Profibus slave is successfully receiving the acyclic message from the connected Profibus master.
0xC0380025An error occurred when sending an acyclic write request to the slave.
If Write request bErrorCode1 value is equal to 13, it means it is a user-defined error:
Then, if Write request bErrorCode2 value is 1, it means that the slave address is out of range. The correct range value for this is between 2 and 125.
If Write request bErrorCode2 value is 2, it means that the slot number is incorrect and the slave doesn't recognize it.
If Write request bErrorCode2 value is 3, it means that the index number is incorrect and is not found in the corresponding slot.
Or if Write request bErrorCode2 value is 4, it means that the length of the requested data is incorrect. The maximum data length is 240 bytes.

If Write request bErrorCode1 value is different from 13, this error is explained in section 5.3.2.2 of Profibus master API.
otherAny other status is returned directly from the CIFX card driver API. The hexadecimal value of this status must be used to find the corresponding description in the CIFX API documentation, CIFX error codes documentation or in the Profibus master API.

The table below describes the alarm acknowledge the status value that might be returned by the driver.

alarm_ack_statusDescription
0No error. The Profibus slave is successfully receiving the acyclic message from the connected Profibus master.
0xC0380025An error occurred when sending an alarm acknowledge request to the slave.
If Alarm ack bErrorCode1 value is 13, it means it is a user-defined error :
Then, if Alarm ack bErrorCode2 value is 1, it means that the slave address is out of range. The correct range value for this is between 2 and 125.

otherAny other status is returned directly from the CIFX card driver API. The hexadecimal value of this status must be used to find the corresponding description in the CIFX API documentation, CIFX error codes documentation or in the Profibus master API.

The Profibus DPV0 master example model shows how to perform the connections using 'OpInput' and 'OpOutput' blocks. It is located in the following directory:


YOUR_RT_LAB_INSTALLATION_FOLDER/Examples/IO/Profibus/Hilscher/Master/DPV0/simulink


You can also use the Profibus DPV1 master example model that is located in the following directory:


YOUR_RT_LAB_INSTALLATION_FOLDER/Examples/IO/Profibus/Hilscher/Master/DPV1/simulink


The example model is also accessible from the New Project wizard in RT-LAB. Select the Profibus_Master_DPV0 or Profibus_Master_DPV1 template under IO/Profibus/Hilscher/. Here is a screenshot of the master subsystem (DPV1) :

HYPERSIM Usage

The driver is not yet available in Hypersim but can be ported upon request.

Limitations

The current version of the Profibus master communication interface has the following limitations:

  • On 64bit platforms, enabling the XHP mode is not possible; if the driver is part of a model that requires XHP enabled, it is advised to group the OpInputs/OpOutputs used by Profibus master in a separate subsystem that will operate with XHP = off.
  • Number of boards: Only supports one Profibus board per target.
  • Offline mode: Driver does not work offline.
  • Platform: Driver can only be used on Linux (OPAL-RTLinux x86-based 32bit and OPAL-RTLinux x64-based 64bit platforms).
  • Data types: uint8, int8, uint16, int16, uint32, int32, uint64, int64, float, double. The boolean data type is actually represented on 8 bits and is transmitted as an int8. This is a limitation due to the configuration software SYCON.net
  • Maximum number of slaves supported: The Profibus master driver can only communicate with one slave at the moment.
  • Maximum cyclical transmission size: The driver can only send cyclically 244 bytes at once per slave.
  • Maximum cyclical reception size: The driver can only receive cyclically 244 bytes at once per slave.
  • Maximum number of acyclic read/write: The driver can only read/write acyclically 240 bytes at once per slave and telegram.
  • Maximum number of active alarms: The driver can only handle 32 alarms in total by the Profibus DP Master.
  • Configuration: the SYCON.net tool must be used to configure the driver.
  • Connectivity: only direct connection with a slave is supported for the moment.
  • Data transfer mode: cyclic and acyclic data transfer is supported in the current implementation.


OPAL-RT TECHNOLOGIES, Inc. | 1751, rue Richardson, bureau 1060 | Montréal, Québec Canada H3K 1G6 | opal-rt.com | +1 514-935-2323