92
Table of Contents 1 ARCHITECTURAL OVERVIEW.................................1 1.1 CODE Architecture...............................................2 1.2 Profibus Fieldbus Architecture..................................3 1.2.1 Profibus-DP Card............................................4 1.3 Introduction to WAGO I/O Modules................................4 1.4 CODE to Profibus Interface......................................6 1.5 User Procedures................................................10 1.5.1 Step 1 - Configure Profibus-DP Card........................10 1.5.2 Step 2 – Design and Develop CODE Signal Table..............12 1.5.3 Step 3 - Develop Client Control Processes..................12 1.5.4 Step 4 - Develop Customized Device Driver..................12 2 DRIVER FUNCTIONAL CAPABILITIES........................13 2.1 CODE Functional I/O Capabilities...............................13 2.2 Profibus Functional Capabilities...............................14 2.2.1 Profibus-DP Communication Modes............................14 2.2.2 Profibus-DP Functional I/O Capabilities and API Functions Supported.......................................................... 14 2.3 Matching CODE and Profibus-DP I/O Signal Tables................20 3 DEVICE DRIVER ORGANIZATION............................23 3.1 Software Organization..........................................23 3.1.1 Visual C++ Project Structure...............................23 3.1.2 Building a Custom Executable...............................24 3.2 Interface Organization.........................................24 3.2.1 Interface Procedures.......................................25 3.2.2 CODE user_cntrl.c Functions................................26 3.2.3 CODE Signal Table..........................................28 3.2.4 CODE Client process........................................32 3.2.5 Interrupt Device Driver....................................33 3.2.6 Device Driver Threading....................................34 4 IMPLEMENTATION TASKS..................................35

1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

  • Upload
    dangque

  • View
    218

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Table of Contents

1 ARCHITECTURAL OVERVIEW.....................................................................1

1.1 CODE Architecture.........................................................................................................................2

1.2 Profibus Fieldbus Architecture.......................................................................................................31.2.1 Profibus-DP Card.....................................................................................................................4

1.3 Introduction to WAGO I/O Modules.............................................................................................4

1.4 CODE to Profibus Interface............................................................................................................6

1.5 User Procedures.............................................................................................................................101.5.1 Step 1 - Configure Profibus-DP Card.....................................................................................101.5.2 Step 2 – Design and Develop CODE Signal Table................................................................121.5.3 Step 3 - Develop Client Control Processes.............................................................................121.5.4 Step 4 - Develop Customized Device Driver.........................................................................12

2 DRIVER FUNCTIONAL CAPABILITIES.....................................................13

2.1 CODE Functional I/O Capabilities..............................................................................................13

2.2 Profibus Functional Capabilities..................................................................................................142.2.1 Profibus-DP Communication Modes.....................................................................................142.2.2 Profibus-DP Functional I/O Capabilities and API Functions Supported...............................14

2.3 Matching CODE and Profibus-DP I/O Signal Tables................................................................20

3 DEVICE DRIVER ORGANIZATION.............................................................23

3.1 Software Organization...................................................................................................................233.1.1 Visual C++ Project Structure.................................................................................................233.1.2 Building a Custom Executable...............................................................................................24

3.2 Interface Organization..................................................................................................................243.2.1 Interface Procedures...............................................................................................................253.2.2 CODE user_cntrl.c Functions...............................................................................................263.2.3 CODE Signal Table................................................................................................................283.2.4 CODE Client process.............................................................................................................323.2.5 Interrupt Device Driver..........................................................................................................333.2.6 Device Driver Threading........................................................................................................34

4 IMPLEMENTATION TASKS........................................................................35

4.1 Header Files, Constants and Parameters.....................................................................................36

4.2 profibus_signal_drvr_func() Implementation.............................................................................39

4.3 profibus_signal_func() Implementation.......................................................................................414.3.1 profibus_signal_func Private Functions.................................................................................45

Page 2: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

4.3.1.1 Private Function: GetInputBit().........................................................................................454.3.1.2 Private Function: ReadGroupInput().................................................................................464.3.1.3 Private Function: ClearOutputBit()...................................................................................484.3.1.4 Private Function: SetOutputBit().......................................................................................504.3.1.5 Private Function: WriteGroupOutput()..............................................................................51

4.4 profibus_send_cmd() Implementation.........................................................................................54

4.5 Other Private Functions................................................................................................................58

4.6 Verification Tests...........................................................................................................................62

Page 3: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Figure 1.1 - System Topology

1 ARCHITECTURAL OVERVIEW

In this project CODE (Cimetrix Open Development Environment) is customized to integrate a Profibus-DP I/O card software device driver. CODE’s software architecture is designed to control distributed mechanisms and devices. This document provides specifications that will be implemented in the device driver and also reviews the system architecture.

Chapter 1 provides an architectural overview of the device driver interface to the Profibus-DP card. Chapter 2 describes which functional I/O capabilities are implemented on both the CODE and Profibus sides. Chapter 3 describes the PB driver implementation details, including how the project is organized in Visual C++ 4.2, the API (Application Programming Interface) functions that are implemented, and the necessary resources that are used, such as header files, constants, parameters, etc. Chapter 4 is dedicated to further defining the architecture, data structures, and pseudo-code that will be implemented in the driver. In addition, a set of tests will be defined to test the developed driver.

The card is provided by Synergetic - Model SMS-CIF30-DPM. The device driver acts as a software command interface between CODE and the DP card operating system (which runs independently on the DP card). By reading from and writing to dual-port memory (DPM) on the DP card, the device driver can configure, set, and get I/O values from various I/O devices which are distributed over the Profibus network. Since we are implementing the Profibus-DP I/O card only, these modules are primarily connected to sensors, valves, etc. The system topology is shown in Figure 1.1.

Profibus-DP Driver SpecDoc 05/09/23 1

Page 4: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

In Figure 1.1, the CODE system is customized to “attach” a Profibus-DP device driver to the CIMServer. Client control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific I/O using CODE I/O API (Application Programming Interface) library functions. Figure 1.1 shows two CODE API functions (CxGetSignal() and CxSetSignal()) commonly used in client processes for I/O data exchange. Once these functions are called, the client process redirects the data exchange request to the CODE CIMServer, which then passes the request through the device driver. The device driver then calls Profibus API functions to read from or write to the card DPM.

The Profibus API set is a set of C/C++ functions provided with the Synergetic DP card software that can be embedded into a user-customizable software interface provided with CIMServer. Once compiled and linked to make a customized CIMServer version, CODE client processes can directly communicate with the Profibus-DP card for I/O data exchange. The following sections provide more detail concerning the device driver organization.

1.1 CODE Architecture

CODE is an acronym that stands for the Cimetrix Open Development Environment. CODE consists of the following software products:

CIMulation - product that allows you to simulate and control manufacturing tasks using a graphical engineering workstation, such as a PC. It differs from CIMControl by providing an animated simulation of the workcell being controlled.

CIMControl - on-line counterpart to CIMulation. It allows the equipment in an automated workcell to be controlled using a standard PC.

CODE API Libraries - consists of approximately 400 functions, which can be used to develop automated manufacturing applications. Applications developed with these libraries will function in either CIMulation or CIMControl without modification. The API set is accessible in standard C/C++, Microsoft Visual C++, Microsoft Visual Basic, Borland Delphi, and through CIMBuilder-Tcl/Tk.

CIMTools - Software application that allows an automated workcell to be modeled and controlled. It provides interfaces for creating geometrical models, interference checking, motion monitoring, software teach pendant, application project control, cycle time prediction, and I/O signal panel.

CODE software is based on client-server architecture – see Figure 1.1. CIMServer is CODE’s central server control program. Each CODE client program is organized as a set of function calls to monitor and control simulated or actual physical processes. These may range from the control of mechanisms, vision systems, or distributed I/O. Each client function call encapsulates its data (send data or request data) into message packets that communicate with CIMServer using Inter-Process Communication (IPC) methods.

Profibus-DP Driver SpecDoc 05/09/23 2

Page 5: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Figure 1.2 - Profibus application areas

CIMServer’s open architecture provides software "hooks" whereby users can integrate custom software interfaces to mechanism and I/O controllers. The user-modifiable interface that can be customized for mechanism control and I/O is included in a project workspace file. This software interface will be described in full detail later.

1.2 Profibus Fieldbus Architecture

The purpose of this document is to help the user understand the development process of creating a device driver for an I/O interface card of type Profibus-DP, manufactured by Hilscher Ggesellschaft fur Systemautomation mbH.

Profibus is one of the new generations of fieldbus I/O bus networks. Fieldbus is a generic term that describes a new digital communications network that is being used in industry to replace the existing 4-20 mA analog signal standard. The network is a digital, bi-directional, multidrop, serial-bus communication network used to link isolated field devices, such as controllers, transducers, actuators and sensors. Bi-directional means it is a duplex port; the data can be transmitted in two directions at the same time. Multidrop is also referred to as multi-access and it can be interpreted as a single bus with many nodes connected to it. Serial-bus means the data is transmitted serially according to RS232 or RS485 protocol. Profibus uses RS485 protocol.

The fieldbus has a multitude of advantages that end-users will benefit from. The major advantage is that it is a bus network and not a star network, which will reduce both configuration time and maintenance. It also improves systems performance, since fieldbus networks perform at higher baud rates.

Profibus is a vendor-independent, open fieldbus standard for a wide range of applications in manufacturing, and process automation. Devices configured by different

Profibus-DP Driver SpecDoc 05/09/23 3

Page 6: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

manufacturers can communicate without special interface adjustments. Profibus can be used for both high-speed, time-critical data transmission and extensive complex communication tasks - see Figure 1.2. The Profibus family consists of three compatible versions: Profibus-DP, Profibus-PA and Profibus-FMS.

Profibus-DP - Optimized for high speed and inexpensive hookup. DP version is designed especially for communication between automation control systems and distributed I/O at the device level. Can be used to replace parallel signal transmission with 24 V or 0 to 20 mA. This is the only card that will be supported in this specification document.

Profibus-PA - Designed especially for process automation. It permits sensors and actuators to be connected on one common bus line even in intrinsically safe areas. Permits data communication and power over the bus using 2-wire technology according to the international standard IEC 1158-2. Will not be implemented in this spec because only I/O will be controlled.

Profibus-FMS - General-purpose solution for communication tasks at the cell level. Powerful FMS services open up a wide range of applications and provide great flexibility. Can also be used for extensive and complex communication tasks. Will not be implemented in this spec because CODE provides much of the same function.

1.2.1 Profibus-DP Card Profibus-DP is designed for high-speed data communication at the device level. The main purpose of this project is to provide reliable high-speed communication between the CODE system and I/O modules. Profibus DP meets these objectives, so the device driver is developed only for the Profibus-DP card. The DP API function overview is given in Section 1.4.

1.3 Introduction to WAGO I/O Modules

The I/O modules used in this project are the products of WAGO Electronics. Figure 1.3 shows a simple Wago I/O module connecting two proximity sensors. Wago modules are intelligent, fieldbus-independent terminal blocks designed for the decentralized automation of manufacturing and production equipment.

Figure 1.4 shows a 2-channel digital input module. The digital input module receives signals from digital field devices (sensors, etc). The physical connection of the WAGO module is simple as shown in Figures 1.3 and 1.4. The middle two wires are for the sensor power supply. The other two wires are signal input/output and signal ground.

The fieldbus coupler for Profibus-DP connects the WAGO I/O modules as a slave to the Profibus-DP card – see Figure 1.5. The bus coupler is capable of supporting all bus modules and automatically transfers the data to/from mixed I/O modules to the process image.

Profibus-DP Driver SpecDoc 05/09/23 4

Page 7: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Figure 1.3 - 2-channel modularity

Figure 1.4 - Two-channel digital input module

Profibus-DP Driver SpecDoc 05/09/23 5

Page 8: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Figure 1.5 Fieldbus coupler for Profibus DP

1.4 CODE to Profibus Interface

Control processes developed under the architecture of Figure 1.1 require the development of client process applications, which interact with the CODE server. The server processes the messages and requests from the client process. The Profibus-DP environment provides a set of API functions that are integrated into the compiled device driver that provide for the communication with the Profibus –DP card. These API functions allow for direct access to the card function. They are responsible for initializing and configuring the card, as well as the writing and reading of data to the I/O modules (setting and getting individual I/O bits/bytes).

The CODE I/O interface has been implemented using CODE’s open architecture interface for implementing custom device drivers. To see how CODE communicates with the Profibus-DP card, review the basic flow chart in Figure 1.6 and the following brief description bullets:

CODE client control processes are application programs developed by the user. When these processes are executed (run), I/O functions will be called to set/get signal values. Some of these signals may be software signals used for coordinating several client processes and some may be hardware signals which are be directed to the WAGO I/O modules. The CIMServer controls the communication to these processes and provides the interpretation services for the client processes.

Profibus-DP Driver SpecDoc 05/09/23 6

Page 9: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Figure 1.6 - Flow chart of CODE to Profibus DP interface

The user customizes the device-driver by modifying the user_cntrl.c software interface provided by CODE. A customized CIMServer is made when the custom software interface is compiled and linked. This device driver then establishes the interface between the client processes and the Profibus-DP card.

A set of C/C++ API functions comes with the Profibus-DP card, providing the functionality necessary to initialize and monitor the card and to exchange data through the dual-port memory (DPM) on the card.

The DP card uses an embedded, real-time operating systems to cyclically scan the I/O modules, read the DPM, and write to the DPM. Thus, the device driver purpose is to write to these memory addresses and read from these memory addresses. There is some

Profibus-DP Driver SpecDoc 05/09/23 7

Page 10: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

configuration initialization required, both for the DP card and for the CODE signal table. These will be described in greater detail later.

The Profibus API’s are defined in a source file that came with the DP card, called interface.cpp. This file contains function definitions. Table 1.1 classifies these functions; some support the PA and FMS function and will not be implemented in this device driver.

Table 1.1 – Profibus DP API Functions

Profibus API’s Function

DevOpenDriver() Implemented – check if the board device driver is available and opens a link to it.

DevInitBoard() Implemented – used for board initialization.

DevCloseDriver Implemented –application calls this function to close an opened link to card device driver.

DevExitBoard() Implemented – to end the communication, the application program calls this function for each board opened previously by DevInitBoard().

DevExchangeIO() Implemented – used for data I/O exchange.

DevSetHostState() Implemented – used to signal card that CODE application is not running.

DevGetInfo() Implemented – used to access board parameters and state in one large request.

DevPutMessage() Not implemented – used for PA and FMS capabilities; not implemented in this driver.

DevGetMessage() Not implemented – used for PA and FMS capabilities; not implemented in this driver.

DevGetBoardInfo() Not implemented – used to get board information such as IRQ number, physical memory address. This information can be requested in CODE client process using the send command capabilities.

DevReadSendData() Not implemented – used to read back data which has been set to the card using DevExchangeIO(). It can be used to verify that data has been written correctly and also used to

Profibus-DP Driver SpecDoc 05/09/23 8

Page 11: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

detect errors on the Profibus card.

DevReset() Not implemented – resets the communication board when called.

DevPutTaskParameter() Not implemented – used for PA and FMS capabilities; not implemented in this driver.

DevGetTaskState() Not implemented – used for PA and FMS capabilities; not implemented in this driver.

DevTriggerWatchDog() Not implemented – not using a watchdog timer in device driver.

DevGetMBXState() Not implemented – used for PA and FMS capabilities; not implemented in this driver.

The CODE signal table is a user-defined file. It has specific formats and it contains the detailed data configuration for each signal that will be used in the CODE system, and then translated to the correct DP format. A signal is valid only after it is defined. Once the server locates the signal type in the signal table, it will determine if the signal is an external (hardware) I/O signal. If so, the CODE server will redirect the message data from the client process to the Profibus-DP card through the device driver. The driver is developed to manage the communications between the Profibus-DP card and the I/O modules and is based on two API function sets: CODE API’s and Profibus-DP API’s.

The way the card is configured is straightforward. The card scans the bus network and thus reads the input and writes the output on I/O devices connected to the network, in this case the WAGO modules. Since the DPM read and write is in the scanning loop, the card operating system (OS) will read the DPM or write to the DPM the current I/O state. The CODE device driver determines the current signal state by using DevExchangeIO(), a Profibus-DP API function provided with the Profibus-DP card. DevExchangeIO() is compiled into the device driver that forms the customized CIMServer, and then is used to write I/O to the card DPM and read I/O from the card DPM.

The I/O devices/modules are assigned addresses at specified offsets from the base address of the card. For example, the base address of a card might be set to 000H (H stands for hexadecimal format), which becomes the beginning address for the 512 bytes of DPM that stores the data sent from the CODE application to the Profibus-DP card – see Figure 1.7.

Although an I/O module typically provides for either 2 or 4 bit access at a particular offset location, we will implement 8 bit (1 byte) offsets to simplify the device driver architecture. There are 512 bytes for output data, where SndPd refers to the space reserved for Send Process Data, which is the output data sent from the host application to the Profibus-DP card. Figure 1.7 also shows that in the 2K Profibus-DP DPM, there are 512 bytes reserved for input data, where RecvPd refers to Receive Process Data, which is the input data sent from the

Profibus-DP Driver SpecDoc 05/09/23 9

Page 12: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Profibus-DP card to the host application. Using 1 byte offsets, there is enough memory for 512 inputs and 512 outputs, if only single byte I/O is used.

1.5 User Procedures

There are four individually defined steps that will link a Profibus DP card to a CODE process application:

Step 1 - Configure Profibus DP card

Step 2 – Design and develop CODE signal table.

Step 3 - Develop client control processes.

Step 4 - Develop customized device driver to link CODE and the Profibus DP card.

1.5.1 Step 1 - Configure Profibus-DP CardThis step is accomplished by using a system configurator that comes with the Profibus card. The user adds master and slave modules using an add-device option. The master module is one or more Profibus-DP cards, while the slave devices are the Wago fieldbus coupler modules (WAGO I/O SYSTEM DP/FMS – 750-303) which can be interfaced to A/D and I/O modular devices. Other options enable the user to select the type of the device and the number of each device that is needed.

Other options enable the user to select the device type and the number of each device that is needed. Devices can be configured for 8, 16, 24, and up to 128 bits input or output when the I/O requires more complex data exchange. Our application requires simple 2 and 4 bit modules (which will be mapped to 1 byte or 2 byte address space). We will also use some analog modules (requiring 4 bytes) for RS232 communications.

The modules can be selected from a list by the user double clicking on a slave symbol (such as WAGO I/O SYSTEM DP/FMS 12MBaud) and then selecting the Configuration data button. Individual modules are added to the device list by selecting the module and next clicking on the Add module button. The I Addr column is where the input modules (RECEIVE Data) are assigned memory locations. The O Addr column is where the output modules (SEND Data) are assigned memory locations.

The Profibus configuration file defines the memory assignment for each physical I/O module. Similarly, the physical signals are also described in the CODE signal table. Obviously, the memory assignment in the configuration file must be compatible with the corresponding signal definition in the CODE signal table.

Profibus-DP Driver SpecDoc 05/09/23 10

Page 13: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

The CODE signal table contains fields that are used by the user to match the offsets specified in the Profibus configurator tables. As an example, Figure 1.8 shows the InBase and OutBase fields used to specify the address offsets in the CODE signal table for simple single bit input and output signals. In the Profibus configurator the A/D modules that require 4 bytes each (or 2 words as shown in the table) must be ordered first, followed by simple I/O modules. The field ”Type” has the value -1 for simple digital I/O and a value equal to the A/D module number of a Wago interface module when an analog module such as 75060 is used for RS232 interfacing. Fields 6 – 10 are not used in the CODE signal table.

There are constraints on the way the memory is configured. The first part of memory is reserved for analog I/O followed by digital I/O. Each WAGO I/O module uses a certain number of bits, regardless of whether each bit is physically wired to a terminal. The number of bits varies for each module type.

Profibus-DP Driver SpecDoc 05/09/23 11

################################ input signals from sensors ################################

Logical signal name: SENSOR_1_ONinput output use_init init_value1 0 0 0InBase OutBase Type IOnum Width field6 field7 field8 field9 field10

16 -1 -1 1 1 0 0 0 0 0

Logical signal name: SENSOR_2_ONinput output use_init init_value1 0 0 0InBase OutBase Type IOnum Width field6 field7 field8 field9 field10

16 -1 -1 2 1 0 0 0 0 0

################################ output signals to modules ################################

Logical signal name: OPEN_GRIPPERinput output use_init init_value0 1 1 1InBase OutBase Type IOnum Width field6 field7 field8 field9 field10

-1 16 -1 1 1 0 0 0 0 0

Logical signal name: VALVE_1_OPENinput output use_init init_value0 1 1 1InBase OutBase Type IOnum Width field6 field7 field8 field9 field10

-1 18 -1 2 1 0 0 0 0 0

Figure 1.8 – Mapping CODE Signal Table I/O to Profibus Configurator

Page 14: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Additional system parameters need to be set as described in the system configuration manual. Once the configuration setup is completed, the configuration is downloaded to the card where it can be debugged and tested.

1.5.2 Step 2 – Design and Develop CODE Signal TableThe CODE signal table represents the logical mapping of CODE process control signals to the physical I/O module hardware signals processed by the Profibus-DP card. These signals are actually individual bits that are turned on and off as the Profibus operating system scans the I/O modules and the DPM. Of significance are the send process data and receive process data memory areas, each of which is 512 bytes. The signals defined in the signal table are assigned to specific offset locations within the dual port memory (DPM), which in turn represent individual bits on the I/O modules. The signal table also identifies if the signal is input and/or output, if the signal is to be initialized by the server, how the specific data relates to the hardware configuration, etc.

1.5.3 Step 3 - Develop Client Control ProcessesTo control the numerous workcell devices, including the cell I/O, the user must develop source code client programs (client processes) that implement CODE API function calls. These control programs are developed under Visual C++, Version 4.2. The source code includes I/O events, mechanism motion functions, and other control functions as described in Volume 1 of the CODE documentation in Events, States and I/O.

After the client programs have been developed, compiled and linked, each client program (also referred to as a client process) can be started and then connected to a CODE server that is also running concurrently. After connecting to the server, the clients can then exchange control commands in the form of data packets with the server. The server processes I/O messages through the Profibus device driver interface, which uses the supplied Profibus-DP API functions to read from and write to the DP card DPM.

1.5.4 Step 4 - Develop Customized Device DriverOnce the device driver is completed, the user will not need to apply this step again. It will only be necessary to configure the CODE signal table and the Profibus DP card consistently. The purpose of this document is to develop and document such a device driver for the Profibus-DP I/O card.

Profibus-DP Driver SpecDoc 05/09/23 12

Page 15: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

2 DRIVER FUNCTIONAL CAPABILITIES

These sections are used to describe which functional I/O capabilities are implemented on both the CODE and Profibus sides, and also to specify which I/O capabilities are not supported and why.

2.1 CODE Functional I/O Capabilities

This section describes which CODE functional I/O capabilities are implemented and also specify which are not supported and why.

Table 2.1 lists the CODE I/O cases that will be supported by the Profibus-DP driver. These cases are passed as a constant (long) argument through a CODE interface function call in the device driver. These values are also defined by the constant names shown in the left column of the table. The specific signal data information is passed through data structures in these same interface functions and will be discussed in later sections.

Table 2.2 lists the cases that will not be supported. Although the Profibus-DP card is not set up to monitor signals and provide interrupts, we will implement signal monitoring by internal polling.

Table 2.1 – CODE I/O Cases Supported

Cases Supported Explanation

CX_CNTRL_OPEN_SIGNAL_TABLE Used to initialize the signal table on an I/O controller, the Profibus DP card in this case (set signal values in DPM).

CX_CNTRL_CLOSE_SIGNAL_TABLE Used to close the connection to a signal table on an I/O controller, the Profibus DP card in this case.

CX_CNTRL_INITIALIZE_SIGNAL Used to initialize the state of a hardware signal in the Profibus card signal table (set or write a signal value in DPM).

CX_CNTRL_GET_SIGNAL_VALUE Used to get the value of a hardware signal from the Profibus card signal table (read DPM to get a signal value).

CX_CNTRL_SET_SIGNAL_VALUE Used to set the value of a hardware signal in the Profibus card signal table (set or write a signal value in DPM).

Profibus-DP Driver SpecDoc 05/09/23 13

Page 16: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Table 2.2 – CODE I/O Cases Not Supported

Cases not Supported Explanation

CX_CNTRL_SETUP_SIGNAL_MONITORING Not implemented - Defines how a controller or I/O card will monitor the state of a given signal, and how the I/O card will return the state when the signal changes value. Will use the polling mode for signal monitoring..

CX_CNTRL_MONITOR_SIGNALS Not implemented - CIMServer’s polling mode will be used since the Profibus driver software cannot provide an interrupt upon a signal attaining a certain value.

CX_CNTRL_GET_SIGNAL_CNTRL Not implemented - Used to get specific I/O information that is implemented by the Profibus-DP card, but not implemented in CODE. Uses a CODE pass-through data structure to pass card-specific information through to the client process.

CX_CNTRL_SET_LATCH Not implemented since Profibus-DP card does not support latching of joint encoder values.

2.2 Profibus Functional Capabilities

The following sub-sections describe the supported communication mode with the Profibus-DP card, and the I/O capabilities and API functions that will be implemented.

2.2.1 Profibus-DP Communication ModesProfibus-DP supports five communication modes for exchanging data between a host application (CODE client process) and the interface modules (WAGO) that are networked (linked) to the RS485 bus network. The four not implemented are identified in Table 2.3. We will support the user controlled, buffered data transfer communication mode. This mode allows the user application to directly control the data exchange by implementing a corresponding Profibus DP API function and by using a locally defined data buffer. In addition, the user can use event objects to synchronize the communication process when writer and reader threads are executing concurrently. This mode permits the CIMServer to communicate with the CIF card when requested by a CODE client process, rather than have the card assume control. We will not support the other four modes for the reasons listed in Table 2.3.

2.2.2 Profibus-DP Functional I/O Capabilities and API Functions SupportedThe Profibus card is supported by a set of API functions that ease the burden of communicating with the board, and assist in data exchange. Some of these functions are not applicable for Profibus-DP data exchange and will not be implemented – see Table 1.1.

The implemented functions are defined in interface.cpp (source code for the Profibus-DP driver) and listed in Table 2.4. Table 2.5 describes some functions that will probably be

Profibus-DP Driver SpecDoc 05/09/23 14

Page 17: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

implemented in the future. The Profibus card has the capability to support interrupt communications by properly setting the board IRQ. The setting of the IRQ for the board is achieved through editing of the configuration data for the board done in the registry (i.e., setting of the base address and the interrupt request for each board).

Table 2.3 –Communication Modes not Implemented

Communication Modes Explanation

Bus synchronous, device controlled communication with a process image

In this mode the CIF card starts a data exchange cycle by itself if it is master or receives a data exchange cycle if it is slave. In each valid bus cycle the device exchanges data with the DPM. The end of the data exchange is indicated when the operating system on the CIF card inverts a bit in a memory cell. In response to an interrupt, the user program complements a bit in a different memory cell. When these handshake bits are not equal at the end of each bus cycle (CIMServer device driver interface to Profibus-DP card), the CIF card grants access to both DPM data buffers, allowing reading of input data or writing of output data to the DPM. In the next bus cycle the CIMServer device driver must perform a data-exchange cycle and invert a bit in a memory cell, so both handshaking bits from the communication memory cells are equal.

In this mode the CIF controls the communication and the user application (device driver) must be able to handle the handshake in interrupt and not in polling mode. We have decide to let CIMServer assume on-demand communication control rather than the card.

CIF controlled, buffered data transfer

This mode is similar to the previous mode except internal buffers are used to store the DPM data in the DPM in bus cycle. Again, we choose to have CIMServer control the I/O process.

Uncontrolled direct data transfer In this mode the user application (CIMServer device driver) and the Profibus-DP operating system all read and write to the DPM simultaneously. Since there is no synchronization capability, this mode is not implemented.

User controlled, direct data transfer bus synchronous

The start point of each bus cycle is fixed by the user application. After the initialization of both buffer areas (send and receive process data areas), the user application starts each bus cycle by inverting a bit in a memory cell and obtaining access to the DPM. It then sets another bit to relinquish control back to the CIF card. This mode guarantees the fastest exchange of process data, because a bus cycle is activated after each data delivery in the DPM by the user application. So the faster the user application works, the faster the bus cycles are triggered.

This mode requires user control over the timing of the bus cycle. The input/output data needs to be processed continuously with low-level bit-wise manipulation capabilities. Therefore, it will not be implemented.

Profibus-DP Driver SpecDoc 05/09/23 15

Page 18: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Table 2.4 – Profibus API Implemented Functions

Implemented PB Functions Description

short DevOpenDriver(unsigned short usDevNumber )

This function must be called first. It checks if the device driver is available and opens a link to it. Once this link is established, all other functions can be used. usDevNumber represents the board number 0,..,3. This function is designed for interrupt mode.

Function arguments:

usDevNumber – board number 0,..,3

Return Values:

DRV_NO_ERROR - No error occurred, device driver is available.DRV_USR_OPEN_ERROR - Device driver is not available.

short DevInitBoard(unsigned short usDevNumber, void pDevAddress )

After an application has opened a link to the device driver, it must call that function, before it can start with the communication. The function tells the device driver that an application wants to communicate with a defined board. The device driver checks to see if the board is physically available, if the board works properly and setup all the internal state flags for the addressed board. pDevAddress is a pointer to the physical board address.

Function arguments:

usDevNumber – board number 0,..,3

pDevAddress – pointer to the board’s address

Return Values:

DRV_NO_ERROR - no error occurred, device driver is available.DRV_USR_NOT_INITIALIZED - device driver is not available.DRV_USR_DEV_NUMBER_INVALID - board number is not allowed and miscellaneous driver errors - see error description.

short DevCloseDriver(unsigned short usDevNumber )

The application (CODE device driver interface) calls this function to close an opened link to a card device driver. The function is designed for interrupt mode where multiple cards are present.

Function arguments:

usDevNumber – board number 0,..,3

Return Values:

DRV_NO_ERROR - no error occurred, device driver is available.DRV_USR_OPEN_ERROR - device driver is not available.

short DevExitBoard(If an application wants to end communication it calls DevExitBoard() for each board which has been opened by a

Profibus-DP Driver SpecDoc 05/09/23 16

Page 19: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

unsigned short usDevNumber ) previous call to DevInitBoard().

Function arguments:

usDevNumber – board number 0,..,3

Return Values:

DRV_NO_ERROR - no error occurred, device driver is available.DRV_USR_NOT_INITIALIZED - device driver is not available.DRV_USR_DEV_NUMBER_INVALID - board number is not allowed and miscellaneous driver errors: See chapter error numbers.

short DevSetHostState(unsigned short usDevNumber,unsigned short usMode,unsigned long ulTimeout )

Used to signal the DP board that a user application is running or not.

Function arguments:

usDevNumber – board number 0,..,3

usMode – 0 – HOST_NOT_READY 1 – HOST_READY

usTimeout – timeout in milliseconds

Return Values:

DRV_NO_ERROR - no error occurred, device driver is available.DRV_USR_NOT_INITIALIZED - device driver is not available.DRV_USR_DEV_NUMBER_INVALID - board number is not allowed and miscellaneous driver errors: See chapter error numbers.DRV_USR_MODE_INVALID – mode parameter not allowed.

short DevExchangeIO(unsigned short usDevNumber, unsigned short usSendOffset, unsigned short usSendSize,void *pvSendData,unsigned short usReceiveOffset, unsigned short usReceiveSize,void *pvReceiveData,unsigned long ulTimeout )

DevExchangeIO() function is used to send IO data to and read IO data from a communication board. The function is able to send and read IO data at once. If one of the size parameter is set to zero, no action will be taken for the corresponding function. This means, if usSendSize is set to zero, send data will not be written to the board ( the data will not be written to the 512- byte memory space – send process data, SndPd ). If usReceiveSize is set to zero, receive data will not be read from the board. The input data from the bus will not be written to the 512-byte memory space – receive process data, RecvPd.

Function arguments:

usDevNumber – board number 0..3

usSendOffset – byte offset in the send IO data area of the communication board

usSendSize – length of the send IO data

pvSendData - pointer to the user send data buffer

usReceiveOffset – byte offset in ther receive IO data area of the communication board

Profibus-DP Driver SpecDoc 05/09/23 17

Page 20: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

usReceiveSize – length of the received IO data

pvReceiveData – pointer to the user read data buffer

ulTimeout – timeout in milliseconds, 0=no timeout

Return Values:

DRV_NO_ERROR - No error occurred, device driver is available.DRV_USR_NOT_INITIALIZED - device driver is not available.DRV_USR_DEV_NUMBER_INVALID – invalid board number.DRV_USR_SENDBUF_PTR_NULL - pointer to buffer is a null pointer.DRV_USR_RECVBUF_PTR_NULL - pointer to buffer is a null pointer.DRV_USR_SENDSIZE_TOO_LONG - SendSize parameter too long.DRV_USR_RECVSIZE_TOO_LONG - ReceiveSize parameter too long or miscellaneous driver error.

short DevGetInfo(unsigned short usDevNumber, unsigned short usSize,void* pvData)

With DevGetInfo() function the user can read the DPM by information area. The area of interest here is GET_IO_SEND_DATA.

Function arguments:

usDevNumber – board number 0..3

usInfoArea – information area specified by a logical name

usSize – size of the user’s data buffer and length of data to be read

pvData – pointer to the user’s data buffer

Return Values:

DRV_NO_ERROR - no error occurred, device driver is available. DRV_USR_INFO_AREA_INVALID – Parameter InfoArea invalidDRV_USR_NOT_INITIALIZED - device driver not available.DRV_USR_MSG_BUF_NULL_PTR - pointer to the user’s data buffer is a NULL pointer.DRV_USR_SIZE_TOO_LONG - size of user data buffer exceeds 512 K

Table 2.5 – Profibus API Functions for Future Implementation

Future Implemention Description

short DevGetBoardInfo(unsigned short usDevNumber, unsigned short usSize,void* pvData)

With DevGetBoardInfo() function the user can read global information of all communication boards that the device driver is aware of. The user interface offers to the user a data structure, which describes the board information data. The function copies the

Profibus-DP Driver SpecDoc 05/09/23 18

Page 21: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

number of data, given in the parameter usSize.

Function arguments:

usDevNumber – board number 0..3

usSize – size of the user’s data buffer and length of data to be read

pvData – pointer to the user’s data buffer

Return Values:

DRV_NO_ERROR - no error occurred, device driver is available.DRV_USR_NOT_INITIALIZED - device driver not available.DRV_USR_MSG_BUF_NULL_PTR - pointer to the user’s data buffer is a NULL pointer.DRV_USR_SIZE_INVALID - size of user data buffer does not correspond to the expected size or miscellaneous driver error.

short DevReset(unsigned short usDevNumber, unsigned short usMode, unsigned long ulTimeout)

The function causes a reset of a communication board. The function argument usMode toggles the reset between a COLDSTART or WARMSTART. The amount of the timeout ulTimeout depends on the protocol and reset mode. A COLDSTART needs a longer time than a WARMSTART, because a complete hardware check will be made by the device operating system. The time for a COLDSTART is between 3 and 10 seconds, a WARMSTART needs between 2 and 8 seconds. The reset of the board will occur whenever there is a malfunction in the system’s I/O. The bit statuses on the WAGO modules will be initialized after reset with signal values obtained from the process’s signal table.

Function arguments:

UsDevNumber – board number 0..3

usMode – 2 = COLDSTART, 3 = WARMSTART

ulTimeout – timeout value for the reset to complete

Return Values:

DRV_NO_ERROR - no error occurred, device driver is available.DRV_USR_NOT_INITIALIZED - device driver is not available.DRV_USR_DEV_NUMBER_INVALID – invalid board number.DRV_USR_MODE_INVALID – invalid mode parameter or miscellaneous driver error.

short DevReadSendData(unsigned short usDevNumber, unsigned short usOffset,unsigned short usSize,void* pvSendData)

Function is used for verification and validation of the data which are written to the send data area with the function DevExchangeIO(). It reads back the sent data in order to perform the verification. The function can be used by the application program to update the user input, after the data are successfully written to the communication board.

Profibus-DP Driver SpecDoc 05/09/23 19

Page 22: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Figure 2.1 – Mapping of Physical I/O to DPM

Function arguments:

usDevNumber – board number 0..3

usOffset – byte offset in the send I/O data area of the communication board

usSize – length of the send I/O data to be read.

pvData – pointer to the user data buffer.

Return Values:

DRV_NO_ERROR - no error occurred, device driver is available.DRV_USR_NOT_INITIALIZED - device driver not available.DRV_USR_DEV_NUMBER_INVALID – invalid board number.DRV_USR_BUF_PTR_NULL – pointer to buffer NULL pointerDRV_USR_SIZE_TOO_LONG – SendSize parameter too long or miscellaneous driver error.

2.3 Matching CODE and Profibus-DP I/O Signal Tables

The DPM on the Profibus-DP card is configured initially to support a library of I/O devices. The selection of I/O modules that are being implemented in the current I/O configuration is done using system configurator software. By double clicking on the added I/O slave device and selecting the configuration data button, the user can add a number of input and/or output modules which can extend over an address space of from 8 bits to 128 bits relative to an address offset. These offsets are specified for both the input signals and the output signals and represent a memory offset relative to the base addressof the DPM. The physical hardware signals are then mapped into these addresses.

Since the configurator only permits the specifying of relative address space of 8 bits to 128 bits, 2 and 4-bit hardware I/O modules must fit within the relative address space specified in the configurator table. Figure 2.1 shows how a 4-bit input module and two 2-bit modules would be configured at an offset (I Addr) of 16B (B for bytes), when a length

of 8 bits is specified in the configurator, Figure 2.2.

Profibus-DP Driver SpecDoc 05/09/23 20

Page 23: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Figure 2.1 shows how the 8 physical input bits map to the memory address bits in the PB DPM. Figure 2.2 shows an excerpt of the CODE signal table in which three input signals (GRIPPER_ATTACHED, PART_HERE, PART_GONE) map to the first three hardware bits of the 4-bit hardware module.

In this case, byte 17 is not used. The Type is specified as W for word (2 bytes) or as B for byte. IW stands for input word type and QW stands for output word type, with similar notation for input and output byte type. The 4B A/D modules shown in the configurator are not shown in the CODE signal table excerpt.

Each hardware signal defined in the signal table contains fields that access hardware bits in the current I/O configuration. The DPM locations are specified at offsets and at relative bits within the signal table file as defined in Table 2.6.

Profibus-DP Driver SpecDoc 05/09/23 21

################################ output signals to modules ################################

Logical signal name: GRIPPER_ATTACHEDinput output use_init init_value1 0 0 0InBase OutBase Type IOnum Width field6 field7 field8 field9 field10

-1 16 -1 1 1 0 0 0 0 0

Logical signal name: PART_HEREinput output use_init init_value1 0 0 0InBase OutBase Type IOnum Width field6 field7 field8 field9 field10

-1 16 -1 2 1 0 0 0 0 0

Logical signal name: PART_GONEinput output use_init init_value1 0 0 0InBase OutBase Type IOnum Width field6 field7 field8 field9 field10

-1 16 -1 3 1 0 0 0 0 0

Figure 2.2 – Mapping CODE Signal Table I/O to Profibus Configurator

Page 24: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Table 2.6 – Relationship between CODE Signal Table and Profibus Configurator

Signal Table Field Definitions Description/Relation to Profibus Signals

use_init Indicates whether or not CIMServer will initialize a hardware output signal to the value specified in the adjacent field:

0 = CIMServer does not initialize the value,1 = CIMServer initializes the hardware signal with the value specified in the adjacent field.

Initialization takes place through a Profibus API function to write the initial value to the I/O modules which are configured to match the defined hardware signal.

init_value Represents the integer value which will be written to the I/O modules configured in PB-DP to match the defined CODE hardware signal. This value must not exceed what is possible by the number of bits specified for the signal (see Width).

InBase Field 1 - This field represents the DPM base address for an input signal. IOnum and Width are then used to move to the correct bits assigned to the signal.

OutBase Field 2 - This field represents the DPM base address for an output signal. IOnum and Width are then used to move to the correct bits assigned to the signal.

Type Field 3 – This field will have a –1 value if simple I/O, but will have a value of 750650 if analog signal used for RS232 communications.

IOnum Field 4 – Represents the offset I/O location for simple I/O relative to the base address. Will have value of –1 if analog I/O of Type 750650.

Width Field 5 - This field specifies the number of bits allocated to this signal. For example, if 4 bits are specified, the signal value must not exceed 24 = 16.

Fields 6 -10 Not used

Profibus-DP Driver SpecDoc 05/09/23 22

Page 25: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Table 3.1 – Project Workspace

cimcont.rcPB_DP.cppsoftware_drvr.cthreadmain.cuser_cntrl.cuser_kin.cuser_motion.c

3 DEVICE DRIVER ORGANIZATION

These sections describe the details of the PB driver implementation, how the project is organized in Visual C++ 4.2, the functions that are implemented, the necessary resources that are used, header files, constants, parameters, etc.

3.1 Software Organization

This section identifies the project organization and resources used.

3.1.1 Visual C++ Project StructureVisual C++ 4.2 is the basic development environment used to create client processes. A customized version of CIMServer will be created that provides a software interface to the Profibus-DP I/O card. CODE supports compatibility with this version of Visual C++ and with Microsoft Developer’s Studio. The main project workspace is CIMControl (runtime control version). Adding software function that supports device drivers for different controllers expands this project workspace. In this particular case we reconfigure the project workspace by linking the file CIFNTDLL.LIB provided with the Profibus-DP card into the project workspace. In addition, the dynamic link library CIFNTDLL.DLL must be placed in a path where the application can reach it.

The files in Table 3.1, including the one Profibus-DP source file developed by the user under the name profibus.cpp, now represent the total project workspace. Once compiled and linked, the new custom CIMControl (or CIMulation if the user wishes to see screen animation of the cell) executable will include the code sufficient to read/write I/O to the Profibus-DP card.

The include files and header files are located in the folder Dependencies and are shown in Table 3.2. A number of these include header files related to other device drivers, and one provided with the Profibus card, CIFUSER.H

Table 3.2 - Include and Header Files

autodh.hbasic_msg_const.hbasic_msg_defs.hCIFUSER.Hcimulation.icocntr_const.hconst.herror.hfb_const.hforce_traj.hfwrdkin.hinvkin.h

matx_defs.h motion.h msg_defs.h msg_types.hOacErrno.hprofibus.hProfibusErrors.hrob_globs.hrob_to_ac28.hrob_todt2815.hrob_to_dt2821.hrob_to_ibs.h

rob_to_pcm.h rob_to_pdx.h rob_to_pmac.hrob_to_yscxm.h robconst.hroberrno.hrobot.hrobsignal.hrobstruct.hRobToOac.hs_func.hSendStruct.hserver.h

tree_node.h TYPES.Huser_cntrl.huser_defs.huser_kin.CKuser_kin.FKuser_kin.IKuser_kin.NKuser_kin_funcs.huser_motion.AJuser_motion.FGuser_motion.h

Profibus-DP Driver SpecDoc 05/09/23 23

Page 26: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

ipc.hipc_io.hjoint.hmatrix.h

rob_to_icb104.hrob_to_ipc.hrob_to_mx100.hrob_to_pcl722.h

sigcalls.hsoftware_drvr.hstarttree.htnt.h

user_motion.JAuser_motion.JMuser_motion.VT

3.1.2 Building a Custom ExecutableTo build an initial executable CIMControl (or CIMulation), the user needs to perform the following steps. The character sequence Option1 Option2 refers to selecting from the menu Option1 to get Option2. Option1 Option2 Option3 refers to a multiple selection sequence.

Step 1 - Select File Open Workspace cimcontrol.mak or cimulation.mak to choose the appropriate make file. The make file automatically creates and opens a workspace, establishes initial dependencies, etc.

Step 2 - When new drivers are added to the server, if there are any #include statements in the *.cpp or *.c files added to the project, the user must select Build Update All Dependencies to automatically update the include dependencies.

Step 3 - In addition, the user must select Tool Options Directories so that the user can specify the directory paths where the header files are located. This useful option saves the user the trouble of specifying the path of each header file. For example the file profibus.cpp includes the following include file:

#include <e:\cimetrix\lib\eaal_header\ProfibusErrors.h>

The path to the folder where include files are located may be different from the path where the executable was originally located. By specifying: these paths in Tool Options Directories Directories, the compiler and the preprocessor knows how to build the *.obj, *.pdb and *.sbr files. Files ending in sbr extension contain browsing information which keep track of the functions, variables, pointers, data structure and etc. When right clicking the mouse on any identifier and selecting Go To Definition of ‘identifier’, the user can view its definition. Files ending in pdb contain debugging information, created by selecting Debug Settings Link Generate debug info. For detailed information, see Visual C++ manuals.

3.2 Interface Organization

This section describes the user_cntrl.c interface provided by CODE, and how it is to be modified for the device driver to the Profibus-DP card that incorporates the Profibus API functions. The CODE signal table provides the data formatting and signal initialization required for CODE I/O. CIMServer then stores this information in data structures which are passed to user developed functions in user_cntrl.c. These functions must be written to reformat the data for I/O exchange with the Profibus card through the Profibus API functions provided with the card.

Profibus-DP Driver SpecDoc 05/09/23 24

Page 27: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

3.2.1 Interface ProceduresThe procedures basically include the following steps. These are described in the Customizing CODE reference manual, in Chapter 3 – Controller Interface Functions. The following steps do not describe the detailed organization of each user-defined routine. These steps describe how these routines are integrated into user_cntrl.c, without providing all the directory paths and other details. Again, see the CODE manuals for the exact details.

Step 1 – Identify a unique defined constant and logical name for the Profibus driver. This number must be greater than 1000 (numbers less than 1000 are reserved by Cimetrix). We will select

#define profibus 1006

Add this defined constant to the supplied file cntr_const.h.

Step 2 – Identify the prefix name for the user-defined interface functions to be described further in Section 3.2.2 and shown in Table 3.3. These functions provide the function names under which the driver will be built.

Step 3 – Identify the number of controller types. Note that user_cntrl.c integrates a data structure controller_instance into its organization so that an array of these controller instances can be expanded (using array enumeration) to incorporate (and point to) the correct user-supplied function through the generic function calls provided in user_cntrl.c. The user must identify the number of controller types that will be enumerated in the controller_instance array and place the following statement before the array enumeration:

#define CX_NUM_CONTROLLER “place number here”

The number of controllers must include the software signals in this number. The user simply must then add to the controller_instance array the names of the user-defined functions at the top of the user_cntrl.c file under the unique defined constant profibus. The user must identify a command line argument for an # ifdef include directive so that only those drivers that are active in the cell will be included at compile time. We will use the directive USE_profibus and add the user functions under the # ifdef, e.g.,

# ifdef USE_profibus“specify user defined functions”

# else“specify NULL”

# endif

The array listing should now assume the format (the first two NULL’s outside the ifdef mean that this I/O controller does not support any motion commands):

#define CX_NUM_CONTROLLER “place number here”

controller_instance controller_funclist[CX_NUM_CONTROLLER] ={.

Profibus-DP Driver SpecDoc 05/09/23 25

Page 28: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

.{

profibus,NULL,NULL,

#ifdef USE_profibusprofibus _signal_func,profibus _signal_drvr_func,profibus _send_cmd

#elseNULL,NULL,NULL

#endif},

.

.}

Step 4 – The user will usually build one or more include/header files that are unique to his/her interface functions. These include files should be unique and also added to the top of user_cntrl.c, again using an #ifdef and the command line argument USE_profibus .

Step 5 – The user now develops a source file expanded in the user functions defined in Section 3.1.2. This interface file constitutes the driver interface that processes the various CIMServer cases, reformats the data that is being passed back and forth between the CIMServer and the Profibus card through the CIMServer data structures and the Profibus API calls. This file is integrated to make a custom CIMServer by compiling and linking to make a new executable.

NOTE: If the user chooses to use the MFC (Microsoft Foundation Class) library, the interface functions provided must be compiled as a C++ executable. This means that the extensions to software_drvr.c, threadmain.c, user_cntrl.c, user_kin.c, and user_motion.c must be changed to “cpp”, i.e., software_drvr.cpp, threadmain.cpp, user_cntrl.cpp, user_kin.cpp, and user_motion.cpp.

3.2.2 CODE user_cntrl.c FunctionsThe interface file user_cntrl.c contains several routines (or functions) which the user can modify to customize a device driver. Some of these are applicable to motion control, and some to I/O control. We refer to the three that are applicable to the Profibus I/O driver in Table 3.3. Note that the xxxx refers to a user chosen prefix for these functions for which we have chosen the prefix “profibus”.

Table 3.3 – I/O user_cntrl.c Functions

Function Description

xxxx_signal_func() Implements specific I/O signals.

Profibus-DP Driver SpecDoc 05/09/23 26

Page 29: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

xxxx_signal_drvr_func() Implements specific I/O interface drivers. xxxx_send_cmd() Used to send controller specific commands

to the controller. This function is used by several CODE API’s to pass through Profibus-DP I/O capabilities and commands not supported in CODE.

The custom functions used in the driver are:

extern long profibus_signal_func (signals_t* sigPtr, long function, void* arg, CxErrorMsg* this_error);

extern long profibus_signal_drvr_func (signal_drivers_t* drvrPtr, long function, void* arg, CxErrorMsg* this_error);

extern long profibus_send_cmd (cmd_msg *msg, CxErrorMsg* this_error);

These functions are designed to return the value CX_OK if no error occurs inside the function, or return CX_ERROR if an error occurs. If CX_ERROR is returned, then the this_error argument of type CxErrorMsg data structure should be loaded with the correct error information and returned through the argument. The error return procedures are described in the CODE documentation section Handling Driver Errors in Chapter 3 – Controller Interface Functions.

The prototype arguments are defined in Table 3.4.

Table 3.4 – Function Arguments

Argument Description

function This argument passes the particular I/O case from a client process to the user function. It will have values like CX_CNTRL_OPEN_SIGNAL_TABLE (see Table 2.1) which can be used in a case switch statement to call a user supplied routine.

arg The pointer void* to arg means that this argument is supplied as a pointer address to a value (or data type) that depends on the I/O case defined by function. In some cases arg is of type long and in other cases it might be of data structure type signal_info - see Chapter 3 – Controller Interface Functions.

this_error this_error is a data structure of type CxErrorMsg which the user uses to pass error information back to the client process when an error occurs in one of the interface routines.

Profibus-DP Driver SpecDoc 05/09/23 27

Page 30: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

sigPtr A pointer of data structure type signals_t which contains the specific entry information for the CIMServer signals – again see Chapter 3 – Controller Interface Functions.

drvrPtr A pointer of data structure type signal_drivers_t which contains the specific parameter information for the CIMServer signals – again see Chapter 3 – Controller Interface Functions.

msg A pointer of data structure type cmd_msg which contains the specific parameters used to pass information between a client process and the profibus driver; see Chapter 3 – Controller Interface Functions.

The user developed functions must simply operate with these data structures to get and set the signal information required by the CODE client processes, reformatting the data as required by the Profibus card.

3.2.3 CODE Signal TableBefore any signals can be used with CODE software, the signals must be defined in a file called a signal table. When the –sigtable option is used in the CIMulation or CIMControl command line argument list, the signal table is read by CIMServer. If the signal table contains an error, CIMServer will fail to start. The command line that needs to be entered in the Settings Debug Project settings Project arguments edit box is:

cimcontrol –sigtable “path where the signal table file is located”

When the server reads in the signal table it initializes all signals, and internally sets them to the values specified by the user in the signal table. If the signal table contains hardware signals, it will initialize the Profibus I/O card. This allows the client process application to access and manipulate signals or set/read values for the hardware/software signals.

When CIMServer is started, it immediately reads the signal table as defined in the command line arguments. There is a header file created by a makeheader utility, associated with the signal table. It contains the logical names of the signals along with ordering numbers. The header file is included in the client process project workspace as well as in the client source code file. This way the server knows that the signals exist and are defined, so it can access and use those signals to map them to physical hardware equipment – in this case I/O interface modules.

The signal table will normally include software signal definitions as the first entry. The CIMServer manages all signals declared in the signal table. Any CODE client process may interact with the defined signals using the API functions defined in the CODE API library: Events, States, and I/O. The client process may not reference any signals in a CODE client application process that are not defined in the signal table.

Profibus-DP Driver SpecDoc 05/09/23 28

Page 31: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

typedef struct signals_t { /* Data on physical signal instances */char name[CX_NAME_LEN]; /* ascii name of logical signal */long input; /* Hardware Input toggle */long output; /* Hardware Output toggle */long use_init; /* (T/F) use init_value to initialize signal */long init_value; /* Value to set on startup */long field1; /* Driver specific field 1 */long field2; /* Driver specific field 2 */long field3; /* Driver specific field 3 */long field4; /* Driver specific field */long field5; /* Driver specific field 5 */long field6; /* Driver specific field 6 */long field7; /* Driver specific field 7 */long field8; /* Driver specific field */long field9; /* Driver specific field 9 */long field10; /* Driver specific field 10 */long value; /* Current signal value */long sim; /* Simulation toggle */caddr_t sigInfo ; /* Generic pointer to driver specific sig str */signal_drivers_t *sdrvr; /* Pointer to corresponding signal driver. */struct table_entry first_entry; / Pointer for internal CIMServer use */long table_index; /* Array index in signal table array */char *expression; /* Logical expression, etc */char *description; /* Brief signal description */char *sig_class; /* Signal class */

}

Figure 3.1 - signals_t Data Structure

The signal table contains hardware specific information, such as memory offsets that will be mapped relative to the base address specified for the card DPM, etc. When CIMServer is started, the signal table file is read. The field names and values are copied to two CODE defined data structures: signals_t and signal_drivers_t. The structure members are shown in Figures 3.1 and 3.2.

The copied data from the signal table correspond directly to the member variable names, as can be seen from Figure 3.1 and Figure 3.2. The pointer variables are defined to reference local instances of these data structures. The member variables are used to perform I/O operations and access the Profibus-DP card. Table 3.5 explains the correspondence between signal table definitions and the CODE data structure member variables. In addition, CIMServer data parameters are also mapped to the arguments of the appropriate Profibus API functions and the related data structure members.

Profibus-DP Driver SpecDoc 05/09/23 29

Page 32: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

typedef struct signal_drivers_t { /* Signal device driver struct */long driver_type ; /* Type of device driver */long driver_instance; /* Which instance of the driver */char device_name[CX_MAX_PATH_LEN]; /* Logical device name */long start_index ; /* Starting signal index */long end_index ; /* Ending signal index */long poll_flag ; /* T/F indicating polled signals */long intr_flag ; /* T/F indicating intr signals */char labels[10][CX_NAME_LEN]; /* Optional signal parm labels */caddr_t drvrInfo; /* Generic pntr to drvr specific info */long initialized; /* T/F indicating driver inited. */long num_polled_table_entries; /* Num polled signals in driver */long controller_index ; /* Index into CxController funclist */

}Figure 3.2 - signal_drivers_t Data Structure

Table 3.5 – Mapping of Signal Table Fields to CIMServer and PB-DP Parameters

Signal Table Field Definitions

Map to CIMServer Data Parameter

Map to Profibus-DP Data Parameter

Driver type signal_drivers_t long driver_type

Defines signal controller type, with value defined in cntr_const.h (we use 1003 for PB-DP driver. (READ ONLY)

This field is passed through the CODE function long get_controller_index( long controller_type, CxErrorMsg *this_error) by the CODE server, corresponding to argument controller_type. This function is defined in user_cntrl.c. It does not map to any PB API parameter.

Driver instance signal_drivers_t long driver_instance

Defines an instance of a specific driver when user connected to several different controllers of the same type. (READ ONLY)

If several signal table blocks are of the same driver type value, e.g., 1003, then a different number is entered for the driver instance. The PB-DP driver permits up to 4 boards in the same bus, as specified by the parameter usDevNumber passed as an argument in several PB API functions.

NT device name signal_drivers_t char device_name[PATH_LN]

Defines a logical device name used to communicate with the device (READ ONLY)

The field is used during initialization in DevOpenDriver(). Within the function CreateFile() is called to open a communication resource. The field value is used as an argument for CreateFile(). Also, the field value is referenced in PB_DP_init_card() which contains a local pointer to signal_drivers_t data structure. A member variable of that structure is assigned the value of the field. The character string in this field is copied to sdrvr->device_name. That character string is used subsequently in PB_DP_init_card() to open a

Profibus-DP Driver SpecDoc 05/09/23 30

Page 33: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

communication resource ( in this case serial communication resource RS485)

logical signal name signals_tchar name[NAME_LEN]

Contains the characters of the logical signal. (READ ONLY)

The character string in this field does not map to Profibus DP data parameter, but it can be accessed indirectly through locally defined pointers to signals_t data structure.

input signals_tlong input

Defines whether the signal is available as a hardware input. A value of 0 indicates that the signal is not readable in hardware. A value of 1 means the signal must be polled. A value of 2 means that the corresponding driver can generate interrupts for this signal, and does not require polling. (READ ONLY)

The value in the field is mapped indirectly in PB_DP_initialize_signal() to a local pointer to signals_t data structure named sigPtr. sigPtr->input is used in a case statement to perform an assignment of a CODE defined constant to siginfo-> sig_type member variable.

output signals_t long output

Defines whether the signal is available as a hardware output. A value of 0 indicates the signal does not have output capability and the CIMServer does not permit a CODE application process to set the value. A value of 1 indicates that it does. The CIMServer saves the value in its internal table and writes the value to the driver. (READ ONLY)

The value in the field is mapped indirectly in PB_DP_initialize_signal() to a local pointer to signals_t data structure named sigPtr. sigPtr->output is used in a case statement to perform an assignment of a CODE defined constant to siginfo-> sig_type member variable.

use_init signals_tlong use_init

Used only when the output field is 1, and it is a flag indicating whether or not to initialize the signal’s state when the CIMServer is started (1), or to leave the signal in its present condition (0). (READ ONLY).

The long value in this field does not map to Profibus DP data parameter, but it can be accessed indirectly through locally defined pointers to signals_t data structure.

init_value signals_tlong init_value

Used only when the output field is 1 and the use_init field is 1. When these conditions are satisfied, the init_value defines the desired initial value of the signal when the CIMServer starts. (READ ONLY).

The long value in this field does not map to Profibus DP data parameter, but it can be accessed indirectly through locally defined pointers to signals_t data structure.

Profibus-DP Driver SpecDoc 05/09/23 31

Page 34: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

InBase signals_tlong field1

This field represents the DPM base address for an input signal. IOnum and Width are then used to move to the correct bits assigned to the signal.

Mapped to the argument usReceiveOffset in DevExchangeIO().

OutBase signals_tlong field2

This field represents the DPM base address for an input signal. IOnum and Width are then used to move to the correct bits assigned to the signal.

Mapped to the argument usSendOffset in DevExchangeIO().

Type signals_tlong field3

This field will have a –1 value if simple I/O, but will have a value such as 750650 denoting the A/D module type if signal used for RS232 communications.

Not mapped to a PB-DP API parameter. Used in driver to call RS232 interface routines. These routines then exchange ASCII data by A/D emulation.

IOnum signals_tlong field4

Represents the offset bit I/O location for simple I/O relative to the base address. Will have value of –1 if analog I/O of Type 750650.

Used in driver to get to correct byte location in DPM, before exchanging the byte and bit values between the PB_DP card DPM and CODE server. Indirectly maps to the DevExchangeIO() arguments *pvSendData (if output signal) and *pvReceiveData (if input signal).

Width signals_tlong field5

This field specifies the number of bits allocated to this signal. For example, if 4 bits are specified, the signal value must not exceed 24 = 16.

Not mapped to a PB-DP API parameter. Used in driver to convert signal value to correct bit values passed to and from PB card.

field6 –field10 Not used Not used

3.2.4 CODE Client processFigure 3.4 shows a simplified fragment of a client process, whose sole purpose is to set/get signal values through the Profibus-DP I/O interface card. When all of the user-defined interface functions and API functions have been included in the project, the next step is to create a header file from the signal table. This header file must be included in client processes using the logical signal names and also in the user interface files developed for the Profibus driver.

The CIMServer automatically assigns each signal a number based on the order in which the signals are defined in the signal table, starting from 0. In a CODE client process,

Profibus-DP Driver SpecDoc 05/09/23 32

Page 35: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

#include <code\const.h>#include <code\robconst.h>#include <code\robpac.h>#include <code\msgUtil.h>#include <cimUtils\basicUtils.h>#include <code\cntr_const.h>#include <sigtables\profitest.h>void main(void){

CxServer First;char* server_name;long pulse_signal;

server_name = “myServerName”;First = CxOpenServer(server_name,CX_SYSTEM_V,0);

if(First == CX_NULL){

printf(“Unable to open server. \n”);exit(-1);

}

if(CxSetSignal(First,OPEN_GRIPPER,255) == CX_ERROR)printf(“Error in setting signal \n”);

if(CxGetSignalValue(First,OPEN_GRIPPER,&pulse_signal) == CX_ERROR)

printf(“Error in getting signal value\n”);

if(CxSetSignal(First,CLOSE_GRIPPER,122) == CX_ERROR)printf(“Error in setting signal \n”);

if(CxGetSignalValue(First,CLOSE_GRIPPER,&pulse_signal) == CX_ERROR)

printf(“Error in getting signal value\n”);

CxCloseServer(First);CxRobpacExit():

}

Figure 3.4 – Sample client control process

signals are referenced using this numerical index into the signal table. CODE includes a makeheader utility that automatically generates a header file in which the logical name is mapped into the corresponding numerical index in the signal table. By including this header file in a client process and using the defined constant corresponding to the logical name of the signal, the readability of the source code can be improved.

The command to invoke the utility is:

makeheader sigtable_file filename.h

The command is invoked in a Command Prompt Window. The utility is located in a folder cimetrix/bin. In the command line the file containing the signal table is specified along with the target name of the header file that will be created. This command creates a header file in the same folder or in a different path location, if specified by the user. After the header file has been generated, such as the sample file in Figure 3.5, it should be included as an include file in all CODE client processes and also in the device driver interface file which interact with the signals.

3.2.5 Interrupt Device DriverProfibus-DP supports both a polling mode and an interrupt mode. Initially, the interrupt mode will be implemented. Interrupt mode makes it possible for the user interface to access more than one board installed into the PC. This interrupt mode is not configured to interrupt when a signal input attains a certain value; thus, polling will have to be used here.

The default setting of the Profibus-DP board is interrupt mode. In interrupt mode, the default IRQ is 7. All other settings are the same for both modes. Some Profibus-DP API functions are primarily used in interrupt mode, for example DevOpenDriver() and DevCloseDriver(). In interrupt mode, up to four interface-boards can be used. Each board is configured to have its own IRQ.

3.2.6 Device Driver ThreadingCIMServer will initiate a thread for each device driver (different driver or another instance of same driver) it reads from the signal table blocks. For I/O drivers it will also

Profibus-DP Driver SpecDoc 05/09/23 33

Page 36: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

spawn threads for signals that will be monitored (wait for signal to reach certain value, etc.). If the monitoring uses interrupts, CIMServer will spawn a thread to monitor these types of signals. If there are signals that are polled for some value change, then a thread will be spawned for these types of signals. If some are interrupt and some are polled, then it will spawn two threads for monitoring the two different types of signals.

Since CIMServer is threaded, it will not be necessary to thread the device driver user interface.

Profibus-DP Driver SpecDoc 05/09/23 34

Page 37: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

4 IMPLEMENTATION TASKS

This section describes the implementation tasks that are necessary to complete the device driver. Most of this section is dedicated to further defining the architecture, data structures, and pseudo-code that will be implemented in the driver. In addition, a set of tests will be defined to test the developed driver.

The driver will use three operational modes to define the communication sequence with the Profibus card:

Init mode - Mode whereby user starts the server, establishes a link with the Profibus card, and initializes I/O module states according to predefined signal table values.

Table 4.1 – Initialization Mode Case Statements and Implementation Function

Init Mode Cases Description

profibus_signal_drvr_func()

CX_CNTRL_OPEN_SIGNAL_TABLE

This case initializes the signal table on an I/O controller. A function makes the calls required to initialize the I/O controller (DevOpenDriver(), DevInitBoard(), DevSetHostState()), and then initializes the member variable “initialized” in signal_drivers_t data structure to CX_TRUE.

profibus_signal_func()

CX_CNTRL_INITIALIZE_SIGNAL

This case initializes the state of a hardware signal. A function is called when the CIMServer reads the signal table and initializes each signal.

Normal mode - Normal mode whereby client processes interact with the Profibus card by calling signal related API functions.

Table 4.2 – Normal Mode Case Statements and Function Implementation

Normal Mode Cases Description

profibus_signal_func()

CX_CNTRL_SET_SIGNAL_VALUE

DevExchangeIO() is called to pass signal parameters such as offset, signal value, width, etc. The signal value is then written to DPM and corresponding hardware I/O then initialized with the specified value.

profibus_signal_func()

CX_CNTRL_GET_SIGNAL_VALUE

Call to DevExchangeIO() is made to pass signal parameters such as offset, signal value, width, etc. The signal value is read from DPM and the corresponding hardware I/O signal value is loaded into a locally defined buffer which is updated in the signal table offset field for the specified input module.

Profibus-DP Driver SpecDoc 05/09/23 35

Page 38: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Shutdown mode - Client processes and CIMServer closes the communication link to the Profibus card.

Table 4.3 – Shutdown Mode Case Statements and Function Implementation

Shutdown Mode Case Statements Description

profibus_signal_drvr_func()

CX_CNTRL_CLOSE_SIGNAL_TABLE

Calls a function to close the Profibus card. The terminating of the connection with the card is accomplished by sequential function calls to DevSetHostState(), DevExitBoard(), and DevCloseDriver(). The application then relinquishes the memory resources allocated previously for establishing the connection with the driver and the board.

Unfortunately, the CIMServer interface functions described in the next section are not defined as an operational mode sequence. Thus, elements of these three modes pervade all three functions.

Three interface routines will be implemented in the file named profibus.cpp:

profibus_signal_drvr_func()profibus_signal_func()profibus_send_cmd()

The pseudo-code for each signal case defined within these three functions is listed in the following sections.

4.1 Header Files, Constants and Parameters

This section defines the header files, constants, parameters and data structures that are required to implement the device driver and which are used in the interface functions.

Header files required:

The required header files are listed in Table 4.4.

Profibus-DP Driver SpecDoc 05/09/23 36

Page 39: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Table 4.4 – Header Files Associated with profibus_signal_drvr_func()

Header file – Description Contents

profibus.h Contains all of the function prototype definitions that represent the function interface between CIMServer and Profibus-DP card.

extern long profibus_signal_func ( signals_t *sigPtr,long function, void *arg, CxErrorMsg * this_error )

Implemented - function described in following sections.

extern long profibus_signal_drvr_func ( signal_drivers_t *drvrPtr, long function, void *arg, CxErrorMsg *this_error )

Implemented - function described in following sections.

extern long profibus_send_cmd( signal_drivers_t *drvrPtr, long function, void *arg, CxErrorMsg *this_error )

Implemented - function described in following sections.

profibus_signal.h

File is generated when the makeheader utility is run. It contains constant definitions of signals defined in the signal table.

/*---------------profibus_signal.h “sample” ----------------*/

#define OPEN_GRIPPER 0#define CLOSE_GRIPPER 1#define VALVE_1_OPEN 2#define VALVE_1_CLOSE 3#define VALVE_2_OPEN 4#define VALVE_2_CLOSE 5#define SENSOR_1_ON 6#define SENSOR_2_ON 7

/*-------------END of the Header File-----------------*/

ProfibusErrors.h

Contains error handling macro definitions associated with the signal table, i.e. signal table full, signal table not initialized, driver and device I/O errors.

Error constants to be defined under the section Defined constants.

cifuser.h

gldtypes.hcifdev_i.h

Contents of these files can be found under the folder Dependencies in project cimcontrol. These include files are provided with the Profibus driver software and must be included to call the Profibus API functions.

Defined constants (placed in ProfibusErrors.h):

Errors related to signal definitions in signal table:

#define CX_PB_DP_INVALID_SIGNAL_INBASE_ADDRESS 2000#define CX_PB_DP_INVALID_SIGNAL_OUTBASE_ADDRESS 2001#define CX_PB_DP_INVALID_SIGNAL_WIDTH 2002

Profibus-DP Driver SpecDoc 05/09/23 37

Page 40: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

#define CX_PB_DP_INVALID_SIGNAL_VALUE 2004#define CX_PB_DP_INVALID_SIGNAL_TYPE 2005#define CX_PB_DP_INVALID_SIGNAL_IONUM(BER) 2006

Errors related to client process argument errors:

#define CX_PB_DP_INVALID_FUNCTION_TYPE 2007#define CX_PB_DP_INVALID_BOARD_INSTANCE 2008#define CX_PB_DP_CANNOT_MONITOR_SIGNALS 2009

Errors related to Profibus-DP API interface errors:

#define CX_PB_DP_DRIVER_ERROR 2010#define CX_PB_DP_BOARD_NOT_INITIALIZED 2011#define CX_PB_DP_DRIVER_NOT_OPENED 2012

#define CX_PB_DP_DRV_BOARD_NOT_INITIALIZED 2013#define CX_PB_DP_DRV_INIT_STATE_ERROR 2014#define CX_PB_DP_DRV_READ_STATE_ERROR 2015#define CX_PB_DP_DRV_CMD_ACTIVE 2016#define CX_PB_DP_DRV_PARAMETER_UNKNOWN 2017#define CX_PB_DP_DRV_DEV_DPM_ACCESS_ERROR 2018#define CX_PB_DP_DRV_DEV_NOT_READY 2019#define CX_PB_DP_DRV_DEV_NOT_RUNNING 2020#define CX_PB_DP_DRV_DEV_WATCHDOG_FAILED 2021#define CX_PB_DP_DRV_DEV_OS_VERSION_ERROR 2022#define CX_PB_DP_DRV_DEV_SYSERR 2023#define CX_PB_DP_DRV_DEV_MAILBOX_FULL 2024#define CX_PB_DP_DRV_DEV_PUT_TIMEOUT 2025#define CX_PB_DP_DRV_DEV_GET_TIMEOUT 2026#define CX_PB_DP_DRV_DEV_GET_NO_MESSAGE 2027#define CX_PB_DP_DRV_DEV_RESET_TIMEOUT 2028#define CX_PB_DP_DRV_DEV_NO_COM_FLAG 2029#define CX_PB_DP_DRV_DEV_EXCHANGE_FAILED 2030#define CX_PB_DP_DRV_DEV_EXCHANGE_TIMEOUT 2031#define CX_PB_DP_DRV_DEV_COM_MODE_UNKNOWN 2032#define CX_PB_DP_DRV_USR_OPEN_ERROR 2033#define CX_PB_DP_DRV_USR_INIT_DRV_ERROR 2034#define CX_PB_DP_DRV_USR_NOT_INITIALIZED 2035#define CX_PB_DP_DRV_USR_COMM_ERR 2036#define CX_PB_DP_DRV_USR_DEV_NUMBER_INVALID 2037#define CX_PB_DP_DRV_USR_INFO_AREA_INVALID 2038#define CX_PB_DP_DRV_USR_NUMBER_INVALID 2039#define CX_PB_DP_DRV_USR_MODE_INVALID 2040#define CX_PB_DP_DRV_USR_MSG_BUF_NULL_PTR 2041#define CX_PB_DP_DRV_USR_MSG_BUF_TOO_SHORT 2042#define CX_PB_DP_DRV_USR_SIZE_INVALID 2043#define CX_PB_DP_DRV_USR_SIZE_ZERO 2044#define CX_PB_DP_DRV_USR_SIZE_TOO_LONG 2045#define CX_PB_DP_DRV_USR_DEV_PTR_NULL 2046#define CX_PB_DP_DRV_USR_BUF_PTR_NULL 2047#define CX_PB_DP_DRV_USR_SENDSIZE_TOO_LONG 2048#define CX_PB_DP_DRV_USR_RECVSIZE_TOO_LONG 2049#define CX_PB_DP_DRV_USR_SENDBUF_PTR_NULL 2050#define CX_PB_DP_DRV_USR_RECVBUF_PTR_NULL 2051

Profibus-DP Driver SpecDoc 05/09/23 38

Page 41: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

#define CX_PB_DP_RCS_ERROR 2052#define CX_PB_DP_MISC_ERROR 2053

Errors related to failure to initialize WAGO modules:

#define CX_PB_DP_WAGO_MODULE_INIT_FAILURE 2054#define CX_PB_DP_WAGO_MODULE_COM_FAILURE 2055

Global parameters:

None

Global data structures:

None

4.2 profibus_signal_drvr_func() Implementation

Function:

long profibus_signal_drvr_func( signal_drivers_t *drvrPtr, long function, void *arg,CxErrorMsg *this_error)

Return value:

Returns error condition CX_OK or CX_ERROR

Arguments:

*drvrPtr – Pointer to CODE defined data structure (see Figure 3.3)function – The signal case/function to be handled*arg – Different data type depending on function (case) type*this_error – Pointer to CODE defined error data structure (see CODE

documentation.

Local constants:

None

Local parameters:

err - Returns error conditionReturnFlag - Store return values from functions that are calledoutputbuffer - Pointer to server side buffer that maps to DPMloop - For loop counter

Error handling:

Errors returned from calls to the Profibus functions are stored in ReturnFlag. If a Profibus error is returned then the local routine ReportProfibusErrorMessages() is called to report the

Profibus-DP Driver SpecDoc 05/09/23 39

Page 42: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

error type. Errors are returned to the server by the long value CX_ERROR. Error conditions are specified by type and error text in the macros SetErrorMsg() and SetErrorText(), as shown by the following examples:

SetErrorMsg(this_error, CX_CASE_NOT_IMPLEMENTED);SetErrorText(this_error,” CX_CNTRL_MONITOR_SIGNALS not supported for Profibus”);

Pseudo-code - profibus_signal_drvr_func():

long profibus_signal_drvr_func(signal_drivers_t *drvrPtr, long function, void *arg, CxErrorMsg *this_error)

{ local variables:

int loop long err = CX_OK long ReturnFlag char *outputbuffer

Initialize ReturnFlag to DRV_NO_ERROR

Switch based on the value of “function” argument

case CX_CNTRL_CLOSE_SIGNAL_TABLE: // close driver signal tableCall DevSetHostState() with argument HOST_NOT_READY and no timeoutCall DevExitBoard() to end communication with boardCall DevCloseDriver() to close Profibus driver applicationBreak if any of these calls do not return DRV_NO_ERROR

Free the memory allocated to drvrPtr->drvrInfobreak

case CX_CNTRL_MONITOR_SIGNALS:/* monitors signal status when driver generates asynchronous interrupts */

Set err to CX_ERRORSet error msg CX_CASE_NOT_IMPLEMENTEDSet error text “CX_CNTRL_MONITOR_SIGNALS not supported for profibus“

break

case CX_CNTRL_OPEN_SIGNAL_TABLE /* opens signal table associated with a device driver. */

Check to see if Profibus card already open by checking drvrPtr->initializedIf set to one, then already initialized and can return

If not initialized, thenCall DevOpenDriver() to open Profibus driver applicationCall DevInitBoard() to initialize boardCall DevSetHostState() with argument HOST_READYCheck return values in each previous call to ensure that no errors are returnedAllocate 512 Bytes as output buffer and assign to drvrPtr->drvrInfoThen assign all 512 Bytes zero values and pass to card using DevExchangeIO() to zero out DPM 512B output buffer

Initialize drvrPtr->initialized to onebreak

Profibus-DP Driver SpecDoc 05/09/23 40

Page 43: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

default /* handle an error message in case CIMServer passes invalid function argument */

Set err to CX_ERRORSet error msg CX _INVALID_FUNCTION_TYPESet error text “ Invalid function type for Profibus device driver“

break

End switch

If ReturnFlag is DRV_NO_ERROR then return CX_OK

Else call ReportProfibusErrorMessages() to report Profibus error encountered andreturn CX_ERROR

}

4.3 profibus_signal_func() Implementation

Function:

long profibus_signal_func(signals_t* sigPtr, long function, void *arg, CxErrorMsg *this_error)

Return value:

Returns error condition

Arguments:

*sigPtr – Pointer to CODE defined data structure (see Figure 3.3)function – The signal case/function to be handled*arg – Different data type depending on function (case) type*this_error – Pointer to CODE error data struct (see CODE documentation)

Local constants:

None

Local parameters:

err - Return error conditionDesiredValue - Stores signal value to be passed to Profibus card DPMReturnFlag - Stores returned value from function callInBase - Base address for input signal offsetOutBase - Base address for output signal offsetType - Type of I/O (digital bit, analog, RS232)IOnum - Number assigned to the I/O signalWidth - Number of bits allocated to the signaloutput_to_rs232[4] - Control bytes used for rs232 communicationsinput_to_rs232[4] - Control bytes used for rs232 communicationsloop - For loop counter

Profibus-DP Driver SpecDoc 05/09/23 41

Page 44: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

start_time - Used for timing-out functions present_time - Used for timing-out functionslongptr - A pointer to arg

Error handling:

Errors are indicated when a function returns the long value CX_ERROR. Error conditions are specified by type and error text in the macros SetErrorMsg() and SetErrorText(), as shown earlier in Section 4.2.

Pseudo-code - profibus_signal _func():

long profibus_signal_func(signals_t* sigPtr, long function, void* arg, CxErrorMsg* this_error){ local variables: long err = CX_OK

int loopint DesiredValueshort ReturnFlag

short InBase short OutBase

int Type int IOnum int Width unsigned char output_to_rs232[4] unsigned char input_to_rs232[4]

time_t start_timetime_t present_time

Initialize ReturnFlag to DRV_NO_ERROR

Use local parameters to store the field values in the sigPtr data structureInBase = (short) sigPtr ->Field1OutBase = (short) sigPtr ->Field2Type = (int) sigPtr ->Field3 IOnum = (int) sigPtr ->Field4Width = (int) sigPtr ->Field5

arg is used by some cases as a data value, and in others as a pointer.Cast arg as int and load into DesiredValue and also as a long pointer and store in longptr.

Switch based on value of “function” argument

case CX_CNTRL_INITIALIZE_SIGNALCheck to see that sigPtr fields have valid data; return CX_ERROR if invalidOnly 16 bit signal width is supported

Switch on module type from Type fieldcase –1

This is generic bit-based output so break sinceCX_CNTRL_SET_SIGNAL_VALUE will be called to set signals

break

case 750650

Profibus-DP Driver SpecDoc 05/09/23 42

Page 45: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

This is 4 Byte analog module (Wago 750650) used for RS232 communicationsInitialize each of the 4 bytes in output_to rs232 buffer and

input_to_rs232 buffers to zeroAssign the initialization bit (bit 3) for the first control byte (byte 1 which is

output_to rs232[1]) to the value 1 (hex 0x04) and pass it throughDevExchangeIO to init the correct DPM bit at the correct OutBaseaddress offset and with 1000 ms timeout. OutBase is cast to unsigned short in the DevExchangeIO argument as required.

Receive DPM acknowledgement by calling DevExchangeIO with timeoutof 1000 ms in a while loop by reading input_to_rs232[StatusByte] inDevExchangeIO until the status bit (bit 3) is returned as one (or 0x04).The InBase address offset is cast to unsigned short. The status byteis the second input byte (byte 1)

Next, the control byte is cleared to zero by setting output_to rs232[ControlByte] = 0 and passing it back throughDevExchangeIO.

Again acknowledge by calling DevExchangeIO with timeout of 1000 ms in a ` while loop reading input_to_rs232[StatusByte] until it returns a zero value.

defaultSet error msg CX_INVALID_MODULE_TYPESet error text “Invalid profibus module type”Return CX_ERROR

End switch on module type

Check return values in each previous call to ensure that no errors are returned

Break from case CX_CNTRL_INITIALIZE_SIGNAL

case CX_CNTRL_GET_SIGNAL_VALUESwitch on module type

case –1Check signal width. If width is one (simple bit IO), then call GetInputBit

with arguments InBase and IOnum and return value in the argument&ReturnData of function GetInputBit. Store value in longptr.

else if width is greater than 1, then call ReadGroupInput with argumentsInBase, IOnum, and Width and return value in the argument&ReturnData. Store value in longptr.

beak case –1

case 750650Set error msg CX_INVALID_SIGNAL_TYPESet error text “Profibus module type 750650 not supported as

CxGetSignalFunction“return CX_ERROR

defaultSet error msg CX_INVALID_MODULE_TYPESet error text “Invalid profibus module type”return CX_ERROR

End switch on module type

break of case CX_CNTRL_GET_SIGNAL_VALUE

Profibus-DP Driver SpecDoc 05/09/23 43

Page 46: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

case CX_CNTRL_SET_SIGNAL_VALUESwitch on module type

case –1Check signal width. If width is one (simple bit IO), but desired value

is not 0 or 1, then return error.If width is one and desired value is 0, then call ClearOutputBit,

passing arguments of OutBase, IOnum, and drvrInfo, a pointer set to the address of the input buffer that wasinitialized when the signal table was opened.

If width is one and desired value is 1, then call SetOutputBit, passing arguments of OutBase, IOnum, and drvrInfo.

If width is greater than 1, then check value to ensure that it can bestored in 16 bits. If so, call WriteGroupOutput passing argumentsof OutBase, IOnum, DesiredValue, and drvrInfo.

Check return values for potential errors from the previous callsbreak

case 750650Set error msg CX_INVALID_SIGNAL_TYPESet error text “Profibus module type 750650 not supported as

CxSetSignalFunction“return CX_ERROR

DEFAULTSet error msg CX_INVALID_MODULE_TYPESet error text “Invalid profibus module type”return CX_ERROR

End switch on module type

break of case CX_CNTRL_SET_SIGNAL_VALUE

case CX_CNTRL_SETUP_SIGNAL_MONITORINGSet error msg CX_PB_DP_CANNOT_MONITOR_SIGNALSSet error text “CX_CNTRL_SETUP_SIGNAL_MONITORING not supported for profibus “return CX_ERROR

case CX_CNTRL_SET_LATCHSet error msg CX_CASE_NOT_IMPLEMENTEDSet error text “Case CX_CNTRL_SET_LATCH not supported for profibus“return CX_ERROR

case CX_CNTRL_GET_SIGNAL_CNTRLSet error msg CX_CASE_NOT_IMPLEMENTEDSet error text “Case CX_CNTRL_GET_SIGNAL_CNTRL not supported for profibus“return CX_ERROR

case CX_CNTRL_PULSE_SIGNALSet error msg CX_CASE_NOT_IMPLEMENTEDSet error text “Case CX_CNTRL_PULSE_SIGNAL not supported for profibus“return CX_ERROR

DEFAULT

Profibus-DP Driver SpecDoc 05/09/23 44

Page 47: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

/* handle an error message in case CIMServer passes invalid function argument */Set error msg CX_INVALID_FUNC_TYPESet error text “ Invalid function type for profibus_signal_func in profibus driver“return CX_ERROR

End switch

If ReturnFlag is DRV_NO_ERROR then return CX_OK

Else call ReportProfibusErrorMessages() to report Profibus error encountered andreturn CX_ERROR

}

4.3.1 profibus_signal_func Private FunctionsThe following private functions are required to implement profibus_signal_func():

static long GetInputBit(long OutBase, long InBase, CxErrorMsg *this_error)static long ReadGroupInput(long InBase, long IOnum, long Width, CxErrorMsg *this_error)static long SetOutputBit(long OutBase, long IOnum, unsigned char *OutputBuffer,

CxErrorMsg *this_error)static long ClearOutputBit(long OutBase, long IOnum, unsigned char *OutputBuffer,

CxErrorMsg *this_error)static long WriteGroupOutput(long OutBase, long IOnum, long Width, long DesiredValue,

unsigned char *OutputBuffer, CxErrorMsg *this_error)

4.3.1.1 Private Function: GetInputBit()

This function simply gets a single bit , specified by the OutBase address offset and the IOnum.

Function:

static long GetInputBit (unsigned short InBase, int IOnum, long *ReturnData)

Return value:

Returns error condition in ReturnFlag

Arguments:

InBase - DPM input signal address offsetIOnum - Input signal number relative to InBase*ReturnData - To return single bit value (0 or 1)

Local constants:

None

Local parameters:

div_result - Find byte number for bit to be set to zeroReturnFlag - Stores return value from call to DevExchangeIO()

Profibus-DP Driver SpecDoc 05/09/23 45

Page 48: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

ReceiveOffset - The DPM address offset passed through DevExchangeIO()byte_width - Byte width is set to 8 bitsdatabyte - Local parameter used to store the byte of interestBitWithinByte - A byte with all bits set to 0 except the bit of interestDPM_BitNum - IOnum reduced by 1

Error handling:

Shown in pseudo-code

Pseudo-code:

static long GetInputBit (unsigned short InBase, int IOnum, long * ReturnData){ local variables:

short ReturnFlag int ReceiveOffset=0int byte_width = 8int databyteint BitWithinByteint DPM_BitNumdiv_t div_result

Since IOnum numbered from 1, reduce value by one and store in DPM_BitNum

Find byte that contains specified input bit using div() operatordiv_result = div(DPM_BitNum, byte_width)

Set ReceiveOffset to InBase and then apply the div_result byte shift by addingdiv_result quotient to ReceiveOffset

Now create a byte that has the remainder (rem) bit set to one and the other bits in the byte set to 0 by applying BitWithinByte = 2rem

Now call DevExchangeIO() with ReceiveOffset and read back 1 byte into databyte.Check the return value for errors and return the error state in ReturnFlag

Do a bitwise & between BitWithinByte and databyte and if trueSet * ReturnData to 1

elseSet * ReturnData to 0

return ReturnFlag}4.3.1.2 Private Function: ReadGroupInput()

This function simply sets a single bit to zero.

Function:

static long ReadGroupInput ( unsigned short InBase, int IOnum, int Width, long * ReturnData)

Return value:

Profibus-DP Driver SpecDoc 05/09/23 46

Page 49: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Returns error condition in ReturnFlag

Arguments:

InBase - DPM input signal address offsetIOnum - Input signal number relative to InBaseWidth - Number of bits used for signal value

Local constants:

None

Local parameters:

div_result - Find byte number for bit to be set to zeroReturnFlag - Stores return value from call to DevExchangeIO()ReceiveOffset - The DPM address offset passed through DevExchangeIO()byte_width - Byte width is set to 8 bitsdatabyte - Local parameter used to store the byte of interestcurrentbit - Bit determined from remainderBitWithinByte - Byte with all bits set to 0 except the bit of interestGroupdata - Used for local group bit manipulationsbitdataoffset - Stores byte which has some or all of needed bitsDPMdata[3] - Stores 3 received bytes returned from DPM

Error handling:

Shown in pseudo-code

Pseudo-code:

static long ReadGroupInput (unsigned short InBase, int IOnum, int Width, long * ReturnData){ local variables:

char DPMdata[3]int DPM_BitNumint ReceiveOffset=0int BitWithinByte;int databyte unsigned short ReturnFlag long Groupdata = 0int byte_width = 8int bitdataoffsetint currentbit;div_t div_result

Since IOnum numbered from 1, reduce value by one and store in DPM_BitNum

Find byte that contains specified output bit using div() operatordiv_result = div(DPM_BitNum, byte_width)

Profibus-DP Driver SpecDoc 05/09/23 47

Page 50: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Set ReceiveOffset to InBase and then apply the div_result byte shift by addingdiv_result quotient to ReceiveOffset. This quotient is the byte offset from InBase.Use the remainder from this operation to determine the bit number from within the byte found previously and set the remainder to currentbit. This bit, within this byte, is the DPM bit mapped to the desired Hardware (Physical) I/O. This remainder is also the beginning bit offset into DPMdata for Groupdata.

Now call DevExchangeIO() at ReceiveOffset and request three DPM bytesbe loaded into DPMdata. Use timeout of 1000 ms. Check the return value for errors and return the error state if error occurs. Driver only supports bit Width of 16 or less (signal values of 0 to 65536)

Now use a while loop to extract the value of each bit, counting down Width untilall bit values have been determined. Within this while loop:

Use the div() operator to find byte (0, 1, or 2) for the currentbit and store in bitdataoffset

Load the byte numbered bitdataoffset into databyte using the local buffer DPMdata

Now create a byte that has the remainder (rem) bit set to one and the other bits in the byte set to 0 by applying BitWithinByte = 2rem

Now do a bitwise & of BitWithinByte and databyte.If the & result is positive then the current bit in DPMdata is a one. To load these

bits recursively, we start with the empty byte GroupData, do a bitwise shift shift leftand then increment the byte by GroupData++ to place a 1 in the least significant bit.

else if the result is 0 we simply do the shift.

Now count down the Width and increment up currentbit by one and continue the loopuntil Width is zero.

End while loop

Load Groupdata into * ReturnData which will be returned as function argument

Return the error state in ReturnFlag

}

4.3.1.3 Private Function: ClearOutputBit()

This function simply sets a single bit to zero.

Function:

static long ClearOutputBit ( unsigned short OutBase, int IOnum, char *OutputBuffer)

Return value:

Returns error condition ReturnFlag

Arguments:

Profibus-DP Driver SpecDoc 05/09/23 48

Page 51: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

OutBase - DPM output signal address offsetIOnum - Output signal number*OutputBuffer - Output buffer on server side

Local constants:

None

Local parameters:

div_result - Find byte number for bit to be set to zeroReturnFlag - Stores return value from call to DevExchangeIO()SendOffset - The DPM address offset passed through DevExchangeIO()byte_width - Byte width is set to 8 bitsdatabyte - Local parameter used to store the byte of interestBitWithinByte - A byte with all bits set to 0 except the bit of interestDPM_BitNum - IOnum reduced by 1

Error handling:

Shown in pseudo-code

Pseudo-code:

static long ClearOutputBit (unsigned short usOutBase, long IOnum, unsigned char *OutputBuffer, CxErrorMsg *this_error){ local variables:

short ReturnFlag int SendOffset=0int byte_width = 8int databyte int BitWithinByteint DPM_BitNumdiv_t div_result

Since IOnum numbered from 1, reduce value by one and store in DPM_BitNum

Find byte that contains specified output bit using div() operatordiv_result = div(DPM_BitNum, byte_width)

Set SendOffset to OutBase and then apply the div_result byte shift by addingdiv_result quotient to SendOffset

Now create a byte that has the remainder (rem) bit set to one and the other bits in the byte set to 0 by applying BitWithinByte = 2rem

Read the local output buffer at byte offset SendOffset and and store value in databyte

Complement BitWithinByte so it can be used as a mask and then & it with databyte , storingthe final value in databyte and also updating the local output buffer with this same byte.This is the byte of interest with all its original bit values except the bit of interest, now 0.

Profibus-DP Driver SpecDoc 05/09/23 49

Page 52: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Now call DevExchangeIO() to pass this single byte to the DPM which will set the bitof interest to 0. Check the return value for errors and return the error state if error

return ReturnFlag}

4.3.1.4 Private Function: SetOutputBit()

This function simply sets a single bit to one.

Function:

static long SetOutputBit(unsigned short OutBase, int IOnum, char *OutputBuffer)

Return value:

Returns error condition in ReturnFlag

Arguments:

OutBase - DPM output signal address offsetIOnum - Output signal number*OutputBuffer - Output buffer on server side

Local constants:

None

Local parameters:

div_result - Find byte number for bit to be set to zeroReturnFlag - Stores return value from call to DevExchangeIO()SendOffset - The DPM address offset passed through DevExchangeIO()byte_width - Byte width is set to 8 bitsdatabyte - Local parameter used to store the byte of interestBitWithinByte - A byte with all bits set to 0 except the bit of interestDPM_BitNum - IOnum reduced by 1

Error handling:

Shown in pseudo-code

Pseudo-code:

static long SetOutputBit (unsigned short OutBase, int IOnum, char *OutputBuffer){ local variables:

short ReturnFlag int byte_width = 8int SendOffset=0

Profibus-DP Driver SpecDoc 05/09/23 50

Page 53: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

int databyte int DPM_BitNumint BitWithinBytediv_t div_result

Since IOnum numbered from 1, reduce value by one and store in DPM_BitNum

Find byte that contains specified output bit using div() operatordiv_result = div(IOnum, byte_width)

Set SendOffset to OutBase and then apply the div_result byte shift by addingdiv_result quotient to SendOffset

Now create a byte that has the remainder (rem) bit set to one and the other bits in the byte set to 0 by applying BitWithinByte = 2rem

Read the local output buffer at byte offset SendOffset and and store value in databyte

Do a bitwise “or” of databyte and BitWithinByte to set the bit of interest to 1 and storeresult in databyte . Also update the output buffer with this byte.

Now call DevExchangeIO() to pass this single byte to the DPM which will set the bitof interest to 1. Check the return value for errors and return the error state in this_error

return ReturnFlag}

4.3.1.5 Private Function: WriteGroupOutput()

This function simply sets writes the value of a group of bits to the DPM.

Function:

static long WriteGroupOutput(unsigned short OutBase, int IOnum, int Width, int DesiredValue, char *OutputBuffer)

Return value:

Returns error condition in ReturnFlag

Arguments:

OutBase - DPM output signal address offsetIOnum - First bit of output signalWidth - Number of bits for output signalDesiredValue - Set to value received in arg*OutputBuffer - Output buffer on server side

Local constants:

None

Profibus-DP Driver SpecDoc 05/09/23 51

Page 54: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Local parameters:

ReturnFlag - Return value from PB library callbitposition - Used as a bit maskBitWithinByte - Holds value when one bit is set to 1Beginning_IOnum - Holds initial value of IOnumCurrent_IOnum - Holds current DPM bit to be modifiedDPM_BitNum - Local bit number counterdatabyte - Load byte of current bitSendOffset - DPM offset adjusted by bit numberbyte_width - 8 bits per bytediv_result - Determines byte holding bit of interest

Error handling:

Shown in pseudo-code

Pseudo-code:

static long WriteGroupOutput(unsigned short OutBase, int IOnum, int Width, int DesiredValue, char *OutputBuffer)

{ local variables:

short ReturnFlag int bitpositionint BitWithinByteint DPM_BitNumint databyte unsigned short SendOffset=0int byte_width=8int Beginning_IOnumint Current_IOnumdiv_t div_result

Store IOnum in Beginning_IOnum and Current_IOnum as starting bit

Add Width to IOnum to get ending bit number but must decrement by 1.Store result in Current_IOnum

Set bitposition equal to value of 1 which also turns the first bit on

Do a while loop over all group bits by decrementing down from IOnum + Width (now storedas Current_IOnum) until all bits have been considered. Inside the loop do the following:

Do an bitwise & of bitposition and DesiredValue to see if the bit in bitpositionof DesiredValue is a 1. If so, then

Set DPM_BitNum to Current_IOnum and Decrement DPM_BitNum by 1.

First, find the byte that contains the specified beginning output bit by applying the div() operator and storing the result in div_result

Set SendOffset to OutBase and then increment up by the quotient from the div_result

Profibus-DP Driver SpecDoc 05/09/23 52

Page 55: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

quotient.

The remainder from div_result is the bit number within the byte found previously.Form a mask using the div_result remainder as the exponent of 2 to set the desired bit

in the rem position. BitWithinByte = 2rem

Read the buffer at the current offset byte (SendOffset) and store in databyte .

Do a bitwise or between databyte and BitWithinByte to turn bit on and store result in databyte.

Now store the modified byte in OutputBuffer [SendOffset]

In anticipation of next loop decrement apply left shift operator to bitposition to shift bit one place (to next bit).

End if

Else if the bit in bitposition of DesiredValue is not a 1, then

Set DPM_BitNum to Current_IOnum and decrement DPM_BitNum by 1.

First, find the byte that contains the specified beginning output bit by applying the div() operator and storing the result in div_result

Set SendOffset to OutBase and then increment up by the quotient from the div_result quotient.

The remainder from div_result is the bit number within the byte found previously.Form a mask using the div_result remainder as the exponent of 2 to set the desired bit

in the rem position. BitWithinByte = 2rem

Read the buffer at the current offset byte (SendOffset) and store in databyte .

Do a complement of BitWithinByte and store in BitWithinByte as a bit mask.

Do an bitwise & of databyte and BitWithinByte to mask the bit off

Store modified byte in OutputBuffer[SendOffset] as databyte

In anticipation of next loop decrement apply left shift operator to bitposition to shift bit one place (to next bit).

End else if

Decrement Current_IOnum to move to next bit

end while loop

Write data in buffer to DPM by calling DevExchangeIO at SendOffset and writing 3 bytes from the OutputBuffer beginning at byte SendOffset. Timeout of 1000 ms

Error check on ReturnFlag from call

}

Profibus-DP Driver SpecDoc 05/09/23 53

Page 56: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

4.4 profibus_send_cmd() Implementation

This function is used to enable RS232 communications between a CODE client process and a physical device connected through a Wago 750650 RS232 module. In this way, it is not necessary to develop a specific device driver for simple devices connected to the Profibus fieldbus. String commands can be sent directly from the client process.

Devices of interest to the EAAL lab include a reflow oven, barcode device, PLC interface, solder dispenser, etc. These devices only require periodic communications, in contrast to the intensive communications required for the device drivers to the Profibus-DP card and the Seiko controllers.

Function:

long profibus_send_cmd (cmd_msg *msg, CxErrorMsg *this_error)

Return value:

Returns error condition

Arguments:

*msg – Pointer to CODE message data structure (see Figure 3.3)*this_error – Pointer to CODE error data struct (see CODE documentation)

Local constants:

None

Local parameters:

err - Return error conditionReturnFlag - Stores returned value from function callInBase - Base address for input signal offsetOutBase - Base address for output signal offsetSendDataBuffer - Server side data bufferNumberBytesToTransmit - Bytes to be sent to rs232 moduleNumBytesSent - Local counter for bytes sentEndOfHeader - Offset at beginning of rs232 data*commandstring - Command string sent to deviceoutput_to_rs232[4] - Control bytes used for rs232 communicationsinput_to_rs232[4] - Control bytes used for rs232 communicationsstart_time - Used for timing-out functions present_time - Used for timing-out functions

Error handling:

Profibus-DP Driver SpecDoc 05/09/23 54

Page 57: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Errors are indicated when a function returns the long value CX_ERROR. Error conditions are specified by type and error text in the macros SetErrorMsg() and SetErrorText(), as shown earlier in Section 4.2.

Pseudo-code - profibus_send_cmd():

long profibus_send_cmd(cmd_msg *msg, CxErrorMsg* this_error){ local variables:

long err = CX_OKshort ReturnFlag unsigned short InBaseunsigned short OutBaseunsigned char SendDataBuffer[512]unsigned int NumBytesToTransmitunsigned char NumBytesSentunsigned char EndOfHeader=7unsigned char *commandstringunsigned char output_to_rs232[4]unsigned char input_to_rs232[4]time_t start_timetime_t present_time

The command message is first loaded into commandstring as an unsigned char pointer.

ReturnFlag is initialized to DRV_NO_ERROR

Note: The first byte of the command string will be a command type. This function will read the first byte, and switch to a case for handling that command type. The first byte is an unsigned Hexadecimal byte. Wago 750-650 RS-232 module data transmissionswill be handled by case 1. Wago 750-650 RS-232 module data receptions will be handled by case 2.

Do a case switch on the first byte in commandstring (byte 0)

Case 1 is the Wago 750-650 RS-232 module data transmission case.The next 2 bytes of the string will be the InBase value fromthe signal table, and the following 2 bytes will be the OutBase value from the signal table. These bases are theaddresses assigned in the signal table to the Wago 750-650module that you wish to transmit data to (PC->WAGO->field).

Byte 1 (numbered from 0) is the upper byte of InBase. Byte 2 is the lower byte ofInBase. Byte 3 is the upper byte of OutBase, and Byte 4 isthe lower byte of OutBase. Thus,

Load commandstring[1] as an unsigned short into InBase and then shift into the upper byte using <<=8

Next add commandstring[2] as an unsigned short to InBase to load the lower byte

Perform the same operations with bytes 3 and 4 of commandstring to load theupper and lower bytes of OutBase.

The next 2 bytes (5,6) of the string contain the number of bytes to be transmitted to the

Profibus-DP Driver SpecDoc 05/09/23 55

Page 58: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

WAGO 750650 rs-232 module's 16 byte buffer for subsequent transmission.Load them into NumBytesToTransmit by shifting byte 5 to the upper byteand adding byte 6.

Initialize NumBytesSent to 0.

Now call DevExchangeIO to load the current status byte at input offset InBasewith a timeout of 1000 ms. Receive buffer is “input_from_rs232”. Check return error in ReturnFlag.

Next call DevGetInfo() with argument GET_IO_SEND_DATA to get read all 512DPM bytes to get at ControlByte value in the SendDataBuffer local buffer. Check return error in ReturnFlag.Set output_to_rs232[ControlByte]=SendDataBuffer[OutBase+ControlByte]

Next clear the data bytes of output_to_rs232 for OutputByte0, OutputByte1,and OutputByte2.

Note: The WAGO 750650 module is ready for data to be loaded into its bufferwhen the TA bit (bit0) of the Status Byte is equal to the TR bit (bit0)of the Command Byte.

Use a while loop to transmit the bytes by counting down from NumBytesToTransmitusing NumBytesSent as a counter.

While NumBytesSent less than NumBytesToTransmit

First init a timer using time(&start_time)

Do a while loop until the TR bit equals the TA bit, calling DevExchangeIO()at offset InBase, loading 4 bytes into input_from_rs232, then using theStatusByte in comparing bit values for TR = TA. Check ReturnFlag for errors.The comparison is made by comparing 2 bitwise &’s of

output_to_rs232[ControlByte] & 0x01 and input_from_rs232[StatusByte] & 0x01.

When these two results are the same, then the first bit of the control byte (TR) is 1 and the first bit of the status bit (TA) is 1 anddata can be transmitted.

Inside while loop get present time and exit with error if time expired reaches 5 sec.

End while loop when TR = TA.

Now, load the output_to_rs232 buffer in 4 byte increments, transmittinguntil all the bytes have been transmitted. The Wago RS232 protocol uses4 byte packets for each input and output data packet, withthe second output and second input byte as the control and status bytes, respectively. In the control and status bytes, bits 4 and 5 areused to specify whether 1, 2, or 3 “frames” (frame = byte) are to be communicated (the output or input). 0,1 = 1 byte; 1,0 = 2 bytes; 1, 1 = 3 bytes.Each byte will transmit 1 ascii character.

The bytes are loaded into output_to_rs232 and, depending on the numberof bytes to be sent, the control byte output_to_rs232[ControlByte] is bitwise &

Profibus-DP Driver SpecDoc 05/09/23 56

Page 59: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

with 0x07 to save the bit values for the 1st 3bits of the control byte, whichcorrespond to TR, RA, and IR in RS232 protocol. All other bits are set to 0by the & operation. Next, the control byte is | (or’ed) with 0x10, 0x20, or 0x30,depending on the number of bytes to transmit. This will set the 5 and 6 bits .to their correct value. NumBytesSent is incremented by the number of bytessent.

DevExchangeIO is now called to transmit the 4 bytes with timeout of 1000 msat OutBase. Check return error in ReturnFlag.

The TR bit is now inverted by the xor (^) operator, according to the operationoutput_to_rs232[ControlByte]^=0x01. This step completes the sending of dataand we continue the while loop.

End while loop for transmitting data

Set cmd_len in msg data structure to 0 to indicate no data to be returned.

Break from Case 1

Case 2: Wago 750-650 RS-232 module data receiving case.The next 2 bytes of thestring will be the InBase value from the signal table, and the following 2 byteswill be the OutBase value from the signal table. These bases are the addressesassigned, in the signal table, to the Wago 750-650 module that you wish toreceive data from (field>WAGO>PC).

Byte 1 is the upper byte of InBase. Byte 2 is the lower byte of InBase. Byte 3 is the upper byte of OutBase, and Byte 4 is the lower byte of OutBase.

Load commandstring[1] as an unsigned short into InBase and then shift into the upper byte using <<=8

Next add commandstring[2] as an unsigned short to InBase to load the lower byte

Perform the same operations with bytes 3 and 4 of commandstring to load theupper and lower bytes of OutBase.

Now call DevExchangeIO to load the current status byte at input offset InBasewith a timeout of 1000 ms. Receive buffer is “input_from_rs232”. Check return error in ReturnFlag.

Next call DevGetInfo() with argument GET_IO_SEND_DATA to get read all 512DPM bytes to get at ControlByte value in the SendDataBuffer local buffer. Check return error in ReturnFlag.Set output_to_rs232[ControlByte]=SendDataBuffer[OutBase+ControlByte]

Note: The WAGO 750650 module is ready for data to be read from its bufferwhen the RR bit (bit1) of the Status Byte is NOT equal to the RA bit (bit1)of the Command Byte.

This comparison is made by comparing 2 bitwise &’s of

output_to_rs232[ControlByte] & 0x02 and input_from_rs232[StatusByte] & 0x02.

If these two results are NOT the same, then data is to be read and we must first

Profibus-DP Driver SpecDoc 05/09/23 57

Page 60: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

determine how many bytes are ready.

To determine the number of bytes do the “&”

input_from_rs232[StatusByte]&0x30

and compare to 0x10, 0x20, 0x30 to determine if , 2, or 3, bytes (characters)are ready to be read. Then load commandstring with these bytes.

Toggle bit 1 to signal module that data has been read. This is done by invertingthe RA bit using output_to_rs232[ControlByte]^=0x02 and then callingDevExchangeIO with OutBase, transmitting 4 bytes sending output_to_rs232,with timeout of 1000 ms. Check ReturnFlag for error

Break from case 2.

Else if no bytes ready set cmd_len in msg data structure to 0 and break case 2.

Default case is returned as error

End switch

If ReturnFlag is DRV_NO_ERROR then return CX_OK

Else call ReportProfibusErrorMessages() to report Profibus error encountered andreturn CX_ERROR

}

4.5 Other Private Functions

The primary error function called in the various routines introduced previously is

static void ReportProfibusErrorMessages(short ProfibusErrorNumber, CxErrorMsg *this_error) This function relays Profibus driver errors returned from calls to Profibus API functions to the user.

Function:

void ReportProfibusErrorMessages(short ProfibusErrorNumber, CxErrorMsg *this_error)

Return value:

Returns error condition CX_ERROR

Arguments:

ProfibusErrorNumber - error number returned from call to Profibus API function*this_error - pointer to CODE defined error data structure(see CODE

documentation)

Local constants:

Profibus-DP Driver SpecDoc 05/09/23 58

Page 61: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

None

Local parameters:

None

Error handling:

Uses a switch to load the PB specific errors into CODE format.

Pseudo-code:

static void ReportProfibusErrorMessages(short ProfibusErrorNumber, CxErrorMsg *this_error){

Switch on ProfibusErrorNumber

case -1Set error msg CX_PB_DP_DRV_BOARD_NOT_INITIALIZEDSet error text DRIVER board not initializedbreak

case -2Set error msg CX_PB_DP_DRV_INIT_STATE_ERRORSet error text DRIVER error in internal init statebreak

case -3Set error msg CX_PB_DP_DRV_READ_STATE_ERRORSet error text DRIVER error in internal read statebreak

case -4Set error msg CX_PB_DP_DRV_CMD_ACTIVESet error text DRIVER command on this channel is activebreak

case -5Set error msg CX_PB_DP_DRV_PARAMETER_UNKNOWNSet error text DRIVER unknown parameter in function occurredbreak

case -10Set error msg CX_PB_DP_DRV_DEV_DPM_ACCESS_ERRORSet error text DEVICE dual port ram not accessiblebreak

case -11Set error msg CX_PB_DP_DRV_DEV_NOT_READYSet error text DEVICE not ready - ready flag failedbreak

case -12Set error msg CX_PB_DP_DRV_DEV_NOT_RUNNINGSet error text DEVICE not running - running flag failedbreak

case -13Set error msg CX_PB_DP_DRV_DEV_WATCHDOG_FAILEDSet error text DEVICE watch dog test failedbreak

case -14Set error msg CX_PB_DP_DRV_DEV_OS_VERSION_ERROR

Profibus-DP Driver SpecDoc 05/09/23 59

Page 62: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Set error text DEVICE signals wrong OS versionbreak

case -15Set error msg CX_PB_DP_DRV_DEV_SYSERRSet error text DEVICE error in dual port flagsbreak

case -16Set error msg CX_PB_DP_DRV_DEV_MAILBOX_FULLSet error text DEVICE send mailbox is fullbreak

case -17Set error msg CX_PB_DP_DRV_DEV_PUT_TIMEOUTSet error text DEVICE PutMessage timeoutbreak

case -18Set error msg CX_PB_DP_DRV_DEV_GET_TIMEOUTSet error text DEVICE GetMessage timeoutbreak

case -19Set error msg CX_PB_DP_DRV_DEV_GET_NO_MESSAGESet error text DEVICE no message availablebreak

case -20Set error msg CX_PB_DP_DRV_DEV_RESET_TIMEOUTSet error text DEVICE RESET command timeoutbreak

case -21Set error msg CX_PB_DP_DRV_DEV_NO_COM_FLAGSet error text DEVICE COM-flag not set break

case -22Set error msg CX_PB_DP_DRV_DEV_EXCHANGE_FAILEDSet error text DEVICE IO data exchange failedbreak

case -23Set error msg CX_PB_DP_DRV_DEV_EXCHANGE_TIMEOUTSet error text DEVICE IO data exchange timeoutbreak

case -24Set error msg CX_PB_DP_DRV_DEV_COM_MODE_UNKNOWNSet error text DEVICE IO data mode unknownbreak

case -30Set error msg CX_PB_DP_DRV_USR_OPEN_ERRORSet error text USER driver not openedbreak

case -31Set error msg CX_PB_DP_DRV_USR_INIT_DRV_ERRORSet error text USER can't connect with DEV boardbreak

case -32Set error msg CX_PB_DP_DRV_USR_NOT_INITIALIZEDSet error text USER board not initializedbreak

case -33Set error msg CX_PB_DP_DRV_USR_COMM_ERR

Profibus-DP Driver SpecDoc 05/09/23 60

Page 63: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Set error text USER IOCTRL function failedbreak

case -34Set error msg CX_PB_DP_DRV_USR_DEV_NUMBER_INVALIDSet error text USER parameter DEV number invalidbreak

case -35Set error msg CX_PB_DP_DRV_USR_INFO_AREA_INVALIDSet error text USER parameter InfoArea unknownbreak

case -36Set error msg CX_PB_DP_DRV_USR_NUMBER_INVALIDSet error text USER parameter Number invalidbreak

case -37Set error msg CX_PB_DP_DRV_USR_MODE_INVALIDSet error text USER parameter Mode invalidbreak

case -38Set error msg CX_PB_DP_DRV_USR_MSG_BUF_NULL_PTRSet error text USER NULL pointer assignmentbreak

case -39Set error msg CX_PB_DP_DRV_USR_MSG_BUF_TOO_SHORTSet error text USER Messagebuffer too shortbreak

case -40Set error msg CX_PB_DP_DRV_USR_SIZE_INVALIDSet error text USER size parameter invalidbreak

case -42Set error msg CX_PB_DP_DRV_USR_SIZE_ZEROSet error text USER size parameter with zero lengthbreak

case -43Set error msg CX_PB_DP_DRV_USR_SIZE_TOO_LONGSet error text USER size parameter too longbreak

case -44Set error msg CX_PB_DP_DRV_USR_DEV_PTR_NULLSet error text USER device address null pointerbreak

case -45Set error msg CX_PB_DP_DRV_USR_BUF_PTR_NULLSet error text USER pointer to buffer is a null pointerbreak

case -46Set error msg CX_PB_DP_DRV_USR_SENDSIZE_TOO_LONGSet error text SendSize parameter too longbreak

case -47Set error msg CX_PB_DP_DRV_USR_RECVSIZE_TOO_LONGSet error text ReceiveSize parameter too longbreak

case -48Set error msg CX_PB_DP_DRV_USR_SENDBUF_PTR_NULL

Profibus-DP Driver SpecDoc 05/09/23 61

Page 64: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

Set error text Pointer to buffer is a null pointerbreak

case -49Set error msg CX_PB_DP_DRV_USR_RECVBUF_PTR_NULLSet error text Pointer to buffer is a null pointerbreak

case 1000Set error msg CX_PB_DP_RCS_ERRORSet error text Board operation system errors. See Compiled Device Driver manual.break

defaultprintf("Profibus error number: %d\n",ProfibusErrorNumber)Set error msg CX_PB_DP_MISC_ERRORSet error text Miscellaneous errorbreak

End switch}

4.6 Verification Tests

The following verification tests should be run to test the Profibus interface driver:

1. Develop a signal table and configure the Wago modules for a series of 10 inputs and 10 outputs that can be physically tested. There should also be a set of software signals defined in the signal table so that both software and hardware signals are active at the same time. The hardware I/O should be connected to physical devices in the cell such as proximity switches, pneumatic valves, etc. The first test set of I/O should be single byte I/O. The input signals are to be specified as polled.

2. Develop a client process that will test each of the 20 I/O signals by setting and/or reading their values. The client process should write the response to the API calls and also the signal values to a file and also write any errors that occur from these calls. The user should be able to trigger an input signal by physically triggering a sensor in the cell and then see that the polling mode responds immediately by using API’s such as CxWaitForValue, etc. Any input signal that changes its value and is polled should print to the screen the value that is changed. In addition, the user should start up CIMTools and watch the signal table respond to signal changes, to ensure that the system response is timely. The output signals should be set up to cause something physically to happen, such as a pallet lift, etc. Again, note and record response times.

3. Develop another client process to test all modes not implemented by calling each signal API that relates to signal monitoring, latching, send command, etc. Each API should be called in the client process and ensure that the proper error response is returned from the driver interface.

4. Test all remaining signal API’s to ensure that no undesirable response occurs.

Profibus-DP Driver SpecDoc 05/09/23 62

Page 65: 1 Architectural Overview - Ira A. Fulton College of …ered/ME486/sec1-2-3-4.doc · Web viewClient control processes in CODE communicate with the Profibus-DP card by calling Profibus-specific

5. Force and test failure modes such as removing power to the sensors, and determine that the PB API’s return errors. See if these errors are returned properly to the client process.

Profibus-DP Driver SpecDoc 05/09/23 63