Commit 00a953fa authored by Robert Karlsson's avatar Robert Karlsson

Added functionality for PROFINET IO using Softing's Profinet Stack

parent 5ea0f459
......@@ -20,3 +20,5 @@
071211 rk mmi Added supgraph mcomp_pb_dp_slave.
080115 cs - Reading of Di, Ai and Ii can be disabled by setting ConversionOn in channel object to 0.
080229 rk - I/O-handling routines generalized and some routines moved to rt_io_bus.c
100708 rk - Added functionality for PROFINET IO using Softing Profinet Stack
ifndef link_rule_mk
link_rule_mk := 1
link = $(ldxx) -L$(elib_dir) $(elinkflags) $(domap) -o $(pwr_exe)/profinet_viewer_gtk \
link = $(ldxx) $(elinkflags) $(domap) -o $(pwr_exe)/profinet_viewer_gtk \
$(bld_dir)/profinet_viewer_gtk.o \
$(bld_dir)/pn_viewer_gtk.o $(bld_dir)/pn_viewernav_gtk.o \
$(bld_dir)/pn_viewer.o $(bld_dir)/pn_viewernav.o $(bld_dir)/pn_viewer_pnac.o\
$(wb_msg_eobjs) $(rt_msg_eobjs) \
$(pwr_eobj)/rt_io_user.o -L/usr/X11R6/lib \
-L/opt/gnome/lib \
-lpwr_flow_gtk -lpwr_flow -lpwr_rt \
-lpwr_cow_gtk -lpwr_cow -lpwr_co -lpwr_flow_gtk -lpwr_flow \
-lpwr_flow_gtk -lpwr_flow -lpwr_rt_gtk -lpwr_rt \
-lpwr_co_gtk -lpwr_co -lpwr_flow_gtk -lpwr_flow \
`pkg-config --libs gtk+-2.0` \
-lpwr_msg_dummy -lantlr \
-lcrypt -lrpcsvc -lpthread -lm -ldb_cxx -lz
-lcrypt -lrpcsvc -lpthread -lm -ldb_cxx -lz -lpnioif
endif
......@@ -23,10 +23,104 @@
#include "co_error.h"
#include "pn_viewer_pnac.h"
#include "profinet.h"
#include "pnak.h"
#include "sys/socket.h"
#include "sys/ioctl.h"
#include "net/if.h"
#include "netinet/in.h"
#include "arpa/inet.h"
#ifndef rt_pn_iface_h
# include "rt_pn_iface.h"
#endif
PnViewerPNAC::PnViewerPNAC( pwr_tStatus *sts)
{
// Init PNAC
int s;
struct ifreq ifr = {};
PnDeviceData *pn_dev_data;
T_PNAK_EVENT_SET_MODE pMode;
T_PNAK_WAIT_OBJECT wait_object;
/* Init PNAC */
local = new io_sAgentLocal;
pnak_init();
*sts = pnak_start_profistack(0, PNAK_CONTROLLER_MODE);
if (*sts != PNAK_OK) {
printf("Starting profistack returned with error code\n");
exit(0);
}
/* Get configs for device */
s = socket(AF_INET, SOCK_DGRAM, 0);
strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFADDR, &ifr) >= 0) {
strcpy(dev_data.ip_address, inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr));
}
if (ioctl(s, SIOCGIFNETMASK, &ifr) >= 0) {
strcpy(dev_data.subnet_mask, inet_ntoa(((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr));
}
sscanf(dev_data.ip_address, "%hhu.%hhu.%hhu.%hhu", &local->ipaddress[3], &local->ipaddress[2], &local->ipaddress[1], &local->ipaddress[0]) ;
sscanf(dev_data.subnet_mask, "%hhu.%hhu.%hhu.%hhu", &local->subnetmask[3], &local->subnetmask[2], &local->subnetmask[1], &local->subnetmask[0]) ;
strcpy(dev_data.device_name, "dumle");
dev_data.device_num = PN_DEVICE_REFERENCE_THIS_STATION;
strcpy(dev_data.device_text, "controller");
dev_data.vendor_id = 279; // Softing vendor id
dev_data.device_id = 0;
strcpy(dev_data.version, "1.0");
dev_data.byte_order = 0;
pn_dev_data = new PnDeviceData;
pn_dev_data->device_ref = PN_DEVICE_REFERENCE_THIS_STATION;
local->device_data.push_back(pn_dev_data);
/* Download config */
pack_download_req(&local->service_req_res, &dev_data, pn_dev_data->device_ref);
*sts = pnak_send_service_req_res(0, &local->service_req_res);
if (*sts == PNAK_OK) {
*sts = handle_service_con(local, 0);
if (*sts != PNAK_OK) {
/* Loop through devices and calculate offset for io */
}
}
/* Set identification */
pack_set_identification_req(&local->service_req_res);
*sts = pnak_send_service_req_res(0, &local->service_req_res);
if (*sts == PNAK_OK) {
*sts = handle_service_con(local, 0);
}
pMode.Mode = PNAK_MODE_ONLINE;
*sts = pnak_set_mode(0, &pMode);
wait_object = PNAK_WAIT_OBJECT_STATE_CHANGED;
*sts = pnak_wait_for_multiple_objects(0, &wait_object, PNAK_INFINITE_TIMEOUT);
if (*sts != PNAK_OK) {
printf("Setting state failed, sts: %d\r\n", *sts);
return;
}
*sts = 1;
}
......@@ -38,109 +132,102 @@ PnViewerPNAC::~PnViewerPNAC()
void PnViewerPNAC::fetch_devices( vector<PnDevice>& dev_vect)
{
PnDevice d1;
strcpy( d1.devname, "D1");
d1.ipaddress[3] = 168;
d1.ipaddress[2] = 192;
d1.ipaddress[1] = 101;
d1.ipaddress[0] = 56;
d1.macaddress[0] = 255;
d1.macaddress[1] = 255;
d1.macaddress[2] = 255;
d1.macaddress[3] = 36;
d1.macaddress[4] = 9;
d1.macaddress[5] = 22;
d1.vendorid = 42;
d1.deviceid = 769;
dev_vect.push_back(d1);
PnDevice d2;
strcpy( d2.devname, "D2");
d2.ipaddress[3] = 168;
d2.ipaddress[2] = 192;
d2.ipaddress[1] = 101;
d2.ipaddress[0] = 57;
d2.macaddress[0] = 255;
d2.macaddress[1] = 255;
d2.macaddress[2] = 255;
d2.macaddress[3] = 36;
d2.macaddress[4] = 9;
d2.macaddress[5] = 23;
d2.vendorid = 42;
d2.deviceid = 769;
dev_vect.push_back(d2);
PnDevice d3;
strcpy( d3.devname, "D3");
d3.ipaddress[3] = 168;
d3.ipaddress[2] = 192;
d3.ipaddress[1] = 101;
d3.ipaddress[0] = 58;
d3.macaddress[0] = 255;
d3.macaddress[1] = 255;
d3.macaddress[2] = 255;
d3.macaddress[3] = 36;
d3.macaddress[4] = 9;
d3.macaddress[5] = 24;
d3.vendorid = 42;
d3.deviceid = 769;
dev_vect.push_back(d3);
PnDevice d4;
strcpy( d4.devname, "D4");
d4.ipaddress[3] = 168;
d4.ipaddress[2] = 192;
d4.ipaddress[1] = 101;
d4.ipaddress[0] = 59;
d4.macaddress[0] = 255;
d4.macaddress[1] = 255;
d4.macaddress[2] = 255;
d4.macaddress[3] = 36;
d4.macaddress[4] = 9;
d4.macaddress[5] = 25;
d4.vendorid = 42;
d4.deviceid = 769;
dev_vect.push_back(d4);
PnDevice d5;
strcpy( d5.devname, "D5");
d5.ipaddress[3] = 168;
d5.ipaddress[2] = 192;
d5.ipaddress[1] = 101;
d5.ipaddress[0] = 60;
d5.macaddress[0] = 255;
d5.macaddress[1] = 255;
d5.macaddress[2] = 255;
d5.macaddress[3] = 36;
d5.macaddress[4] = 9;
d5.macaddress[5] = 26;
d5.vendorid = 266;
d5.deviceid = 1;
dev_vect.push_back(d5);
PnDevice d6;
strcpy( d6.devname, "D6");
d6.ipaddress[3] = 168;
d6.ipaddress[2] = 192;
d6.ipaddress[1] = 100;
d6.ipaddress[0] = 55;
d6.macaddress[0] = 200;
d6.macaddress[1] = 1;
d6.macaddress[2] = 0;
d6.macaddress[3] = 201;
d6.macaddress[4] = 202;
d6.macaddress[5] = 203;
d6.vendorid = 285;
d6.deviceid = 750;
dev_vect.push_back(d6);
PnDevice device;
unsigned int ii;
int sts;
while (1) {
for (ii = 0; ii < local->dev_info.size(); ii++) {
delete local->dev_info[ii];
}
local->dev_info.clear();
pack_get_los_req(&local->service_req_res);
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, 0);
if (sts == PNAK_OK) {
if (local->dev_info.size() > 0) {
for (ii = 0; ii < local->dev_info.size(); ii++) {
device.ipaddress[0] = local->dev_info[ii]->ipaddress[0];
device.ipaddress[1] = local->dev_info[ii]->ipaddress[1];
device.ipaddress[2] = local->dev_info[ii]->ipaddress[2];
device.ipaddress[3] = local->dev_info[ii]->ipaddress[3];
device.macaddress[0] = local->dev_info[ii]->macaddress[0];
device.macaddress[1] = local->dev_info[ii]->macaddress[1];
device.macaddress[2] = local->dev_info[ii]->macaddress[2];
device.macaddress[3] = local->dev_info[ii]->macaddress[3];
device.macaddress[4] = local->dev_info[ii]->macaddress[4];
device.macaddress[5] = local->dev_info[ii]->macaddress[5];
strncpy(device.devname, local->dev_info[ii]->devname, sizeof(device.devname));
device.vendorid = local->dev_info[ii]->vendorid;
device.deviceid = local->dev_info[ii]->deviceid;
dev_vect.push_back(device);
}
break;
} else continue;
}
}
}
/* pMode.Mode = PNAK_MODE_OFFLINE;
sts = pnak_set_mode(0, &pMode);
wait_object = PNAK_WAIT_OBJECT_STATE_CHANGED;
sts = pnak_wait_for_multiple_objects(0, &wait_object, PNAK_INFINITE_TIMEOUT);
if (sts != PNAK_OK) {
printf("Setting state failed, sts: %d\r\n", sts);
return;
} */
// if ( ...error... ) throw co_error_str( "Somethings is wrong...");
}
void PnViewerPNAC::set_device_properties( unsigned char *macaddress, unsigned char *ipaddress,
char *devname)
{
printf( "Set %s %hhu.%hhu.%hhu.%hhu\n", devname, ipaddress[3],
ipaddress[2], ipaddress[1], ipaddress[0]);
PnDevice device;
int sts;
PnDeviceInfo dev_info;
/* Set name and ip-address of device */
dev_info.ipaddress[0] = ipaddress[0];
dev_info.ipaddress[1] = ipaddress[1];
dev_info.ipaddress[2] = ipaddress[2];
dev_info.ipaddress[3] = ipaddress[3];
dev_info.subnetmask[0] = local->subnetmask[0];
dev_info.subnetmask[1] = local->subnetmask[1];
dev_info.subnetmask[2] = local->subnetmask[2];
dev_info.subnetmask[3] = local->subnetmask[3];
dev_info.macaddress[0] = macaddress[0];
dev_info.macaddress[1] = macaddress[1];
dev_info.macaddress[2] = macaddress[2];
dev_info.macaddress[3] = macaddress[3];
dev_info.macaddress[4] = macaddress[4];
dev_info.macaddress[5] = macaddress[5];
strncpy(dev_info.devname, devname, sizeof(dev_info.devname));
pack_set_device_name_req(&local->service_req_res, &dev_info);
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, 0);
}
pack_set_ip_settings_req(&local->service_req_res, &dev_info);
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, 0);
}
}
......@@ -31,6 +31,18 @@
# include "pn_viewernav.h"
#endif
# include "rt_io_base.h"
#ifndef rt_io_pn_locals_h
# include "rt_io_pn_locals.h"
#endif
#ifndef rt_pn_gsdml_data_h
# include "rt_pn_gsdml_data.h"
#endif
class PnViewerPNAC {
public:
......@@ -40,6 +52,9 @@ class PnViewerPNAC {
void fetch_devices( vector<PnDevice>& dev_vect);
void set_device_properties( unsigned char *macaddress, unsigned char *ipaddress,
char *devname);
GsdmlDeviceData dev_data;
io_sAgentLocal *local;
};
......
/******************************************************************************
SOFTING AG
Richard-Reitzner-Allee 6
D-85540 Haar
Phone: ++49-89-4 56 56-0
Fax: ++49-89-4 56 56-3 99
http://www.softing.com
Copyright (C) SOFTING AG 2005-2009. All Rights Reserved
Version: 1.60.0.00.release
******************************************************************************/
#ifndef __PNAK_H__
#define __PNAK_H__
/*****************************************************************************/
#if defined WIN32 || defined _WIN32
#pragma warning (disable : 4103) /* used #pragma pack to change alignment */
#pragma pack (push, 2)
#pragma warning (default : 4103)
#ifndef PACK_WORD_ALIGNMENT
#define PACK_WORD_ALIGNMENT(Struct) Struct
#endif
#ifndef PACK_BYTE_ALIGNMENT
#define PACK_BYTE_ALIGNMENT(Struct) Struct
#endif
#else
#ifdef __GNUC__
#ifndef PACK_WORD_ALIGNMENT
#define PACK_WORD_ALIGNMENT(Struct) __attribute__ ((packed, aligned (2))) Struct
#endif
#ifndef PACK_BYTE_ALIGNMENT
#define PACK_BYTE_ALIGNMENT(Struct) __attribute__ ((packed, aligned (1))) Struct
#endif
#else
#error CAUTION: set word structure alignment
#endif
#endif
/******************************************************************************
ACCESS KIT USER INTERFACE
******************************************************************************/
#define MAX_NUMBER_SUPPORTED_DEVICES (PN_U16) 256u
#define _BITSET256_RESET_BIT(pBS,BitNr) (((pBS)) [(BitNr) >> 3] &= ~(1u << ((BitNr) & 7u)))
#define _BITSET256_SET_BIT(pBS,BitNr) (((pBS)) [(BitNr) >> 3] |= 1u << ((BitNr) & 7u) )
#define _BITSET256_IS_BIT_SET(pBS,BitNr) ((((pBS)) [(BitNr) >> 3]) & (1u << ((BitNr) & 7u) ))
/*---------------------------------------------------------------------------*/
#ifndef _MAX
#define _MAX(A,B) ((A) > (B) ? (A) : (B))
#endif
#ifndef _MIN
#define _MIN(A,B) ((A) < (B) ? (A) : (B))
#endif
/*---------------------------------------------------------------------------*/
typedef enum _T_PNAK_RESULT
{
PNAK_OK = 0,
/*-------------------------------------------------------------------------*/
PNAK_NO_EXCEPTION_THROWN,
PNAK_EXCEPTION_THROWN,
PNAK_NO_NOTIFICATION_RECEIVED,
PNAK_NOTIFICATION_RECEIVED,
/*-------------------------------------------------------------------------*/
PNAK_ERR_FATAL_ERROR,
PNAK_ERR_INVALID_CHANNEL_ID,
PNAK_ERR_CHANNEL_ALREADY_IN_USE,
PNAK_ERR_CHANNEL_NOT_IN_USE,
PNAK_ERR_INVALID_POINTER_VALUE,
PNAK_ERR_SERVICE_IF_ALREADY_BUSY,
PNAK_ERR_INVALID_DATA_SIZE,
PNAK_ERR_INVALID_NUMBER_OF_SERVICES,
PNAK_ERR_INVALID_SERVICE_LENGTH,
PNAK_ERR_INVALID_SERVICE_OFFSET,
PNAK_ERR_INVALID_PARAMETER,
PNAK_ERR_MODE_DOES_NOT_SUPPORT_FUNCTION,
PNAK_ERR_STARTUP_FAILES,
PNAK_ERR_INVALID_IOCR,
PNAK_ERR_IOCR_ACCESS_DENIED,
PNAK_ERR_NOT_SUPPORTED,
/*--- errors for host-controller-systems ----------------------------------*/
PNAK_ERR_MEM_ALLOC_FAIL,
PNAK_ERR_NO_PROTOCOL_SOFTWARE_RESPONSE,
PNAK_ERR_INTERFACE_VERSION_CONFLICT,
/*--- errors for snmp agents ----------------------------------------------*/
PNAK_ERR_SNMP_TOO_BIG,
PNAK_ERR_SNMP_NO_SUCH_NAME,
PNAK_ERR_SNMP_BAD_VALUE,
PNAK_ERR_SNMP_READ_ONLY,
PNAK_ERR_SNMP_UNSPECIFIC,
PNAK_ERR_SNMP_NO_ACCESS,
PNAK_ERR_SNMP_WRONG_TYPE,
PNAK_ERR_SNMP_WRONG_LENGTH,
PNAK_ERR_SNMP_WRONG_ENCODING,
PNAK_ERR_SNMP_WRONG_VALUE,
PNAK_ERR_SNMP_NO_CREATION,
PNAK_ERR_SNMP_INCONSISTENT_VALUE,
PNAK_ERR_SNMP_RESOURCE_UNAVAILABLE,
PNAK_ERR_SNMP_COMMIT_FAILED,
PNAK_ERR_SNMP_UNDO_FAILED,
PNAK_ERR_SNMP_AUTHORIZATION_ERROR,
PNAK_ERR_SNMP_NOT_WRITABLE,
PNAK_ERR_SNMP_INCONSISTENT_NAME,
PNAK_ERR_SNMP_CONTEXT_NO_SUCH_OBJECT,
PNAK_ERR_SNMP_CONTEXT_NO_SUCH_INSTANCE
} T_PNAK_RESULT;
/*---------------------------------------------------------------------------*/
typedef unsigned char T_BITSET_256 [32];
/*---------------------------------------------------------------------------*/
typedef unsigned short T_PNAK_EXCEPTION_SOURCE;
#define PNAK_EXCEPTION_SOURCE_IS_STACK 0u
#define PNAK_EXCEPTION_SOURCE_IS_PNAK 1u
#define PNAK_EXCEPTION_SOURCE_IS_APPL 2u
typedef struct _T_PNAK_EXCEPTION
{
T_PNAK_EXCEPTION_SOURCE Source;
unsigned short ChannelId;
unsigned short ModuleId;
unsigned short FileId;
unsigned short ErrorId;
unsigned long UserSpecificParameter;
char UserString [22];
} PACK_WORD_ALIGNMENT (T_PNAK_EXCEPTION);
/*---------------------------------------------------------------------------*/
typedef unsigned long T_PNAK_OID;
/*---------------------------------------------------------------------------*/
typedef unsigned short T_PNAK_MODE_ID;
#define PNAK_UNINITIALIZED_MODE 0
#define PNAK_CONTROLLER_MODE 1
#define PNAK_DEVICE_MODE 2
#define PNAK_SUPERVISOR_MODE 3
/*---------------------------------------------------------------------------*/
#define PNAK_VERSION_STRING_LENGTH 42
typedef struct _T_PNAK_VERSION
{
unsigned short IfId;
unsigned short HostIfId;
unsigned short HostConfigIfId;
unsigned short ExceptionIfId;
unsigned short ServiceIfId;
unsigned short EventIfId;
unsigned short StatisticIfId;
unsigned short DataIfId;
char VersionString [PNAK_VERSION_STRING_LENGTH];
} PACK_WORD_ALIGNMENT (T_PNAK_VERSION);
typedef struct _T_PNAK_VERSIONS
{
T_PNAK_VERSION Firmware;
T_PNAK_VERSION Pnak;
} PACK_WORD_ALIGNMENT (T_PNAK_VERSIONS);
/*---------------------------------------------------------------------------*/
#define PNAK_INFINITE_TIMEOUT 0xFFFFFFFFuL
#define PNAK_MAX_NUMBER_WAIT_OBJECTS 32uL
typedef unsigned long T_PNAK_TIMEOUT;
typedef unsigned long T_PNAK_WAIT_OBJECT;
#define PNAK_WAIT_OBJECT_EXCEPTION ((T_PNAK_WAIT_OBJECT) 0x00000001uL)
#define PNAK_WAIT_OBJECT_STATE_CHANGED ((T_PNAK_WAIT_OBJECT) 0x00000002uL)
#define PNAK_WAIT_OBJECT_ALARM ((T_PNAK_WAIT_OBJECT) 0x00000004uL)
#define PNAK_WAIT_OBJECT_ALARM_ACK ((T_PNAK_WAIT_OBJECT) 0x00000008uL)
#define PNAK_WAIT_OBJECT_DEVICE_STATE_CHANGED ((T_PNAK_WAIT_OBJECT) 0x00000010uL)
#define PNAK_WAIT_OBJECT_ETHERNET_STATE_CHANGED ((T_PNAK_WAIT_OBJECT) 0x00000020uL)
#define PNAK_WAIT_OBJECT_PROVIDER_DATA_UPDATED ((T_PNAK_WAIT_OBJECT) 0x00000040uL)
#define PNAK_WAIT_OBJECT_CONSUMER_DATA_CHANGED ((T_PNAK_WAIT_OBJECT) 0x00000080uL)
#define PNAK_WAIT_OBJECT_SERVICE_IND ((T_PNAK_WAIT_OBJECT) 0x00000100uL)
#define PNAK_WAIT_OBJECT_SERVICE_CON ((T_PNAK_WAIT_OBJECT) 0x00000200uL)
#define PNAK_WAIT_OBJECT_SERVICE_REQ_RES_HANDLED ((T_PNAK_WAIT_OBJECT) 0x00000400uL)
#define PNAK_WAIT_OBJECT_CHANNEL_CLOSED ((T_PNAK_WAIT_OBJECT) 0x00200000uL)
#define PNAK_WAIT_OBJECT_INTERRUPTED ((T_PNAK_WAIT_OBJECT) 0x00400000uL)
#define PNAK_USER_WAIT_OBJECT_1 ((T_PNAK_WAIT_OBJECT) 0x00800000uL)
#define PNAK_USER_WAIT_OBJECT_2 ((T_PNAK_WAIT_OBJECT) 0x01000000uL)
#define PNAK_USER_WAIT_OBJECT_3 ((T_PNAK_WAIT_OBJECT) 0x02000000uL)
#define PNAK_USER_WAIT_OBJECT_4 ((T_PNAK_WAIT_OBJECT) 0x04000000uL)
#define PNAK_USER_WAIT_OBJECT_5 ((T_PNAK_WAIT_OBJECT) 0x08000000uL)
#define PNAK_USER_WAIT_OBJECT_6 ((T_PNAK_WAIT_OBJECT) 0x10000000uL)
#define PNAK_USER_WAIT_OBJECT_7 ((T_PNAK_WAIT_OBJECT) 0x20000000uL)
#define PNAK_USER_WAIT_OBJECT_8 ((T_PNAK_WAIT_OBJECT) 0x40000000uL)
#define PNAK_WAIT_TIMEOUT ((T_PNAK_WAIT_OBJECT) 0x80000000uL)
#define PNAK_WAIT_OBJECTS_SERVICE (PNAK_WAIT_OBJECT_SERVICE_CON | \
PNAK_WAIT_OBJECT_SERVICE_IND | \
PNAK_WAIT_OBJECT_SERVICE_REQ_RES_HANDLED)
#define PNAK_WAIT_OBJECTS_EVENT_IND (PNAK_WAIT_OBJECT_STATE_CHANGED | \
PNAK_WAIT_OBJECT_ALARM | \
PNAK_WAIT_OBJECT_ALARM_ACK | \
PNAK_WAIT_OBJECT_DEVICE_STATE_CHANGED | \
PNAK_WAIT_OBJECT_ETHERNET_STATE_CHANGED)
#define PNAK_WAIT_OBJECTS_DATA_IND (PNAK_WAIT_OBJECT_PROVIDER_DATA_UPDATED |\
PNAK_WAIT_OBJECT_CONSUMER_DATA_CHANGED)
#define PNAK_WAIT_OBJECTS_OTHER (PNAK_WAIT_OBJECT_EXCEPTION | \
PNAK_WAIT_OBJECT_CHANNEL_CLOSED | \
PNAK_WAIT_OBJECT_INTERRUPTED)
#define PNAK_WAIT_OBJECTS_USER (PNAK_USER_WAIT_OBJECT_1 | \
PNAK_USER_WAIT_OBJECT_2 | \
PNAK_USER_WAIT_OBJECT_3 | \
PNAK_USER_WAIT_OBJECT_4 | \
PNAK_USER_WAIT_OBJECT_5 | \
PNAK_USER_WAIT_OBJECT_6 | \
PNAK_USER_WAIT_OBJECT_7 | \
PNAK_USER_WAIT_OBJECT_8)
#define PNAK_WAIT_OBJECTS_ALL (PNAK_WAIT_OBJECTS_OTHER | \
PNAK_WAIT_OBJECTS_EVENT_IND | \
PNAK_WAIT_OBJECTS_DATA_IND | \
PNAK_WAIT_OBJECTS_SERVICE | \
PNAK_WAIT_OBJECTS_USER | \
PNAK_WAIT_TIMEOUT)
/*=============================================================================
SERVICE INTERFACE
=============================================================================*/
typedef unsigned char T_PNAK_SERVICE_PRIMITIVE;
#define PNAK_SERVICE_REQ (T_PNAK_SERVICE_PRIMITIVE) 0x01u
#define PNAK_SERVICE_RES (T_PNAK_SERVICE_PRIMITIVE) 0x02u
#define PNAK_SERVICE_CON (T_PNAK_SERVICE_PRIMITIVE) 0x03u
#define PNAK_SERVICE_IND (T_PNAK_SERVICE_PRIMITIVE) 0x04u
typedef unsigned char T_PNAK_SERVICE_RESULT;
#define PNAK_RESULT_POS (T_PNAK_SERVICE_RESULT) 0x00u
#define PNAK_RESULT_NEG (T_PNAK_SERVICE_RESULT) 0x01u
typedef struct _T_PNAK_SERVICE_DESCRIPTION
{
unsigned short DeviceRef;
unsigned char Instance;
unsigned char Service;
T_PNAK_SERVICE_PRIMITIVE Primitive;
T_PNAK_SERVICE_RESULT Result;
unsigned short ClientId;
unsigned short InvokeId;
unsigned short DataLength;
} PACK_WORD_ALIGNMENT (T_PNAK_SERVICE_DESCRIPTION);
/*---------------------------------------------------------------------------*/
#define PNAK_MAX_NUMBER_REQ_SERVICES 52u
#define PNAK_MAX_NUMBER_CON_SERVICES 52u
#define PNAK_MAX_NUMBER_IND_SERVICES 52u
#define PNAK_SERVICE_REQ_CHANNEL_SIZE (PN_U16) 8086u
#define PNAK_SERVICE_CON_CHANNEL_SIZE (PN_U16) 8086u
#define PNAK_SERVICE_IND_CHANNEL_SIZE (PN_U16) 8086u
/*=== SERVICE REQUEST/RESPONSE ==============================================*/
typedef struct _T_PNAK_SERVICE_REQ_RES_ENTRY
{
unsigned short ServiceOffset;
} PACK_WORD_ALIGNMENT (T_PNAK_SERVICE_REQ_RES_ENTRY);
/*---------------------------------------------------------------------------*/
typedef struct _T_PNAK_SERVICE_REQ_RES
{
unsigned short NumberEntries;
T_PNAK_SERVICE_REQ_RES_ENTRY ServiceEntry [PNAK_MAX_NUMBER_REQ_SERVICES];
unsigned char ServiceChannel [PNAK_SERVICE_REQ_CHANNEL_SIZE];
} PACK_WORD_ALIGNMENT (T_PNAK_SERVICE_REQ_RES);
/*=== SERVICE CONFIRMATION ==================================================*/
typedef struct _T_PNAK_SERVICE_CON_ENTRY
{
unsigned short ServiceOffset;
} PACK_WORD_ALIGNMENT (T_PNAK_SERVICE_CON_ENTRY);
/*---------------------------------------------------------------------------*/
typedef struct _T_PNAK_SERVICE_CON
{
unsigned short NumberEntries;
T_PNAK_SERVICE_CON_ENTRY ServiceEntry [PNAK_MAX_NUMBER_CON_SERVICES];
unsigned char ServiceChannel [PNAK_SERVICE_CON_CHANNEL_SIZE];
} PACK_WORD_ALIGNMENT (T_PNAK_SERVICE_CON);
/*=== SERVICE INDICATION ====================================================*/
typedef struct _T_PNAK_SERVICE_IND_ENTRY
{
unsigned short ServiceOffset;
} PACK_WORD_ALIGNMENT (T_PNAK_SERVICE_IND_ENTRY);
/*---------------------------------------------------------------------------*/
typedef struct _T_PNAK_SERVICE_IND
{
unsigned short NumberEntries;
T_PNAK_SERVICE_IND_ENTRY ServiceEntry [PNAK_MAX_NUMBER_IND_SERVICES];
unsigned char ServiceChannel [PNAK_SERVICE_IND_CHANNEL_SIZE];
} PACK_WORD_ALIGNMENT (T_PNAK_SERVICE_IND);
/*=============================================================================
EVENT INTERFACE
=============================================================================*/
typedef unsigned short T_PNAK_MODE;
#define PNAK_MODE_OFFLINE (T_PNAK_MODE) 0u
#define PNAK_MODE_ONLINE (T_PNAK_MODE) 1u
/*=== EVENT REQUEST ==========================================================*/
typedef struct _T_PNAK_EVENT_SET_MODE
{
T_PNAK_MODE Mode;
} PACK_WORD_ALIGNMENT (T_PNAK_EVENT_SET_MODE);
/*---------------------------------------------------------------------------*/
typedef struct _T_PNAK_EVENT_SET_DEVICE_STATE
{
T_BITSET_256 ActivateDeviceReference;
T_BITSET_256 DeactivateDeviceReference;
} PACK_WORD_ALIGNMENT (T_PNAK_EVENT_SET_DEVICE_STATE);
/*=== EVENT INDICATION ======================================================*/
typedef enum _T_PNAK_STATE
{
PNAK_STATE_OK = 0,
PNAK_STATE_NO_PARAMETER,
PNAK_STATE_DOUBLE_ADDRESS_ERROR,
PNAK_STATE_HARDWARE_ERROR,
PNAK_STATE_APPL_WATCHDOG_EXPIRED,
PNAK_STATE_ETH_FAILURE,
PNAK_STATE_UDP_FAILURE,
PNAK_STATE_DUPLICATE_NAME_ERROR
} T_PNAK_STATE;
/*---------------------------------------------------------------------------*/
typedef struct _T_PNAK_EVENT_STATE
{
T_PNAK_MODE Mode;
T_PNAK_STATE State;
} PACK_WORD_ALIGNMENT (T_PNAK_EVENT_STATE);
/*---------------------------------------------------------------------------*/
typedef struct _T_PNAK_EVENT_ALARM
{
T_BITSET_256 DeviceReference;
} PACK_WORD_ALIGNMENT (T_PNAK_EVENT_ALARM);
/*---------------------------------------------------------------------------*/
typedef struct _T_PNAK_EVENT_ALARM_ACK
{
T_BITSET_256 DeviceReference;
} PACK_WORD_ALIGNMENT (T_PNAK_EVENT_ALARM_ACK);
/*---------------------------------------------------------------------------*/
#define PNAK_DEVICE_STATE_DEACTIVATED 0x00u
#define PNAK_DEVICE_STATE_FIND_DEVICE 0x01u
#define PNAK_DEVICE_STATE_CONNECTION_ESTABLISHMENT 0x02u
#define PNAK_DEVICE_STATE_CONNECTED 0x04u
#define PNAK_DEVICE_STATE_CONNECT_ERROR 0x10u
#define PNAK_DEVICE_STATE_WRITE_ERROR 0x20u
#define PNAK_DEVICE_STATE_CONTROL_ERROR 0x40u
#define PNAK_DEVICE_STATE_CLOSE_PENDING 0x80u
#define PNAK_DEVICE_STATE_ERROR_MASK (PNAK_DEVICE_STATE_CONNECT_ERROR | \
PNAK_DEVICE_STATE_WRITE_ERROR | \
PNAK_DEVICE_STATE_CONTROL_ERROR)
typedef struct _T_PNAK_EVENT_DEVICE_STATE
{
unsigned char State [MAX_NUMBER_SUPPORTED_DEVICES];
} PACK_WORD_ALIGNMENT (T_PNAK_EVENT_DEVICE_STATE);
/*=== EVENT INDICATION MASK =================================================*/
#define PNAK_EVENT_STATE_CHANGED 0x00000001uL
#define PNAK_EVENT_DEVICE_STATE_CHANGED 0x00000002uL
#define PNAK_EVENT_ALARM 0x00000004uL
#define PNAK_EVENT_MASK (PNAK_EVENT_STATE_CHANGED | \
PNAK_EVENT_ALARM | \
PNAK_EVENT_DEVICE_STATE_CHANGED)
typedef unsigned long T_PNAK_EVENT_REG;
typedef struct _T_PNAK_EVENT_IND_MASK
{
T_PNAK_EVENT_REG EventMaskReg;
} PACK_WORD_ALIGNMENT (T_PNAK_EVENT_IND_MASK);
/*=============================================================================
DATA INTERFACE
=============================================================================*/
/*=== DATA INDICATION =======================================================*/
typedef struct _T_PNAK_DATA_CONSUMER_DATA_CHANGED
{
T_BITSET_256 DeviceReference;
} PACK_WORD_ALIGNMENT (T_PNAK_DATA_CONSUMER_DATA_CHANGED);
/*---------------------------------------------------------------------------*/
typedef struct _T_PNAK_DATA_PROVIDER_DATA_UPDATED
{
T_BITSET_256 DeviceReference;
} PACK_WORD_ALIGNMENT (T_PNAK_DATA_PROVIDER_DATA_UPDATED);
/*=== DATA INDICATION MASK ==================================================*/
#define PNAK_DATA_EVENT_CYCLIC_TRANSFER_FINISHED 0x00000001uL
#define PNAK_DATA_EVENT_CONSUMER_DATA_CHANGED 0x00000002uL
#define PNAK_DATA_EVENT_PROVIDER_DATA_UPDATED 0x00000004uL
typedef unsigned long T_PNAK_DATA_EVENT_REG;
typedef struct _T_PNAK_DATA_IND_MASK
{
T_PNAK_DATA_EVENT_REG EventMaskReg;
} PACK_WORD_ALIGNMENT (T_PNAK_DATA_IND_MASK);
/*---------------------------------------------------------------------------*/
#define PNAK_IOXS_STATUS_NO_EXTENTION_FOLLOWS 0x00u
#define PNAK_IOXS_STATUS_DETECTED_BY_SUBSLOT 0x00u
#define PNAK_IOXS_STATUS_DETECTED_BY_SLOT 0x20u
#define PNAK_IOXS_STATUS_DETECTED_BY_DEVICE 0x40u
#define PNAK_IOXS_STATUS_DETECTED_BY_CONTROLLER 0x60u
#define PNAK_IOXS_STATUS_DATA_BAD 0x00u
#define PNAK_IOXS_STATUS_DATA_GOOD 0x80u
/*---------------------------------------------------------------------------*/
/* now we support only one controller-device and
* one supervisor-device connection, if we want later
* also support further connections we must increase
* the max number and add specific statemachines in the
* object data structure
*/
#define MAX_NUMBER_CMDEV_CONNECTIONS 2u
/******************************************************************************
FUNCTION DECLARATION
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/*--- initialization/termination functions ----------------------------------*/
extern void pnak_init (void);
extern void pnak_term (void);
extern T_PNAK_RESULT pnak_start_profistack (unsigned short, const T_PNAK_MODE_ID);
extern T_PNAK_RESULT pnak_stop_profistack (unsigned short);
/*--- General interface functions -------------------------------------------*/
extern T_PNAK_RESULT pnak_wait_for_multiple_objects (unsigned short, T_PNAK_WAIT_OBJECT*, T_PNAK_TIMEOUT);
extern T_PNAK_RESULT pnak_set_multiple_objects (unsigned short, const T_PNAK_WAIT_OBJECT);
extern T_PNAK_RESULT pnak_mask_multiple_objects (unsigned short, const T_PNAK_WAIT_OBJECT);
extern T_PNAK_RESULT pnak_get_exception (unsigned short, T_PNAK_EXCEPTION*);
extern T_PNAK_RESULT pnak_get_version (unsigned short, T_PNAK_VERSIONS*);
extern T_PNAK_RESULT pnak_snmp_get_data (unsigned short, T_PNAK_OID*, void*, unsigned long*, unsigned long*, unsigned char, PN_BOOL);
extern T_PNAK_RESULT pnak_snmp_check_data (unsigned short, T_PNAK_OID*, void*, unsigned long, unsigned long, unsigned char);
extern T_PNAK_RESULT pnak_snmp_set_data (unsigned short, T_PNAK_OID*, void*, unsigned long, unsigned long);
/*--- Service interface functions -------------------------------------------*/
extern T_PNAK_RESULT pnak_send_service_req_res (unsigned short, const T_PNAK_SERVICE_REQ_RES*);
extern T_PNAK_RESULT pnak_get_service_ind (unsigned short, T_PNAK_SERVICE_IND*);
extern T_PNAK_RESULT pnak_get_service_con (unsigned short, T_PNAK_SERVICE_CON*);
/*--- Event interface functions ---------------------------------------------*/
extern T_PNAK_RESULT pnak_set_mode (unsigned short, const T_PNAK_EVENT_SET_MODE*);
extern T_PNAK_RESULT pnak_set_device_state (unsigned short, const T_PNAK_EVENT_SET_DEVICE_STATE*);
extern T_PNAK_RESULT pnak_get_state (unsigned short, T_PNAK_EVENT_STATE*);
extern T_PNAK_RESULT pnak_get_device_state_ind (unsigned short, T_PNAK_EVENT_DEVICE_STATE*);
extern T_PNAK_RESULT pnak_get_alarm_ind (unsigned short, T_PNAK_EVENT_ALARM*);
extern T_PNAK_RESULT pnak_get_alarm_ack_ind (unsigned short, T_PNAK_EVENT_ALARM_ACK*);
/*--- Data interface functions ----------------------------------------------*/
extern T_PNAK_RESULT pnak_set_iocr_data (unsigned short, unsigned short, const unsigned char*, unsigned short);
extern T_PNAK_RESULT pnak_get_iocr_data (unsigned short, unsigned short, unsigned char*, unsigned short*, unsigned char*);
extern T_PNAK_RESULT pnak_get_consumer_data_changed_ind (unsigned short, T_PNAK_DATA_CONSUMER_DATA_CHANGED*);
extern T_PNAK_RESULT pnak_get_provider_data_updated (unsigned short, T_PNAK_DATA_PROVIDER_DATA_UPDATED*);
/*=============================================================================
CALLBACK INTERFACE
=============================================================================*/
typedef int (*T_PNAK_WAIT_OBJECT_CALLBACK) (unsigned short, T_PNAK_WAIT_OBJECT);
typedef int (*T_PNAK_HW_START_CALLBACK) (unsigned short, T_PNAK_MODE_ID, void*);
typedef void (*T_PROVIDER_CALLBACK) (unsigned short, unsigned short, unsigned char*, unsigned short);
typedef void (*T_CONSUMER_CALLBACK) (unsigned short, unsigned short, const unsigned char*, unsigned short, unsigned char);
extern T_PNAK_RESULT pnak_register_provider_callback (unsigned short, T_PROVIDER_CALLBACK);
extern T_PNAK_RESULT pnak_unregister_provider_callback (unsigned short);
extern T_PNAK_RESULT pnak_register_consumer_callback (unsigned short, T_CONSUMER_CALLBACK);
extern T_PNAK_RESULT pnak_unregister_consumer_callback (unsigned short);
#ifdef __cplusplus
}
#endif
/*****************************************************************************/
#if defined WIN32 || defined _WIN32
#pragma warning (disable : 4103) /* used #pragma pack to reset alignment */
#pragma pack(pop)
#pragma warning (default : 4103)
#else
#ifdef __GNUC__
/* nothing to do */
#else
#error CAUTION: set default structure alignment
#endif
#endif
/*****************************************************************************/
#endif /* __PNAK_H__ */
/*****************************************************************************/
/* vim: set nu ts=2 et nowrap: */
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* rt_io_m_pncontrollersoftingpnak.cpp -- io methods for the profinet master object
The PnControllerSoftingPNAK object serves as agent for one Profinet network
The profinet stack we use is a Profinet stack from Softing
*/
#include <vector>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pwr.h"
#include "co_cdh.h"
#include "pwr_baseclasses.h"
#include "pwr_profibusclasses.h"
#include "rt_io_base.h"
#include "rt_io_bus.h"
#include "rt_io_msg.h"
#include "rt_errh.h"
#include "rt_io_agent_init.h"
#include "rt_pb_msg.h"
#include "profinet.h"
#include "pnak.h"
#include "co_dcli.h"
#include "rt_pn_gsdml_data.h"
#include "rt_io_pn_locals.h"
#include "rt_pn_iface.h"
#include "sys/socket.h"
#include "sys/ioctl.h"
#include "net/if.h"
#include "netinet/in.h"
#include "arpa/inet.h"
static int count;
static pwr_tStatus IoAgentInit (
io_tCtx ctx,
io_sAgent *ap
);
static pwr_tStatus IoAgentRead (
io_tCtx ctx,
io_sAgent *ap
);
static pwr_tStatus IoAgentWrite (
io_tCtx ctx,
io_sAgent *ap
);
static pwr_tStatus IoAgentClose (
io_tCtx ctx,
io_sAgent *ap
);
/*----------------------------------------------------------------------------*\
Init method for the Pb_profiboard agent
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoAgentInit (
io_tCtx ctx,
io_sAgent *ap
)
{
pwr_sClass_PnControllerSoftingPNAK *op;
pwr_tUInt16 sts;
io_sAgentLocal *local;
io_sRackLocal *r_local;
char fname[196];
char hname[40];
char *env;
vector<GsdmlDeviceData *> device_vect;
GsdmlDeviceData *dev_data;
PnDeviceData *pn_dev_data;
PnIOCRData *pn_iocr_data;
PnModuleData *pn_slot_data;
PnSubmoduleData *pn_subslot_data;
unsigned short ii, jj, kk, ll, offset_inputs, offset_outputs, type;
unsigned short num_modules = 0;
int s;
struct ifreq ifr = {};
io_sRack *slave_list;
count=0;
/* Allocate area for local data structure */
ap->Local = (io_sAgentLocal *) new io_sAgentLocal;
if (!ap->Local) {
// errh_Error( "ERROR config Profibus DP Master %s - %s", ap->Name, "calloc");
return IO__ERRINIDEVICE;
}
local = (io_sAgentLocal *) ap->Local;
op = (pwr_sClass_PnControllerSoftingPNAK *) ap->op;
op->Status = PB__NOTINIT;
/* Initialize interface */
errh_Info( "Initializing interface for Profinet IO Master %s", ap->Name);
/* Add master as a device */
dev_data = new GsdmlDeviceData;
/* Get configs for device */
gethostname(hname, 40);
s = socket(AF_INET, SOCK_DGRAM, 0);
strncpy(ifr.ifr_name, "eth1", sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFADDR, &ifr) >= 0) {
strcpy(dev_data->ip_address, inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr));
}
if (ioctl(s, SIOCGIFNETMASK, &ifr) >= 0) {
strcpy(dev_data->subnet_mask, inet_ntoa(((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr));
}
sscanf(dev_data->ip_address, "%hhu.%hhu.%hhu.%hhu", &local->ipaddress[3], &local->ipaddress[2], &local->ipaddress[1], &local->ipaddress[0]) ;
sscanf(dev_data->subnet_mask, "%hhu.%hhu.%hhu.%hhu", &local->subnetmask[3], &local->subnetmask[2], &local->subnetmask[1], &local->subnetmask[0]) ;
strcpy(dev_data->device_name, hname);
dev_data->device_num = PN_DEVICE_REFERENCE_THIS_STATION;
strcpy(dev_data->device_text, "controller");
dev_data->vendor_id = 279; // Softing vendor id
dev_data->device_id = 0;
strcpy(dev_data->version, "1.0");
dev_data->byte_order = 0;
device_vect.push_back(dev_data);
pn_dev_data = new PnDeviceData;
pn_dev_data->device_ref = PN_DEVICE_REFERENCE_THIS_STATION;
local->device_data.push_back(pn_dev_data);
env = getenv("pwrp_load");
/* Iterate over the slaves. */
for (slave_list = ap->racklist, ii = 0; slave_list != NULL;
slave_list = slave_list->next, ii++) {
dev_data = new GsdmlDeviceData;
pn_dev_data = new PnDeviceData;
sprintf(fname, "%s/pwr_pn_%s.xml", env, cdh_ObjidToFnString(NULL, slave_list->Objid ));
dev_data->read(fname);
device_vect.push_back(dev_data);
pn_dev_data->device_ref = ii + 1;
for (jj = 0; jj < dev_data->iocr_data.size(); jj++) {
pn_iocr_data = new PnIOCRData;
pn_iocr_data->type = dev_data->iocr_data[jj]->type;
pn_dev_data->iocr_data.push_back(pn_iocr_data);
}
num_modules = 0;
for (jj = 0; jj < dev_data->slot_data.size(); jj++) {
if ((dev_data->slot_data[jj]->module_enum_number != 0) ||
(jj == 0))
num_modules++;
else break;
}
for (jj = 0; jj < num_modules; jj++) {
pn_slot_data = new PnModuleData;
pn_slot_data->slot_number = dev_data->slot_data[jj]->slot_number;
pn_slot_data->ident_number = dev_data->slot_data[jj]->module_ident_number;
pn_dev_data->module_data.push_back(pn_slot_data);
for (kk = 0; kk < dev_data->slot_data[jj]->subslot_data.size(); kk++) {
pn_subslot_data = new PnSubmoduleData;
pn_subslot_data->subslot_number = dev_data->slot_data[jj]->subslot_data[kk]->subslot_number;
pn_subslot_data->ident_number = dev_data->slot_data[jj]->subslot_data[kk]->submodule_ident_number;
if (dev_data->slot_data[jj]->subslot_data[kk]->io_input_length > 0) {
pn_subslot_data->io_in_data_length = dev_data->slot_data[jj]->subslot_data[kk]->io_input_length;
pn_subslot_data->type = PROFINET_IO_SUBMODULE_TYPE_INPUT ;
}
if (dev_data->slot_data[jj]->subslot_data[kk]->io_output_length > 0) {
pn_subslot_data->io_out_data_length = dev_data->slot_data[jj]->subslot_data[kk]->io_output_length;
pn_subslot_data->type |= PROFINET_IO_SUBMODULE_TYPE_OUTPUT;
}
if ((dev_data->slot_data[jj]->subslot_data[kk]->io_output_length > 0) &&
(dev_data->slot_data[jj]->subslot_data[kk]->io_input_length > 0)) {
pn_subslot_data->type |= PROFINET_IO_SUBMODULE_TYPE_INPUT_AND_OUTPUT;
}
pn_dev_data->module_data[jj]->submodule_data.push_back(pn_subslot_data);
}
}
local->device_data.push_back(pn_dev_data);
}
/* Start profistack */
pnak_init();
sts = pnak_start_profistack(0, PNAK_CONTROLLER_MODE);
if (sts != PNAK_OK) {
op->Status = PB__INITFAIL;
errh_Error( "Starting profistack returned with error code: %d", sts);
return IO__ERRINIDEVICE;
}
/* Download configuration for all devices */
for (ii = 0; ii < device_vect.size(); ii++) {
// for (ii = 0; ii < 1; ii++) {
pack_download_req(&local->service_req_res, device_vect[ii], local->device_data[ii]->device_ref);
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, ap);
if (sts == PNAK_OK) {
/* Loop through devices and calculate offset for io */
for (jj = 0; jj < local->device_data[ii]->iocr_data.size(); jj++) {
offset_inputs = 0;
offset_outputs = 0;
type = local->device_data[ii]->iocr_data[jj]->type;
for (kk = 0; kk < local->device_data[ii]->module_data.size(); kk++) {
for (ll = 0; ll < local->device_data[ii]->module_data[kk]->submodule_data.size(); ll++) {
PnSubmoduleData *submodule;
submodule = local->device_data[ii]->module_data[kk]->submodule_data[ll];
if (submodule->type & type) {
if ((submodule->type == PROFINET_IO_SUBMODULE_TYPE_INPUT) ||
(submodule->type == PROFINET_IO_SUBMODULE_TYPE_INPUT_AND_OUTPUT)) {
submodule->offset_clean_io_in = offset_inputs;
offset_inputs += submodule->io_in_data_length;
}
if ((submodule->type == PROFINET_IO_SUBMODULE_TYPE_OUTPUT) ||
(submodule->type == PROFINET_IO_SUBMODULE_TYPE_INPUT_AND_OUTPUT)) {
submodule->offset_clean_io_out = offset_outputs;
offset_outputs += submodule->io_out_data_length;
}
}
}
}
local->device_data[ii]->iocr_data[jj]->clean_io_data = (unsigned char *) calloc(1, offset_inputs + offset_outputs);
local->device_data[ii]->iocr_data[jj]->clean_io_data_length = offset_inputs + offset_outputs;
}
}
}
}
/* Loop trough devices and set up i/o */
for (slave_list = ap->racklist, ii = 0; slave_list != NULL;
slave_list = slave_list->next, ii++) {
slave_list->Local = (unsigned char *) calloc(1, sizeof(io_sRackLocal));
r_local = (io_sRackLocal *) slave_list->Local;
for (jj = 0; jj < local->device_data[ii + 1]->iocr_data.size(); jj++) {
if (local->device_data[ii + 1]->iocr_data[jj]->type == PROFINET_IO_CR_TYPE_INPUT) {
r_local->bytes_of_input = local->device_data[ii + 1]->iocr_data[jj]->clean_io_data_length;
r_local->inputs = local->device_data[ii + 1]->iocr_data[jj]->clean_io_data;
}
else if (local->device_data[ii + 1]->iocr_data[jj]->type == PROFINET_IO_CR_TYPE_OUTPUT) {
r_local->bytes_of_output = local->device_data[ii + 1]->iocr_data[jj]->clean_io_data_length;
r_local->inputs = local->device_data[ii + 1]->iocr_data[jj]->clean_io_data;
}
}
}
/* Set identification */
pack_set_identification_req(&local->service_req_res);
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, ap);
}
/* Set mode online */
T_PNAK_EVENT_SET_MODE pMode;
pMode.Mode = PNAK_MODE_ONLINE;
sts = pnak_set_mode(0, &pMode);
if (sts != PNAK_OK) {
op->Status = PB__INITFAIL;
errh_Error( "Profistack unable to go online, errcode: %d", sts);
return IO__ERRINIDEVICE;
}
T_PNAK_WAIT_OBJECT wait_object;
wait_object = PNAK_WAIT_OBJECT_STATE_CHANGED;
sts = pnak_wait_for_multiple_objects(0, &wait_object, PNAK_INFINITE_TIMEOUT);
if (sts == PNAK_OK) {
T_PNAK_EVENT_STATE pState;
sts = pnak_get_state(0, &pState);
if (pState.Mode != PNAK_MODE_ONLINE) {
if (sts != PNAK_OK) {
op->Status = PB__INITFAIL;
errh_Error( "Profistack unable to set state online, errcode: %d", sts);
return IO__ERRINIDEVICE;
}
}
}
/* Activate the devices */
T_PNAK_EVENT_SET_DEVICE_STATE set_dev_state;
memset(&set_dev_state, 0, sizeof(set_dev_state));
for (ii = 0; ii < local->device_data.size(); ii++) {
set_dev_state.ActivateDeviceReference[ii] = 1;
}
sts = pnak_set_device_state(0, &set_dev_state);
if (sts != PNAK_OK) {
op->Status = PB__INITFAIL;
errh_Error( "Profistack unable to activate devices, errcode: %d", sts);
return IO__ERRINIDEVICE;
}
/* Check state for all devices */
for (ii = 1; ii < device_vect.size(); ii++) {
// for (ii = 0; ii < 1; ii++) {
pack_get_device_state_req(&local->service_req_res, local->device_data[ii]->device_ref);
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, ap);
}
}
/* Active supervision thread */
pthread_attr_t attr;
local->args.local = local;
local->args.ap = ap;
pthread_attr_init(&attr);
pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
pthread_create(&local->handle_events, &attr, handle_events, &local->args);
op->Status = PB__NORMAL;
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Read method for the Pb_Profiboard agent
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoAgentRead (
io_tCtx ctx,
io_sAgent *ap
)
{
io_sAgentLocal *local;
PnIOCRData *pn_iocr_data;
pwr_tUInt16 sts;
unsigned char *io_datap;
unsigned char *clean_io_datap;
unsigned char status_data = 0;
PnSubmoduleData *submodule;
unsigned short data_length, ii, jj, kk, ll;
local = (io_sAgentLocal *) ap->Local;
// handle_events(&local->args);
/* Read i/o for all devices and move it to clean io data area */
for (ii = 1; ii < local->device_data.size(); ii++) {
if (local->device_data[ii]->device_state == PNAK_DEVICE_STATE_CONNECTED) {
for (jj = 0; jj < local->device_data[ii]->iocr_data.size(); jj++) {
pn_iocr_data = local->device_data[ii]->iocr_data[jj];
if (pn_iocr_data->type == PROFINET_IO_CR_TYPE_INPUT) {
data_length = pn_iocr_data->io_data_length;
sts = pnak_get_iocr_data(0, pn_iocr_data->identifier, pn_iocr_data->io_data, &data_length, &status_data);
if (sts == PNAK_OK) {
for (kk = 0; kk < local->device_data[ii]->module_data.size(); kk++) {
for (ll = 0; ll < local->device_data[ii]->module_data[kk]->submodule_data.size(); ll++) {
submodule = local->device_data[ii]->module_data[kk]->submodule_data[ll];
if ((submodule->type == PROFINET_IO_SUBMODULE_TYPE_INPUT) ||
(submodule->type == PROFINET_IO_SUBMODULE_TYPE_INPUT_AND_OUTPUT)) {
io_datap = (pn_iocr_data->io_data + submodule->offset_io_in);
clean_io_datap = (pn_iocr_data->clean_io_data + submodule->offset_clean_io_in);
memcpy(clean_io_datap, io_datap, submodule->io_in_data_length);
}
}
}
}
}
}
}
}
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Write method for the Pb_Profiboard agent
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoAgentWrite (
io_tCtx ctx,
io_sAgent *ap
)
{
io_sAgentLocal *local;
PnIOCRData *pn_iocr_data;
pwr_tUInt16 sts;
unsigned char *io_datap;
unsigned char *clean_io_datap;
PnSubmoduleData *submodule;
unsigned short data_length, ii, jj, kk, ll;
unsigned char *status_datap;
local = (io_sAgentLocal *) ap->Local;
/* Write i/o for all devices fetch it first from clean io data area */
for (ii = 1; ii < local->device_data.size(); ii++) {
if (local->device_data[ii]->device_state == PNAK_DEVICE_STATE_CONNECTED) {
for (jj = 0; jj < local->device_data[ii]->iocr_data.size(); jj++) {
pn_iocr_data = local->device_data[ii]->iocr_data[jj];
if (pn_iocr_data->type == PROFINET_IO_CR_TYPE_OUTPUT) {
data_length = pn_iocr_data->io_data_length;
for (kk = 0; kk < local->device_data[ii]->module_data.size(); kk++) {
for (ll = 0; ll < local->device_data[ii]->module_data[kk]->submodule_data.size(); ll++) {
submodule = local->device_data[ii]->module_data[kk]->submodule_data[ll];
if ((submodule->type == PROFINET_IO_SUBMODULE_TYPE_OUTPUT) ||
(submodule->type == PROFINET_IO_SUBMODULE_TYPE_INPUT_AND_OUTPUT)) {
io_datap = (pn_iocr_data->io_data + submodule->offset_io_out);
clean_io_datap = (pn_iocr_data->clean_io_data + submodule->offset_clean_io_out);
memcpy(io_datap, clean_io_datap, submodule->io_out_data_length);
status_datap = io_datap + submodule->io_out_data_length;
*status_datap = PNAK_IOXS_STATUS_NO_EXTENTION_FOLLOWS | PNAK_IOXS_STATUS_DATA_GOOD;
}
}
}
sts = pnak_set_iocr_data(0, pn_iocr_data->identifier, pn_iocr_data->io_data, pn_iocr_data->io_data_length);
}
}
}
}
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoAgentClose (
io_tCtx ctx,
io_sAgent *ap
)
{
io_sAgentLocal *local;
pwr_tStatus sts = PB__NOTINIT;
local = (io_sAgentLocal *) ap->Local;
/* Stop profistack */
pnak_init();
sts = pnak_stop_profistack(0);
pnak_term();
/* Clean data areas .... */
return sts;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport pwr_BindIoMethods(PnControllerSoftingPNAK) = {
pwr_BindIoMethod(IoAgentInit),
pwr_BindIoMethod(IoAgentRead),
pwr_BindIoMethod(IoAgentWrite),
pwr_BindIoMethod(IoAgentClose),
pwr_NullMethod
};
/*
* Copyright (C) 2010 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* rt_io_m_pndevice.c -- io methods for a profinet device */
#include <vector>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pwr.h"
#include "co_cdh.h"
#include "pwr_baseclasses.h"
#include "pwr_profibusclasses.h"
#include "rt_io_base.h"
#include "rt_io_bus.h"
#include "rt_io_msg.h"
#include "rt_errh.h"
#include "rt_pb_msg.h"
#include "profinet.h"
#include "pnak.h"
#include "co_dcli.h"
#include "rt_pn_gsdml_data.h"
#include "rt_io_pn_locals.h"
/*----------------------------------------------------------------------------*\
Init method for the PnDevice
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoRackInit (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp
)
{
io_sCardLocal *local_card;
io_sCard *cardp;
short input_counter;
short output_counter;
pwr_sClass_PnDevice *op;
pwr_sClass_PnModule *mp;
char name[196];
pwr_tStatus sts;
pwr_tCid cid;
io_sChannel *chanp;
int i, latent_input_count, latent_output_count;
pwr_tInt32 chan_size;
pwr_sClass_ChanDi *chan_di;
pwr_sClass_ChanDo *chan_do;
pwr_sClass_ChanAi *chan_ai;
pwr_sClass_ChanAit *chan_ait;
pwr_sClass_ChanIi *chan_ii;
pwr_sClass_ChanAo *chan_ao;
pwr_sClass_ChanIo *chan_io;
sts = gdh_ObjidToName(rp->Objid, (char *) &name, sizeof(name), cdh_mNName);
errh_Info( "Init of Profinet Device and Modules %s", name);
op = (pwr_sClass_PnDevice *) rp->op;
// Do configuration check and initialize modules.
cardp = rp->cardlist;
input_counter = 0;
output_counter = 0;
latent_input_count = 0;
latent_output_count = 0;
while(cardp) {
local_card = (io_sCardLocal *) calloc(1, sizeof(*local_card));
cardp->Local = local_card;
local_card->input_area = ((io_sRackLocal *)(rp->Local))->inputs;
local_card->output_area = ((io_sRackLocal *)(rp->Local))->outputs;
/* From v4.1.3 we can have subclasses, find the super class */
cid = cardp->Class;
while ( ODD( gdh_GetSuperClass( cid, &cid, cardp->Objid))) ;
switch (cid) {
/* New style configuring (from v4.1.3) with Pb_Module objects or subclass. Loop all channels
in the module and set channel size and offset. */
case pwr_cClass_PnModule:
mp = (pwr_sClass_PnModule *) cardp->op;
mp->Status = PB__INITFAIL;
cardp->offset = 0;
for (i=0; i<cardp->ChanListSize; i++) {
chanp = &cardp->chanlist[i];
if (chanp->ChanClass != pwr_cClass_ChanDi) {
input_counter += latent_input_count;
latent_input_count = 0;
}
if (chanp->ChanClass != pwr_cClass_ChanDo) {
output_counter += latent_output_count;
latent_output_count = 0;
}
switch (chanp->ChanClass) {
case pwr_cClass_ChanDi:
chan_di = (pwr_sClass_ChanDi *) chanp->cop;
if (chan_di->Number == 0) {
input_counter += latent_input_count;
latent_input_count = 0;
}
chanp->offset = input_counter;
chanp->mask = 1<<chan_di->Number;
if (chan_di->Representation == pwr_eDataRepEnum_Bit16 && op->ByteOrdering == pwr_eByteOrderingEnum_BigEndian)
chanp->mask = swap16(chanp->mask);
if (chan_di->Representation == pwr_eDataRepEnum_Bit32 && op->ByteOrdering == pwr_eByteOrderingEnum_BigEndian)
chanp->mask = swap32((unsigned short) chanp->mask);
if (chan_di->Number == 0) latent_input_count = GetChanSize((pwr_eDataRepEnum) chan_di->Representation);
// printf("Di channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_di->Number, chanp->offset);
break;
case pwr_cClass_ChanAi:
chan_ai = (pwr_sClass_ChanAi *) chanp->cop;
chanp->offset = input_counter;
chan_size = GetChanSize((pwr_eDataRepEnum) chan_ai->Representation);
chanp->size = chan_size;
chanp->mask = 0;
input_counter += chan_size;
io_AiRangeToCoef(chanp);
// printf("Ai channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_ai->Number, chanp->offset);
break;
case pwr_cClass_ChanAit:
chan_ait = (pwr_sClass_ChanAit *) chanp->cop;
chanp->offset = input_counter;
chan_size = GetChanSize((pwr_eDataRepEnum) chan_ait->Representation);
chanp->size = chan_size;
chanp->mask = 0;
input_counter += chan_size;
io_AiRangeToCoef(chanp);
break;
case pwr_cClass_ChanIi:
chan_ii = (pwr_sClass_ChanIi *) chanp->cop;
chanp->offset = input_counter;
chan_size = GetChanSize((pwr_eDataRepEnum) chan_ii->Representation);
chanp->size = chan_size;
chanp->mask = 0;
input_counter += chan_size;
// printf("Ii channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_ii->Number, chanp->offset);
break;
case pwr_cClass_ChanDo:
chan_do = (pwr_sClass_ChanDo *) chanp->cop;
if (chan_do->Number == 0) {
output_counter += latent_output_count;
latent_output_count = 0;
}
chanp->offset = output_counter;
chan_size = GetChanSize((pwr_eDataRepEnum) chan_do->Representation);
chanp->mask = 1<<chan_do->Number;
if (chan_do->Representation == pwr_eDataRepEnum_Bit16 && op->ByteOrdering == pwr_eByteOrderingEnum_BigEndian)
chanp->mask = swap16(chanp->mask);
if (chan_do->Representation == pwr_eDataRepEnum_Bit32 && op->ByteOrdering == pwr_eByteOrderingEnum_BigEndian)
chanp->mask = swap32((unsigned short) chanp->mask);
if (chan_do->Number == 0) latent_output_count = GetChanSize((pwr_eDataRepEnum) chan_do->Representation);
// printf("Do channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_do->Number, chanp->offset);
break;
case pwr_cClass_ChanAo:
chan_ao = (pwr_sClass_ChanAo *) chanp->cop;
chanp->offset = output_counter;
chan_size = GetChanSize((pwr_eDataRepEnum) chan_ao->Representation);
chanp->size = chan_size;
chanp->mask = 0;
output_counter += chan_size;
io_AoRangeToCoef(chanp);
// printf("Ao channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_ao->Number, chanp->offset);
break;
case pwr_cClass_ChanIo:
chan_io = (pwr_sClass_ChanIo *) chanp->cop;
chanp->offset = output_counter;
chan_size = GetChanSize((pwr_eDataRepEnum) chan_io->Representation);
chanp->size = chan_size;
chanp->mask = 0;
output_counter += chan_size;
// printf("Io channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_io->Number, chanp->offset);
break;
}
}
mp->Status = PB__SUCCESS;
break;
}
cardp = cardp->next;
}
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Read method for the Pb DP slave
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoRackRead (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp
)
{
pwr_sClass_PnControllerSoftingPNAK *mp;
pwr_sClass_PnDevice *sp;
sp = (pwr_sClass_PnDevice *) rp->op;
mp = (pwr_sClass_PnControllerSoftingPNAK *) ap->op;
/* The reading of the process image is now performed at the agent level,
this eliminates the need for board specific code at the rack level. */
if (sp->Status == PB__SUCCESS) {
sp->ErrorCount = 0;
}
else {
sp->ErrorCount++;
}
if (sp->ErrorCount > sp->ErrorSoftLimit ) {
memset(((io_sRackLocal *)(rp->Local))->inputs, 0, ((io_sRackLocal *)(rp->Local))->bytes_of_input);
}
// if (sp->ErrorCount > sp->ErrorHardLimit && sp->StallAction >= pwr_ePbStallAction_EmergencyBreak) {
// ctx->Node->EmergBreakTrue = 1;
// }
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Write method for the Pb DP slave
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoRackWrite (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp
)
{
pwr_sClass_PnControllerSoftingPNAK *mp;
pwr_sClass_PnDevice *sp;
sp = (pwr_sClass_PnDevice *) rp->op;
mp = (pwr_sClass_PnControllerSoftingPNAK *) ap->op;
/* The writing of the process image is now performed at the agent level,
this eliminates the need for board specific code at the rack level. */
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoRackClose (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp
)
{
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport pwr_BindIoMethods(PnDevice) = {
pwr_BindIoMethod(IoRackInit),
pwr_BindIoMethod(IoRackRead),
pwr_BindIoMethod(IoRackWrite),
pwr_BindIoMethod(IoRackClose),
pwr_NullMethod
};
/*
* Copyright (C) 2010 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* rt_io_m_pnmodule.cpp -- io methods for a profinet device */
#include <vector>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pwr.h"
#include "co_cdh.h"
#include "pwr_baseclasses.h"
#include "pwr_profibusclasses.h"
#include "rt_io_base.h"
#include "rt_io_bus.h"
#include "rt_io_msg.h"
#include "rt_errh.h"
#include "rt_pb_msg.h"
#include "profinet.h"
#include "pnak.h"
#include "co_dcli.h"
#include "rt_pn_gsdml_data.h"
#include "rt_io_pn_locals.h"
/*----------------------------------------------------------------------------*\
Init method for the Pnmodule
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardInit (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sCardLocal *local;
pwr_sClass_PnModule *op;
op = (pwr_sClass_PnModule *) cp->op;
local = (io_sCardLocal *) cp->Local;
op->Status = PB__NORMAL;
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Read method for the Pn module
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardRead (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sCardLocal *local;
pwr_sClass_PnModule *op;
pwr_sClass_PnDevice *slave;
op = (pwr_sClass_PnModule *) cp->op;
local = (io_sCardLocal *) cp->Local;
slave = (pwr_sClass_PnDevice *) rp->op;
op->Status = slave->Status;
/* I/O-read operations should always be made. This ensures correct values */
/* on all inputs. Default StallAction is ResetInputs which means that */
/* all inputs will be zeroed */
io_card_read(ctx, rp, cp, local->input_area, 0, slave->ByteOrdering,
slave->FloatRepresentation);
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Write method for the Pn module
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardWrite (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sCardLocal *local;
pwr_sClass_PnModule *op;
pwr_sClass_PnDevice *slave;
op = (pwr_sClass_PnModule *) cp->op;
local = (io_sCardLocal *) cp->Local;
slave = (pwr_sClass_PnDevice *) rp->op;
op->Status = slave->Status;
if (op->Status == PB__NORMAL) {
io_card_write(ctx, cp, local->output_area, slave->ByteOrdering,
slave->FloatRepresentation);
}
// printf("Method Pb_Module-IoCardWrite\n");
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Close method for the Pb module
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardClose (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sCardLocal *local;
local = (io_sCardLocal *) cp->Local;
free ((char *) local);
printf("Method Pb_Module-IoCardClose\n");
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport pwr_BindIoMethods(PnModule) = {
pwr_BindIoMethod(IoCardInit),
pwr_BindIoMethod(IoCardRead),
pwr_BindIoMethod(IoCardWrite),
pwr_BindIoMethod(IoCardClose),
pwr_NullMethod
};
/*
* Proview $Id$
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**/
#ifndef rt_io_pn_locals_h
#define rt_io_pn_locals_h
#include "profinet.h"
#include "pnak.h"
/* rt_io_pn_locals.h -- Profinet io handling locals. */
typedef struct _PN_Alarm_Data {
unsigned short alarm_type;
unsigned short alarm_prio;
unsigned short rem_alarms;
unsigned int slot_number;
unsigned int sub_slot_number;
unsigned int module_ident_number;
unsigned int submodule_ident_number;
unsigned short alarm_spec;
unsigned short data_length;
unsigned char *data;
} PN_Alarm_Data;
class PnIOCRData {
public:
PnIOCRData() : type(0), number_modules(0), identifier(0), io_data_length(0) {}
unsigned short type;
unsigned short number_modules;
unsigned short identifier;
unsigned short io_data_length; // bytes of io-data including status;
unsigned short clean_io_data_length; // bytes of io-data including status;
unsigned char *io_data;
unsigned char *clean_io_data;
~PnIOCRData() {}
int print( ofstream& fp);
};
class PnSubmoduleData {
public:
PnSubmoduleData() : subslot_number(0), subslot_idx(0), type(0), state(0), ident_number(0), phys_ident_number(0) {}
unsigned short subslot_number;
unsigned short subslot_idx;
unsigned short type;
unsigned short state;
unsigned int ident_number;
unsigned int phys_ident_number;
unsigned short io_in_data_length; // bytes of pure io-data
unsigned short offset_io_in; // offset in io-data area for this iocr
unsigned short offset_clean_io_in; // offset in io-data area for this iocr
unsigned short offset_status_in; // offset in io-data area for this iocr
unsigned short io_out_data_length; // bytes of pure io-data
unsigned short offset_io_out; // offset in io-data area for this iocr
unsigned short offset_clean_io_out; // offset in io-data area for this iocr
unsigned short offset_status_out; // offset in io-data area for this iocr
~PnSubmoduleData() {}
int print( ofstream& fp);
};
class PnModuleData {
public:
PnModuleData() : slot_number(0), slot_idx(0), state(0), ident_number(0), phys_ident_number(0) {}
unsigned int slot_number;
unsigned int slot_idx;
unsigned short state;
unsigned int ident_number;
unsigned int phys_ident_number;
vector<PnSubmoduleData *> submodule_data;
~PnModuleData() {
for ( unsigned int i = 0; i < submodule_data.size(); i++)
delete submodule_data[i];
}
int print( ofstream& fp);
};
class PnDeviceData {
public:
PnDeviceData() : device_ref(0), alarm_ref(0), device_state(0), no_diff_modules(0) {memset(&alarm_data, 0, sizeof(PN_Alarm_Data));}
unsigned short device_ref;
unsigned short alarm_ref;
unsigned short device_state;
unsigned short no_diff_modules;
PN_Alarm_Data alarm_data;
vector<PnModuleData *> module_data;
vector<PnIOCRData *> iocr_data;
~PnDeviceData() { device_reset();}
void device_reset() {
for ( unsigned int i = 0; i < module_data.size(); i++)
delete module_data[i];
module_data.clear();
for ( unsigned int i = 0; i < iocr_data.size(); i++)
delete iocr_data[i];
iocr_data.clear();
}
int copy_slot( unsigned int slot_idx);
int cut_slot( unsigned int slot_idx);
int paste_slot( unsigned int slot_idx);
};
class PnDeviceInfo {
public:
PnDeviceInfo() {}
unsigned char ipaddress[4];
unsigned char macaddress[6];
unsigned char subnetmask[4];
char devname[80];
int vendorid;
int deviceid;
};
typedef struct _agent_args {
void *local;
io_sAgent *ap;
} agent_args;
class io_sAgentLocal {
public :
io_sAgentLocal() {}
T_PNAK_SERVICE_REQ_RES service_req_res;
T_PNAK_SERVICE_CON service_con;
unsigned char ipaddress[4];
unsigned char macaddress[6];
unsigned char subnetmask[4];
vector<PnDeviceData *> device_data;
vector<PnDeviceInfo *> dev_info;
pthread_t handle_events;
agent_args args;
};
typedef struct _io_sRackLocal {
unsigned short bytes_of_input;
unsigned short bytes_of_output;
unsigned char *inputs;
unsigned char *outputs;
} io_sRackLocal;
typedef struct _io_sCardLocal {
unsigned char *input_area;
unsigned char *output_area;
} io_sCardLocal;
#endif
Pb_Profiboard
Pb_Hilscher
Pb_DP_Slave
Pb_Module
Pb_Di
Pb_Do
Pb_Ai
Pb_Ao
Pb_Ii
Pb_Io
PnControllerSoftingPNAK
PnDevice
PnModule
/*
* Proview $Id$
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**/
/* rt_pn_iface.cpp -- Profinet driver interface routines */
#include <vector>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pwr.h"
#include "co_cdh.h"
#include "pwr_baseclasses.h"
#include "pwr_profibusclasses.h"
#include "rt_io_base.h"
#include "rt_io_bus.h"
#include "rt_io_msg.h"
#include "rt_errh.h"
#include "rt_pb_msg.h"
#include "profinet.h"
#include "pnak.h"
#include "co_dcli.h"
#include "rt_pn_gsdml_data.h"
#include "rt_io_base.h"
#include "rt_io_pn_locals.h"
#define _PN_U32_HIGH_WORD(U32) ((PN_U16) ((U32) >> 16))
#define _PN_U32_LOW_WORD(U32) ((PN_U16) (U32) )
#define _PN_U32_HIGH_HIGH_BYTE(U32) ((PN_U8) ((U32) >> 24))
#define _PN_U32_HIGH_LOW_BYTE(U32) ((PN_U8) ((U32) >> 16))
#define _PN_U32_LOW_HIGH_BYTE(U32) ((PN_U8) ((U32) >> 8))
#define _PN_U32_LOW_LOW_BYTE(U32) ((PN_U8) (U32) )
#define _PN_U16_HIGH_BYTE(U16) ((PN_U8) ((U16) >> 8))
#define _PN_U16_LOW_BYTE(U16) ((PN_U8) (U16) )
#define _HIGH_LOW_WORDS_TO_PN_U32(High,Low) ((((PN_U32) (High)) << 16) + (Low))
#define _HIGH_LOW_BYTES_TO_PN_U16(High,Low) ((PN_U16) ((((PN_U16) (High)) << 8 ) + (Low)))
#define _HIGH_LOW_BYTES_TO_PN_U32(hwhb, hwlb, lwhb, lwlb) ((PN_U32) ((((PN_U32) (hwhb)) << 24 ) + (((PN_U32) (hwlb)) << 16 ) + (((PN_U32) (lwhb)) << 8 ) + (lwlb)))
#define _
#define NUM_DEVICES 2
char file_vect[2][80] = {
"pwr_pn_000_001_099_020_000000a2.xml",
"pwr_pn_000_001_099_020_000000e5.xml",
};
void pack_set_ip_settings_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, PnDeviceInfo *dev_info)
{
T_PNAK_SERVICE_DESCRIPTION *service_desc;
T_PN_SERVICE_SET_IP_SETTINGS_REQ *pSISR;
unsigned offset = 0u;
memset(ServiceReqRes, 0, sizeof(T_PNAK_SERVICE_REQ_RES));
ServiceReqRes->NumberEntries = 1;
ServiceReqRes->ServiceEntry[0].ServiceOffset = 0;
service_desc = (T_PNAK_SERVICE_DESCRIPTION *) &ServiceReqRes->ServiceChannel[offset];
service_desc->DeviceRef = 0u;
service_desc->Instance = PN_SUPERVISOR;
service_desc->Service = PN_SERVICE_SET_IP_SETTINGS;
service_desc->Primitive = PNAK_SERVICE_REQ;
service_desc->ClientId = 0;
service_desc->InvokeId = 0;
service_desc->DataLength = sizeof(T_PN_SERVICE_SET_IP_SETTINGS_REQ);
/* Fill service */
pSISR = (T_PN_SERVICE_SET_IP_SETTINGS_REQ *) (service_desc + 1);
// no_items = sscanf(dev_data->mac_address, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &havhb, &havlb, &mhb, &mlb, &lhb, &llb);
pSISR->DestMacAddress.HighAndVersionHighByte = dev_info->macaddress[5];
pSISR->DestMacAddress.HighAndVersionLowByte = dev_info->macaddress[4];
pSISR->DestMacAddress.MidHighByte = dev_info->macaddress[3];
pSISR->DestMacAddress.MidLowByte = dev_info->macaddress[2];
pSISR->DestMacAddress.LowHighByte = dev_info->macaddress[1];
pSISR->DestMacAddress.LowLowByte = dev_info->macaddress[0];
// no_items = sscanf(dev_data->ip_address, "%hhi.%hhi.%hhi.%hhi", &high_high_byte,
// &high_low_byte, &low_high_byte, &low_low_byte);
// if (no_items == 4) {
pSISR->AddressHighWordHighByte = dev_info->ipaddress[3];
pSISR->AddressHighWordLowByte = dev_info->ipaddress[2];
pSISR->AddressLowWordHighByte = dev_info->ipaddress[1];
pSISR->AddressLowWordLowByte = dev_info->ipaddress[0];
// no_items = sscanf(dev_data->subnet_mask, "%hhi.%hhi.%hhi.%hhi", &high_high_byte,
// &high_low_byte, &low_high_byte, &low_low_byte);
// if (no_items == 4) {
pSISR->SubnetMaskHighWordHighByte = dev_info->subnetmask[3];
pSISR->SubnetMaskHighWordLowByte = dev_info->subnetmask[2];
pSISR->SubnetMaskLowWordHighByte = dev_info->subnetmask[1];
pSISR->SubnetMaskLowWordLowByte = dev_info->subnetmask[0];
}
void pack_set_device_name_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, PnDeviceInfo *dev_info)
{
T_PNAK_SERVICE_DESCRIPTION *service_desc;
T_PN_SERVICE_SET_NAME_REQ *pSNR;
unsigned short name_length;
unsigned offset = 0u;
memset(ServiceReqRes, 0, sizeof(T_PNAK_SERVICE_REQ_RES));
ServiceReqRes->NumberEntries = 1;
ServiceReqRes->ServiceEntry[0].ServiceOffset = 0;
service_desc = (T_PNAK_SERVICE_DESCRIPTION *) &ServiceReqRes->ServiceChannel[offset];
service_desc->DeviceRef = 0u;
service_desc->Instance = PN_SUPERVISOR;
service_desc->Service = PN_SERVICE_SET_DEVICE_NAME;
service_desc->Primitive = PNAK_SERVICE_REQ;
service_desc->ClientId = 0;
service_desc->InvokeId = 0;
service_desc->DataLength = sizeof(T_PN_SERVICE_SET_NAME_REQ);
/* Fill service */
pSNR = (T_PN_SERVICE_SET_NAME_REQ *) (service_desc + 1);
// no_items = sscanf(dev_data->mac_address, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &havhb, &havlb, &mhb, &mlb, &lhb, &llb);
pSNR->DestMacAddress.HighAndVersionHighByte = dev_info->macaddress[5];
pSNR->DestMacAddress.HighAndVersionLowByte = dev_info->macaddress[4];
pSNR->DestMacAddress.MidHighByte = dev_info->macaddress[3];
pSNR->DestMacAddress.MidLowByte = dev_info->macaddress[2];
pSNR->DestMacAddress.LowHighByte = dev_info->macaddress[1];
pSNR->DestMacAddress.LowLowByte = dev_info->macaddress[0];
name_length = strlen(dev_info->devname);
pSNR->NameLengthHighByte = _PN_U16_HIGH_BYTE(name_length);
pSNR->NameLengthLowByte = _PN_U16_LOW_BYTE(name_length);
strncpy(pSNR->DeviceName, dev_info->devname, PN_MAX_DEVICE_NAME_LENGTH);
}
void pack_set_identification_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes)
{
unsigned offset = 0u;
T_PNAK_SERVICE_DESCRIPTION *service_desc;
T_PN_SERVICE_SET_IDENTIFICATION_REQ *pSSIR;
memset(ServiceReqRes, 0, sizeof(T_PNAK_SERVICE_REQ_RES));
ServiceReqRes->NumberEntries = 1;
ServiceReqRes->ServiceEntry[0].ServiceOffset = 0;
service_desc = (T_PNAK_SERVICE_DESCRIPTION *) &ServiceReqRes->ServiceChannel[offset];
service_desc->DeviceRef = PN_DEVICE_REFERENCE_THIS_STATION;
service_desc->Instance = PN;
service_desc->Service = PN_SERVICE_SET_IDENTIFICATION;
service_desc->Primitive = PNAK_SERVICE_REQ;
service_desc->ClientId = 0;
service_desc->InvokeId = 0;
/* Calculate length of service */
service_desc->DataLength = sizeof(T_PN_SERVICE_SET_IDENTIFICATION_REQ);
/* Fill service */
pSSIR = (T_PN_SERVICE_SET_IDENTIFICATION_REQ *) (service_desc + 1);
sprintf((char *) pSSIR->TypeOfStation, "PN-IO-CON-OC-Implementation");
sprintf((char *) pSSIR->OrderId, "PN-IO-CON-OC ");
sprintf((char *) pSSIR->SerialNumber, "0700123456789099");
pSSIR->HwRevisionHighByte = 0;
pSSIR->HwRevisionLowByte = 1;
pSSIR->SwRevisionHighWordHighByte = 0;
pSSIR->SwRevisionHighWordLowByte = 60;
pSSIR->SwRevisionLowWordHighByte = 0;
pSSIR->SwRevisionLowWordLowByte = 'V';
pSSIR->IdentAndMaintenanceVersionHighByte = 1;
pSSIR->IdentAndMaintenanceVersionLowByte = 1;
}
void pack_get_device_state_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, unsigned short device_ref)
{
unsigned offset = 0u;
T_PNAK_SERVICE_DESCRIPTION *service_desc;
memset(ServiceReqRes, 0, sizeof(T_PNAK_SERVICE_REQ_RES));
ServiceReqRes->NumberEntries = 1;
ServiceReqRes->ServiceEntry[0].ServiceOffset = 0;
service_desc = (T_PNAK_SERVICE_DESCRIPTION *) &ServiceReqRes->ServiceChannel[offset];
service_desc->DeviceRef = device_ref;
service_desc->Instance = PN_CONTROLLER;
service_desc->Service = PN_SERVICE_GET_DEVICE_STATE;
service_desc->Primitive = PNAK_SERVICE_REQ;
service_desc->ClientId = 0;
service_desc->InvokeId = 0;
/* Calculate length of service */
service_desc->DataLength = sizeof(T_PN_SERVICE_GET_DEVICE_STATE_REQ);
}
void pack_get_los_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes)
{
unsigned offset = 0u;
T_PNAK_SERVICE_DESCRIPTION *service_desc;
memset(ServiceReqRes, 0, sizeof(T_PNAK_SERVICE_REQ_RES));
ServiceReqRes->NumberEntries = 1;
ServiceReqRes->ServiceEntry[0].ServiceOffset = 0;
service_desc = (T_PNAK_SERVICE_DESCRIPTION *) &ServiceReqRes->ServiceChannel[offset];
service_desc->DeviceRef = PN_DEVICE_REFERENCE_THIS_STATION;
service_desc->Instance = PN_SUPERVISOR;
service_desc->Service = PN_SERVICE_GET_LIST_OF_STATION;
service_desc->Primitive = PNAK_SERVICE_REQ;
service_desc->ClientId = 0;
service_desc->InvokeId = 0;
/* Calculate length of service */
service_desc->DataLength = sizeof(T_PN_SERVICE_GET_LIST_OF_STATION_REQ);
}
void pack_get_alarm_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, unsigned short ref, unsigned short device_ref)
{
unsigned offset = 0u;
T_PNAK_SERVICE_DESCRIPTION *service_desc;
T_PN_SERVICE_GET_ALARM_REQ *pGAR;
memset(ServiceReqRes, 0, sizeof(T_PNAK_SERVICE_REQ_RES));
ServiceReqRes->NumberEntries = 1;
ServiceReqRes->ServiceEntry[0].ServiceOffset = 0;
service_desc = (T_PNAK_SERVICE_DESCRIPTION *) &ServiceReqRes->ServiceChannel[offset];
service_desc->DeviceRef = device_ref;
service_desc->Instance = PN;
service_desc->Service = PN_SERVICE_GET_ALARM;
service_desc->Primitive = PNAK_SERVICE_REQ;
service_desc->ClientId = 0;
service_desc->InvokeId = 0;
/* Calculate length of service */
service_desc->DataLength = sizeof(T_PN_SERVICE_GET_ALARM_REQ);
pGAR = (T_PN_SERVICE_GET_ALARM_REQ *) (service_desc + 1);
pGAR->AlarmRefHighByte = _PN_U16_HIGH_BYTE(ref);
pGAR->AlarmRefLowByte = _PN_U16_LOW_BYTE(ref);
}
void pack_alarm_ack_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, unsigned short ref, unsigned short prio, unsigned short device_ref)
{
unsigned offset = 0u;
T_PNAK_SERVICE_DESCRIPTION *service_desc;
T_PN_SERVICE_ALARM_ACK_REQ *pAAR;
memset(ServiceReqRes, 0, sizeof(T_PNAK_SERVICE_REQ_RES));
ServiceReqRes->NumberEntries = 1;
ServiceReqRes->ServiceEntry[0].ServiceOffset = 0;
service_desc = (T_PNAK_SERVICE_DESCRIPTION *) &ServiceReqRes->ServiceChannel[offset];
service_desc->DeviceRef = device_ref;
service_desc->Instance = PN;
service_desc->Service = PN_SERVICE_ALARM_ACK;
service_desc->Primitive = PNAK_SERVICE_REQ;
service_desc->ClientId = 0;
service_desc->InvokeId = 0;
/* Calculate length of service */
service_desc->DataLength = sizeof(T_PN_SERVICE_ALARM_ACK_REQ);
pAAR = (T_PN_SERVICE_ALARM_ACK_REQ *) (service_desc + 1);
pAAR->AlarmRefHighByte = _PN_U16_HIGH_BYTE(ref);
pAAR->AlarmRefLowByte = _PN_U16_LOW_BYTE(ref);
pAAR->AlarmPriority = _PN_U16_LOW_BYTE(prio);
}
void pack_download_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, GsdmlDeviceData *dev_data, unsigned short device_ref)
{
unsigned offset = 0u;
T_PNAK_SERVICE_DESCRIPTION *service_desc;
unsigned short num_iocrs = 0;
unsigned short num_apis = 0;
unsigned short num_modules = 0;
unsigned short num_submodules = 0;
unsigned short num_datarecords = 0;
unsigned short num_sm;
char *pData;
unsigned short module_ind = 0;
unsigned short datarecord_ind = 0;
unsigned short data_record_length = 0;
unsigned short no_items;
unsigned short ii, jj, kk, length;
static unsigned short phase = 1;
// static unsigned short old_red_ratio = 1;
memset(ServiceReqRes, 0, sizeof(T_PNAK_SERVICE_REQ_RES));
ServiceReqRes->NumberEntries = 1;
ServiceReqRes->ServiceEntry[0].ServiceOffset = 0;
service_desc = (T_PNAK_SERVICE_DESCRIPTION *) &ServiceReqRes->ServiceChannel[offset];
service_desc->DeviceRef = device_ref;
// service_desc->DeviceRef = PN_DEVICE_REFERENCE_THIS_STATION;
service_desc->Instance = PN; // PN_CONTROLLER
service_desc->Service = PN_SERVICE_DOWNLOAD;
service_desc->Primitive = PNAK_SERVICE_REQ;
service_desc->ClientId = 0;
service_desc->InvokeId = 0;
/* Calculate length of service */
num_iocrs = dev_data->iocr_data.size();
if (num_iocrs > 0)
num_apis = 1;
for (ii = 0; ii < dev_data->slot_data.size(); ii++) {
if ((dev_data->slot_data[ii]->module_enum_number != 0) ||
(ii == 0))
num_modules++;
else break;
}
// num_modules = dev_data->slot_data.size();
for (ii = 0; ii < num_modules; ii++) {
num_sm = dev_data->slot_data[ii]->subslot_data.size();
num_submodules += num_sm;
for (jj = 0; jj < num_sm; jj++ ) {
num_datarecords += dev_data->slot_data[ii]->subslot_data[jj]->data_record.size();
for (kk = 0; kk < dev_data->slot_data[ii]->subslot_data[jj]->data_record.size(); kk++) {
data_record_length += dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->data_length;
}
}
}
length = sizeof(T_PN_SERVICE_DOWNLOAD_REQ) +
num_iocrs * sizeof(T_PN_IOCR) + num_apis * sizeof(T_PN_API) +
num_modules * sizeof(T_PN_MODULE) + num_submodules * sizeof(T_PN_SUBMODULE) +
num_datarecords * sizeof(T_PN_DATA_RECORD) +
(num_iocrs * num_apis + num_modules + num_datarecords) * sizeof(T_PN_REFERENCE) +
data_record_length;
service_desc->DataLength = length;
pData = (char *) (service_desc + 1);
/* Fill data in download request */
T_PN_SERVICE_DOWNLOAD_REQ *pSDR = (T_PN_SERVICE_DOWNLOAD_REQ *) pData;
unsigned char high_high_byte;
unsigned char high_low_byte;
unsigned char low_high_byte;
unsigned char low_low_byte;
unsigned char high_byte;
unsigned char low_byte;
unsigned long ar_property;
unsigned short high_word;
unsigned short low_word;
unsigned short sub_prop;
T_PN_IOCR *pIOCR;
T_PN_REFERENCE *pAPIReference;
T_PN_REFERENCE *pModuleReference;
T_PN_MODULE *pModule;
T_PN_SUBMODULE *pSubModule;
T_PN_REFERENCE *pDataRecordReference;
T_PN_DATA_RECORD *pDataRecord;
if (device_ref == 1) {
printf("sizeof download-struct: %d\n", sizeof(T_PN_SERVICE_DOWNLOAD_REQ));
printf("sizeof IOCR-struct: %d\n", sizeof(T_PN_IOCR));
printf("sizeof API-struct: %d\n", sizeof(T_PN_API));
printf("sizeof MODULE-struct: %d\n", sizeof(T_PN_MODULE));
printf("sizeof SUBMODULE-struct: %d\n", sizeof(T_PN_SUBMODULE));
printf("sizeof DATARECORD-struct: %d\n", sizeof(T_PN_DATA_RECORD));
printf("sizeof REFERENCE-struct: %d\n", sizeof(T_PN_REFERENCE));
}
no_items = sscanf(dev_data->ip_address, "%hhi.%hhi.%hhi.%hhi", &high_high_byte,
&high_low_byte, &low_high_byte, &low_low_byte);
if (no_items == 4) {
pSDR->IpAddressHighWordHighByte = high_high_byte;
pSDR->IpAddressHighWordLowByte = high_low_byte;
pSDR->IpAddressLowWordHighByte = low_high_byte;
pSDR->IpAddressLowWordLowByte = low_low_byte;
}
no_items = sscanf(dev_data->subnet_mask, "%hhi.%hhi.%hhi.%hhi", &high_high_byte,
&high_low_byte, &low_high_byte, &low_low_byte);
if (no_items == 4) {
pSDR->SubnetMaskHighWordHighByte = high_high_byte;
pSDR->SubnetMaskHighWordLowByte = high_low_byte;
pSDR->SubnetMaskLowWordHighByte = low_high_byte;
pSDR->SubnetMaskLowWordLowByte = low_low_byte;
}
sprintf(pSDR->DeviceName, dev_data->device_name);
if (device_ref == PN_DEVICE_REFERENCE_THIS_STATION) {
sprintf(pSDR->InterfaceName, "eth1");
pSDR->Flag = PN_SERVICE_DOWNLOAD_FLAG_AUTO_CONTROL_RES;
ar_property = 0;
pSDR->InstanceLowByte = 0;
}
else {
pSDR->Flag = PN_SERVICE_DOWNLOAD_FLAG_ACTIVATE;
ar_property = PROFINET_AR_PROPERTY_STATE_PRIMARY |
PROFINET_AR_PROPERTY_PARAMETER_SERVER_CM |
PROFINET_AR_PROPERTY_DATA_RATE_100MBIT;
pSDR->InstanceLowByte = 1;
}
no_items = sscanf(dev_data->version, "%hhi.%hhi", &high_byte, &low_byte);
pSDR->VersionHighByte = high_byte;
pSDR->VersionLowByte = low_byte;
high_word = _PN_U32_HIGH_WORD(ar_property);
low_word = _PN_U32_LOW_WORD(ar_property);
pSDR->ARPropertiesHighWordHighByte = _PN_U16_HIGH_BYTE(high_word);
pSDR->ARPropertiesHighWordLowByte = _PN_U16_LOW_BYTE(high_word);
pSDR->ARPropertiesLowWordHighByte = _PN_U16_HIGH_BYTE(low_word);
pSDR->ARPropertiesLowWordLowByte = _PN_U16_LOW_BYTE(low_word);
pSDR->DeviceIdHighByte = _PN_U16_HIGH_BYTE(dev_data->device_id);
pSDR->DeviceIdLowByte = _PN_U16_LOW_BYTE(dev_data->device_id);
pSDR->VendorIdHighByte = _PN_U16_HIGH_BYTE(dev_data->vendor_id);
pSDR->VendorIdLowByte = _PN_U16_LOW_BYTE(dev_data->vendor_id);
pSDR->NumberOfIOCRHighByte = _PN_U16_HIGH_BYTE(num_iocrs);
pSDR->NumberOfIOCRLowByte = _PN_U16_LOW_BYTE(num_iocrs);
pSDR->NumberOfAPIsHighByte = _PN_U16_HIGH_BYTE(num_apis);
pSDR->NumberOfAPIsLowByte = _PN_U16_LOW_BYTE(num_apis);
pSDR->NumberOfModulesHighByte = _PN_U16_HIGH_BYTE(num_modules);
pSDR->NumberOfModulesLowByte = _PN_U16_LOW_BYTE(num_modules);
pSDR->NumberOfDataRecordsHighByte = _PN_U16_HIGH_BYTE(num_datarecords);
pSDR->NumberOfDataRecordsLowByte = _PN_U16_LOW_BYTE(num_datarecords);
pSDR->AlarmCRBlock.VersionHighByte = 1;
pSDR->AlarmCRBlock.VersionLowByte = 0;
pSDR->AlarmCRBlock.RTATimeoutFactorHighByte = 0;
pSDR->AlarmCRBlock.RTATimeoutFactorLowByte = 1;
pSDR->AlarmCRBlock.RTARetryHighByte = 0;
pSDR->AlarmCRBlock.RTARetryLowByte = 3;
pSDR->AlarmCRBlock.PropertiesHighWordHighByte = 0;
pSDR->AlarmCRBlock.PropertiesHighWordLowByte = 0;
pSDR->AlarmCRBlock.PropertiesLowWordHighByte = 0;
pSDR->AlarmCRBlock.PropertiesLowWordLowByte = 0;
pSDR->AlarmCRBlock.MaxAlarmLengthHighByte = 0;
pSDR->AlarmCRBlock.MaxAlarmLengthLowByte = 200;
pSDR->AlarmCRBlock.TagHeaderHighHighByte = 0xC0;
pSDR->AlarmCRBlock.TagHeaderHighLowByte = 0;
pSDR->AlarmCRBlock.TagHeaderLowHighByte = 0xA0;
pSDR->AlarmCRBlock.TagHeaderLowLowByte = 0;
/* Fill the IOCRS's */
pIOCR = (T_PN_IOCR *) (pSDR + 1);
for (ii = 0; ii < num_iocrs; ii++) {
/* Fill data for IOCR */
pIOCR->VersionHighByte = pSDR->VersionHighByte;
pIOCR->VersionLowByte = pSDR->VersionLowByte;
pIOCR->TypeHighByte = _PN_U16_HIGH_BYTE(dev_data->iocr_data[ii]->type);
pIOCR->TypeLowByte = _PN_U16_LOW_BYTE(dev_data->iocr_data[ii]->type);
pIOCR->PropertiesHighWordHighByte = _PN_U32_HIGH_HIGH_BYTE(dev_data->iocr_data[ii]->properties);
pIOCR->PropertiesHighWordLowByte = _PN_U32_HIGH_LOW_BYTE(dev_data->iocr_data[ii]->properties);
pIOCR->PropertiesLowWordHighByte = _PN_U32_LOW_HIGH_BYTE(dev_data->iocr_data[ii]->properties);
pIOCR->PropertiesLowWordLowByte = _PN_U32_LOW_LOW_BYTE(dev_data->iocr_data[ii]->properties);
pIOCR->SendClockFactorHighByte = _PN_U16_HIGH_BYTE(dev_data->iocr_data[ii]->send_clock_factor);
pIOCR->SendClockFactorLowByte = _PN_U16_LOW_BYTE(dev_data->iocr_data[ii]->send_clock_factor);
if (dev_data->iocr_data[ii]->reduction_ratio < 1) {
dev_data->iocr_data[ii]->reduction_ratio = 1;
}
pIOCR->ReductionRatioHighByte = _PN_U16_HIGH_BYTE(dev_data->iocr_data[ii]->reduction_ratio);
pIOCR->ReductionRatioLowByte = _PN_U16_LOW_BYTE(dev_data->iocr_data[ii]->reduction_ratio);
if (dev_data->iocr_data[ii]->reduction_ratio == 0)
dev_data->iocr_data[ii]->reduction_ratio = 1;
/* if (old_red_ratio == dev_data->iocr_data[ii]->reduction_ratio) {
phase = (phase + 1) % old_red_ratio + 1;
} else {
phase = 1;
old_red_ratio = dev_data->iocr_data[ii]->reduction_ratio;
}*/
phase = 1;
// pIOCR->ReductionRatioHighByte = 0;
// pIOCR->ReductionRatioLowByte = 128;
pIOCR->PhaseHighByte = _PN_U16_HIGH_BYTE(phase);
pIOCR->PhaseLowByte = _PN_U16_LOW_BYTE(phase);;
pIOCR->SequenceHighByte = 0;
pIOCR->SequenceLowByte = 0;
pIOCR->WatchdogFactorHighByte = 0;
pIOCR->WatchdogFactorLowByte = 3;
pIOCR->DataHoldFactorHighByte = 0;
pIOCR->DataHoldFactorLowByte = 3;
pIOCR->FrameSendOffsetHighWordHighByte = 0xFF; // As fast as possible
pIOCR->FrameSendOffsetHighWordLowByte = 0xFF;
pIOCR->FrameSendOffsetLowWordHighByte = 0xFF;
pIOCR->FrameSendOffsetLowWordLowByte = 0xFF;
pIOCR->TagHeaderHighByte = 0xC0;
pIOCR->TagHeaderLowByte = 0;
pIOCR->MulticastAddr.HighAndVersionHighByte = 0;
pIOCR->MulticastAddr.HighAndVersionLowByte = 0;
pIOCR->MulticastAddr.MidHighByte = 0;
pIOCR->MulticastAddr.MidLowByte = 0;
pIOCR->MulticastAddr.LowHighByte = 0;
pIOCR->MulticastAddr.LowLowByte = 0;
// pIOCR->NumberOfAPIsHighByte = _PN_U16_HIGH_BYTE(num_apis);
// pIOCR->NumberOfAPIsLowByte = _PN_U16_HIGH_BYTE(num_apis);
pIOCR->NumberOfAPIsHighByte = _PN_U16_HIGH_BYTE(num_apis);
pIOCR->NumberOfAPIsLowByte = _PN_U16_LOW_BYTE(num_apis);
/* Fill references to API */
pAPIReference = (T_PN_REFERENCE *) (pIOCR + 1);
for (jj = 0; jj < num_apis; jj++) {
pAPIReference->ReferenceHighByte = _PN_U16_HIGH_BYTE(jj);
pAPIReference->ReferenceLowByte = _PN_U16_LOW_BYTE(jj);
pAPIReference++;
}
pIOCR = (T_PN_IOCR *) pAPIReference;
}
/* Fill the API's */
T_PN_API *pAPI = (T_PN_API *) pIOCR;
for (ii = 0; ii < num_apis; ii++) {
/* Fill data for API */
pAPI->APIHighWordHighByte = _PN_U32_HIGH_HIGH_BYTE(PROFINET_DEFAULT_API);
pAPI->APIHighWordLowByte = _PN_U32_HIGH_LOW_BYTE(PROFINET_DEFAULT_API);
pAPI->APILowWordHighByte = _PN_U32_LOW_HIGH_BYTE(PROFINET_DEFAULT_API);
pAPI->APILowWordLowByte = _PN_U32_LOW_LOW_BYTE(PROFINET_DEFAULT_API);
pAPI->NumberOfModulesHighByte = _PN_U16_HIGH_BYTE(num_modules);
pAPI->NumberOfModulesLowByte = _PN_U16_LOW_BYTE(num_modules);
/* Fill references to Modules */
pModuleReference = (T_PN_REFERENCE *) (pAPI + 1);
for (module_ind = 0; module_ind < num_modules; module_ind++) {
pModuleReference->ReferenceHighByte = _PN_U16_HIGH_BYTE(module_ind);
pModuleReference->ReferenceLowByte = _PN_U16_LOW_BYTE(module_ind);
pModuleReference++;
}
pAPI = (T_PN_API *) pModuleReference;
}
/* Fill the MODULE's */
pModule = (T_PN_MODULE *) pAPI;
for (ii = 0; ii < num_modules; ii++) {
/* Fill data for MODULE */
pModule->VersionHighByte = pSDR->VersionHighByte;
pModule->VersionLowByte = pSDR->VersionLowByte;
pModule->SlotNumberHighByte = _PN_U16_HIGH_BYTE(dev_data->slot_data[ii]->slot_number);
pModule->SlotNumberLowByte = _PN_U16_LOW_BYTE(dev_data->slot_data[ii]->slot_number);
pModule->IdentNumberHighWordHighByte = _PN_U32_HIGH_HIGH_BYTE(dev_data->slot_data[ii]->module_ident_number);
pModule->IdentNumberHighWordLowByte = _PN_U32_HIGH_LOW_BYTE(dev_data->slot_data[ii]->module_ident_number);
pModule->IdentNumberLowWordHighByte = _PN_U32_LOW_HIGH_BYTE(dev_data->slot_data[ii]->module_ident_number);
pModule->IdentNumberLowWordLowByte = _PN_U32_LOW_LOW_BYTE(dev_data->slot_data[ii]->module_ident_number);
pModule->PropertiesHighByte = 0;
pModule->PropertiesLowByte = 0;
pModule->NumberOfSubmodulesHighByte = _PN_U16_HIGH_BYTE(dev_data->slot_data[ii]->subslot_data.size());
pModule->NumberOfSubmodulesLowByte = _PN_U16_LOW_BYTE(dev_data->slot_data[ii]->subslot_data.size());
/* Fill the SUBMODULE's */
pSubModule = (T_PN_SUBMODULE *) (pModule + 1);
for (jj = 0; jj < dev_data->slot_data[ii]->subslot_data.size(); jj++) {
/* Fill data for the submodule */
pSubModule->SubSlotNumberHighByte = _PN_U16_HIGH_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->subslot_number);
pSubModule->SubSlotNumberLowByte = _PN_U16_LOW_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->subslot_number);
pSubModule->IdentNumberHighWordHighByte = _PN_U32_HIGH_HIGH_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->submodule_ident_number);
pSubModule->IdentNumberHighWordLowByte = _PN_U32_HIGH_LOW_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->submodule_ident_number);
pSubModule->IdentNumberLowWordHighByte = _PN_U32_LOW_HIGH_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->submodule_ident_number);
pSubModule->IdentNumberLowWordLowByte = _PN_U32_LOW_LOW_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->submodule_ident_number);
if ((dev_data->slot_data[ii]->subslot_data[jj]->io_input_length > 0) &&
(dev_data->slot_data[ii]->subslot_data[jj]->io_output_length)) {
sub_prop = PROFINET_IO_SUBMODULE_TYPE_INPUT_AND_OUTPUT;
} else if (dev_data->slot_data[ii]->subslot_data[jj]->io_input_length > 0) {
sub_prop = PROFINET_IO_SUBMODULE_TYPE_INPUT;
} else if (dev_data->slot_data[ii]->subslot_data[jj]->io_output_length) {
sub_prop = PROFINET_IO_SUBMODULE_TYPE_OUTPUT;
} else {
sub_prop = PROFINET_IO_SUBMODULE_TYPE_NO_INPUT_NO_OUTPUT;
}
pSubModule->PropertiesHighByte = _PN_U16_HIGH_BYTE(sub_prop);
pSubModule->PropertiesLowByte = _PN_U16_LOW_BYTE(sub_prop);
pSubModule->InputDataLengthHighByte = _PN_U16_HIGH_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->io_input_length);
pSubModule->InputDataLengthLowByte = _PN_U16_LOW_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->io_input_length);
pSubModule->OutputDataLengthHighByte = _PN_U16_HIGH_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->io_output_length);
pSubModule->OutputDataLengthLowByte = _PN_U16_LOW_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->io_output_length);
pSubModule->ConsumerStatusLength = 1; // Fixed by Profinet-spec
pSubModule->ProviderStatusLength = 1;
pSubModule->NumberOfDataRecordsHighByte = _PN_U16_HIGH_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->data_record.size());
pSubModule->NumberOfDataRecordsLowByte = _PN_U16_LOW_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->data_record.size());
/* Add number of datarecords */
pDataRecordReference = (T_PN_REFERENCE *) (pSubModule + 1);
for (kk = 0; kk < dev_data->slot_data[ii]->subslot_data[jj]->data_record.size(); kk++) {
pDataRecordReference->ReferenceHighByte = _PN_U16_HIGH_BYTE(datarecord_ind);
pDataRecordReference->ReferenceLowByte = _PN_U16_LOW_BYTE(datarecord_ind);
pDataRecordReference++;
datarecord_ind++;
}
pSubModule = (T_PN_SUBMODULE *) pDataRecordReference;
}
pModule = (T_PN_MODULE *) pSubModule;
}
/* Fill the DATA_RECORD's */
pDataRecord = (T_PN_DATA_RECORD *) pModule;
for (ii = 0; ii < num_modules; ii++) {
for (jj = 0; jj < dev_data->slot_data[ii]->subslot_data.size(); jj++) {
for (kk = 0; kk < dev_data->slot_data[ii]->subslot_data[jj]->data_record.size(); kk++) {
pDataRecord->VersionHighByte = pSDR->VersionHighByte;
pDataRecord->VersionLowByte = pSDR->VersionLowByte;
pDataRecord->SequenceHighByte = _PN_U16_HIGH_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->transfer_sequence);
pDataRecord->SequenceLowByte = _PN_U16_LOW_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->transfer_sequence);
pDataRecord->APIHighWordHighByte = _PN_U32_HIGH_HIGH_BYTE(PROFINET_DEFAULT_API);
pDataRecord->APIHighWordLowByte = _PN_U32_HIGH_LOW_BYTE(PROFINET_DEFAULT_API);
pDataRecord->APILowWordHighByte = _PN_U32_LOW_HIGH_BYTE(PROFINET_DEFAULT_API);
pDataRecord->APILowWordLowByte = _PN_U32_LOW_LOW_BYTE(PROFINET_DEFAULT_API);
pDataRecord->IndexHighByte = _PN_U16_HIGH_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->index);
pDataRecord->IndexLowByte = _PN_U16_LOW_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->index);
pDataRecord->LengthHighByte = _PN_U16_HIGH_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->data_length);
pDataRecord->LengthLowByte = _PN_U16_LOW_BYTE(dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->data_length);
pData = (char *) (pDataRecord + 1);
memcpy(pData, dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->data, dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->data_length);
pData += dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->data_length;
pDataRecord = (T_PN_DATA_RECORD *) pData;
}
}
}
if (device_ref != 0) {
pData = (char *) (pSDR);
printf("Download of device: %s\n", dev_data->device_name);
printf("Total datalength %d\n\n", length);
for (ii = 0; ii < length; ii++) {
if (ii % 16 == 0) printf("\n");
printf("%02hhX ", pData[ii]);
}
printf("\n");
printf("\n");
}
}
int unpack_get_los_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local)
{
if (pSdb->Result == PNAK_RESULT_POS) {
T_PN_SERVICE_GET_LIST_OF_STATION_CON* pGetLOSCon;
T_PN_DEVICE_INFO* pDeviceInfo;
PnDeviceInfo *dev_info;
PN_U16 NumberDevices;
unsigned short ii, name_length;
pGetLOSCon = (T_PN_SERVICE_GET_LIST_OF_STATION_CON *) (pSdb + 1);
pDeviceInfo = (T_PN_DEVICE_INFO *) (pGetLOSCon + 1);
NumberDevices = _HIGH_LOW_BYTES_TO_PN_U16 (pGetLOSCon->NumberOfDevicesHighByte, pGetLOSCon->NumberOfDevicesLowByte);
/* Find configured device */
if (NumberDevices == 0) printf("0\r\n");
for (ii = 0; ii < NumberDevices; ii++) {
dev_info = new PnDeviceInfo;
dev_info->ipaddress[3] = pDeviceInfo->Ip.AddressHighWordHighByte;
dev_info->ipaddress[2] = pDeviceInfo->Ip.AddressHighWordLowByte;
dev_info->ipaddress[1] = pDeviceInfo->Ip.AddressLowWordHighByte;
dev_info->ipaddress[0] = pDeviceInfo->Ip.AddressLowWordLowByte;
dev_info->macaddress[5] = pDeviceInfo->MacAddress.HighAndVersionHighByte;
dev_info->macaddress[4] = pDeviceInfo->MacAddress.HighAndVersionLowByte;
dev_info->macaddress[3] = pDeviceInfo->MacAddress.MidHighByte;
dev_info->macaddress[2] = pDeviceInfo->MacAddress.MidLowByte;
dev_info->macaddress[1] = pDeviceInfo->MacAddress.LowHighByte;
dev_info->macaddress[0] = pDeviceInfo->MacAddress.LowLowByte;
dev_info->deviceid = _HIGH_LOW_BYTES_TO_PN_U16(pDeviceInfo->Property.DeviceIdHighByte, pDeviceInfo->Property.DeviceIdLowByte);
dev_info->vendorid = _HIGH_LOW_BYTES_TO_PN_U16(pDeviceInfo->Property.VendorIdHighByte, pDeviceInfo->Property.VendorIdLowByte);
name_length = _HIGH_LOW_BYTES_TO_PN_U16(pDeviceInfo->DeviceNameLengthHighByte, pDeviceInfo->DeviceNameLengthLowByte);
printf("no: %d mac: %hhx:%hhx:%hhx:%hhx:%hhx:%hhx\r\n", NumberDevices,
pDeviceInfo->MacAddress.HighAndVersionHighByte, pDeviceInfo->MacAddress.HighAndVersionLowByte,
pDeviceInfo->MacAddress.MidHighByte, pDeviceInfo->MacAddress.MidLowByte,
pDeviceInfo->MacAddress.LowHighByte, pDeviceInfo->MacAddress.LowLowByte);
pDeviceInfo++;
memset(dev_info->devname, 0, sizeof(dev_info->devname));
strncpy(dev_info->devname, (char *) pDeviceInfo, name_length);
local->dev_info.push_back(dev_info);
pDeviceInfo = (T_PN_DEVICE_INFO *)((unsigned char *) pDeviceInfo + name_length);
}
return PNAK_OK;
}
else if (pSdb->Result == PNAK_RESULT_NEG) {
T_PN_SERVICE_ERROR_CON* pErrorCon = (T_PN_SERVICE_ERROR_CON*) (pSdb + 1);
printf(
"channel %d: get_los.con [-] (%d)\r\n"
" code : %d (0x%02x)\r\n"
" detail : %d (0x%02x)\r\n"
" add. detail: %d (0x%02x)\r\n"
" area : %d (0x%02x)\r\n",
0,
pSdb->DeviceRef,
pErrorCon->Code, pErrorCon->Code,
pErrorCon->Detail, pErrorCon->Detail,
pErrorCon->AdditionalDetail, pErrorCon->AdditionalDetail,
pErrorCon->AreaCode, pErrorCon->AreaCode
);
}
return -1;
}
int unpack_get_alarm_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local, io_sAgent *ap)
{
if (pSdb->Result == PNAK_RESULT_POS) {
T_PN_SERVICE_GET_ALARM_CON* pGAC;
unsigned short alarm_type;
unsigned short alarm_prio;
unsigned short alarm_ref, ii, jj;
unsigned short rem_alarms;
unsigned int slot_number;
unsigned int sub_slot_number;
unsigned int module_ident_number;
unsigned int submodule_ident_number;
unsigned short alarm_spec;
unsigned short data_length;
unsigned char *data;
PnDeviceData *device;;
pGAC = (T_PN_SERVICE_GET_ALARM_CON *) (pSdb + 1);
alarm_prio = pGAC->AlarmPriority;
rem_alarms = pGAC->RemainingAlarms;
alarm_ref = _HIGH_LOW_BYTES_TO_PN_U16(pGAC->AlarmRefHighByte, pGAC->AlarmRefLowByte);
alarm_type = _HIGH_LOW_BYTES_TO_PN_U16(pGAC->AlarmTypeHighByte, pGAC->AlarmTypeLowByte);
slot_number = _HIGH_LOW_BYTES_TO_PN_U16(pGAC->SlotNumberHighByte, pGAC->SlotNumberLowByte);
sub_slot_number = _HIGH_LOW_BYTES_TO_PN_U16(pGAC->SubSlotNumberHighByte, pGAC->SubSlotNumberLowByte);
module_ident_number = _HIGH_LOW_BYTES_TO_PN_U32(pGAC->ModuleIdentNumberHighWordHighByte,
pGAC->ModuleIdentNumberHighWordLowByte,
pGAC->ModuleIdentNumberLowWordHighByte,
pGAC->ModuleIdentNumberLowWordLowByte);
submodule_ident_number = _HIGH_LOW_BYTES_TO_PN_U32(pGAC->SubmoduleIdentNumberHighWordHighByte,
pGAC->SubmoduleIdentNumberHighWordLowByte,
pGAC->SubmoduleIdentNumberLowWordHighByte,
pGAC->SubmoduleIdentNumberLowWordLowByte);
alarm_spec = _HIGH_LOW_BYTES_TO_PN_U16(pGAC->SpecifierHighByte, pGAC->SpecifierLowByte);
data_length = _HIGH_LOW_BYTES_TO_PN_U16(pGAC->LengthHighByte, pGAC->LengthLowByte);
data = (unsigned char *)(pGAC + 1);
/* Find the device */
for (ii = 0; ii < local->device_data.size(); ii++) {
if (local->device_data[ii]->alarm_ref == alarm_ref) {
device = local->device_data[ii];
device->alarm_data.alarm_type = alarm_type;
device->alarm_data.alarm_prio = alarm_prio;
device->alarm_data.rem_alarms = rem_alarms;
device->alarm_data.slot_number = slot_number;
device->alarm_data.sub_slot_number = sub_slot_number;
device->alarm_data.module_ident_number = module_ident_number;
device->alarm_data.submodule_ident_number = submodule_ident_number;
device->alarm_data.alarm_spec = alarm_spec;
device->alarm_data.data_length = data_length;
break;
}
}
if (ap) {
/* Find corresponding device */
io_sRack *slave_list;
for (slave_list = ap->racklist, jj = 0;
(slave_list != NULL) && jj < ii - 1;
slave_list = slave_list->next, jj++) {}
if (slave_list) {
pwr_sClass_PnDevice *dev;
dev = (pwr_sClass_PnDevice *) slave_list->op;
dev->Alarm.Type = alarm_type;
dev->Alarm.Prio = alarm_prio;
dev->Alarm.Remaining = rem_alarms;
dev->Alarm.SlotNumber = slot_number;
dev->Alarm.SubslotNumber = sub_slot_number;
dev->Alarm.ModuleIdentNumber = module_ident_number;
dev->Alarm.SubmoduleIdentNumber = submodule_ident_number;
dev->Alarm.Specifier = alarm_spec;
}
}
printf(
"Alarm prio %d\r\n"
" remaining %d\r\n"
" type %d\r\n"
" slot %d\r\n"
" subslot %d\r\n"
" module_id %d\r\n"
" submodule_id %d\r\n"
" spec %d\r\n",
alarm_prio,
rem_alarms,
alarm_type,
slot_number,
sub_slot_number,
module_ident_number,
submodule_ident_number,
alarm_spec);
return PNAK_OK;
}
else if (pSdb->Result == PNAK_RESULT_NEG) {
T_PN_SERVICE_ERROR_CON* pErrorCon = (T_PN_SERVICE_ERROR_CON*) (pSdb + 1);
printf(
"channel %d: get_los.con [-] (%d)\r\n"
" code : %d (0x%02x)\r\n"
" detail : %d (0x%02x)\r\n"
" add. detail: %d (0x%02x)\r\n"
" area : %d (0x%02x)\r\n",
0,
pSdb->DeviceRef,
pErrorCon->Code, pErrorCon->Code,
pErrorCon->Detail, pErrorCon->Detail,
pErrorCon->AdditionalDetail, pErrorCon->AdditionalDetail,
pErrorCon->AreaCode, pErrorCon->AreaCode
);
}
return -1;
}
int unpack_get_device_state_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local, io_sAgent *ap)
{
if (pSdb->Result == PNAK_RESULT_POS) {
T_PN_SERVICE_GET_DEVICE_STATE_CON* pGDSC;
T_PN_DIFF_MODULE* pDiffModule;
PN_U16 no_diff_modules;
PN_U16 diff_mod_index;
unsigned short device_ref, ii, jj;
PnDeviceData *device;
unsigned short save_first = TRUE;
unsigned short err_slot_number;
unsigned short err_module_state;
unsigned short phys_ident_number;
unsigned short dev_ind;
device_ref = pSdb->DeviceRef;
/* Find configured device */
for (ii = 0; ii < local->device_data.size(); ii++) {
if (local->device_data[ii]->device_ref == device_ref) {
device = local->device_data[ii];
break;
}
}
if (ii == local->device_data.size()) return -1; // ERR_NODEV_FOUND;
dev_ind = ii;
pGDSC = (T_PN_SERVICE_GET_DEVICE_STATE_CON *) (pSdb + 1);
pDiffModule = (T_PN_DIFF_MODULE *) (pGDSC + 1);
no_diff_modules = _HIGH_LOW_BYTES_TO_PN_U16 (pGDSC->NumberOfDiffModulesHighByte, pGDSC->NumberOfDiffModulesLowByte);
device->no_diff_modules = no_diff_modules;
device->device_state = _HIGH_LOW_BYTES_TO_PN_U16(pGDSC->StateHighByte, pGDSC->StateLowByte);
printf("No diff modules: %d \r\n", no_diff_modules);
for (diff_mod_index = 0u; diff_mod_index < no_diff_modules; diff_mod_index++) {
T_PN_DIFF_MODULE_API *pDiffModuleAPI = (T_PN_DIFF_MODULE_API *) (pDiffModule + 1);
PN_U16 no_apis;
PN_U16 api_ind;
no_apis = _HIGH_LOW_BYTES_TO_PN_U16 (pDiffModule->NumberOfAPIsHighByte, pDiffModule->NumberOfAPIsLowByte);
for (api_ind = 0u; api_ind < no_apis; api_ind++) {
T_PN_DIFF_MODULE_SLOT *pModuleSlot = (T_PN_DIFF_MODULE_SLOT *) (pDiffModuleAPI + 1);
PN_U16 no_slots;
PN_U16 slot_ind;
no_slots = _HIGH_LOW_BYTES_TO_PN_U16 (pDiffModuleAPI->NumberOfModulesHighByte, pDiffModuleAPI->NumberOfModulesLowByte);
for (slot_ind = 0u; slot_ind < no_slots; slot_ind++) {
T_PN_DIFF_MODULE_SUBSLOT *pModuleSubSlot = (T_PN_DIFF_MODULE_SUBSLOT *) (pModuleSlot + 1);
PN_U16 no_subslots;
PN_U16 subslot_ind;
PnModuleData *module_data;
no_subslots = _HIGH_LOW_BYTES_TO_PN_U16 (pModuleSlot->NumberOfSubmodulesHighByte, pModuleSlot->NumberOfSubmodulesLowByte);
for (ii = 0; ii < device->module_data.size(); ii++) {
module_data = device->module_data[ii];
if (module_data->slot_number == _HIGH_LOW_BYTES_TO_PN_U16 (pModuleSlot->SlotNumberHighByte, pModuleSlot->SlotNumberLowByte)) {
module_data->state = _HIGH_LOW_BYTES_TO_PN_U16 (pModuleSlot->StateHighByte, pModuleSlot->StateLowByte);
module_data->phys_ident_number = _HIGH_LOW_BYTES_TO_PN_U32(pModuleSlot->IdentNumberHighWordHighByte,
pModuleSlot->IdentNumberHighWordLowByte,
pModuleSlot->IdentNumberLowWordHighByte,
pModuleSlot->IdentNumberLowWordLowByte);
printf(" Slot no: %d, State: %d \r\n", module_data->slot_number, module_data->state);
if (save_first) {
err_slot_number = module_data->slot_number;
err_module_state = module_data->state;
phys_ident_number = module_data->phys_ident_number;
save_first = FALSE;
}
break;
}
}
for (subslot_ind = 0; subslot_ind < no_subslots; subslot_ind++) {
PnSubmoduleData *submodule_data;
if (ii < device->module_data.size()) {
for (jj = 0; jj < module_data->submodule_data.size(); jj++) {
submodule_data = module_data->submodule_data[jj];
if (submodule_data->subslot_number == _HIGH_LOW_BYTES_TO_PN_U16 (pModuleSubSlot->SubSlotNumberHighByte, pModuleSubSlot->SubSlotNumberLowByte)) {
submodule_data->state = _HIGH_LOW_BYTES_TO_PN_U16 (pModuleSubSlot->StateHighByte, pModuleSubSlot->StateLowByte);
submodule_data->phys_ident_number = _HIGH_LOW_BYTES_TO_PN_U32(pModuleSubSlot->IdentNumberHighWordHighByte,
pModuleSubSlot->IdentNumberHighWordLowByte,
pModuleSubSlot->IdentNumberLowWordHighByte,
pModuleSubSlot->IdentNumberLowWordLowByte);
printf(" SubSlot no: %d, State: %d \r\n", submodule_data->subslot_number, submodule_data->state);
}
}
}
pModuleSubSlot++;
}
pModuleSlot = (T_PN_DIFF_MODULE_SLOT *) pModuleSubSlot;
}
pDiffModuleAPI = (T_PN_DIFF_MODULE_API *) pModuleSlot;
}
pDiffModule = (T_PN_DIFF_MODULE *) pDiffModuleAPI;
}
if (ap) {
/* Find corresponding device */
io_sRack *slave_list;
for (slave_list = ap->racklist, jj = 0;
(slave_list != NULL) && jj < dev_ind - 1;
slave_list = slave_list->next, jj++) {}
if (slave_list) {
pwr_sClass_PnDevice *dev;
dev = (pwr_sClass_PnDevice *) slave_list->op;
dev->NoDiffModules = no_diff_modules;
if (device->device_state == PNAK_DEVICE_STATE_CONNECTED)
dev->Status = PB__NORMAL;
else
dev->Status = PB__NOCONN;
if(!save_first) {
dev->ErrSlotNumber = err_slot_number;
dev->ErrModuleState = err_module_state;
dev->PhysIdentNumber = phys_ident_number;
} else {
dev->ErrSlotNumber = 0;
dev->ErrModuleState = 0;
dev->PhysIdentNumber = 0;
}
}
}
return PNAK_OK;
}
else if (pSdb->Result == PNAK_RESULT_NEG) {
T_PN_SERVICE_ERROR_CON* pErrorCon = (T_PN_SERVICE_ERROR_CON*) (pSdb + 1);
printf(
"channel %d: download.con [-] (%d)\r\n"
" code : %d (0x%02x)\r\n"
" detail : %d (0x%02x)\r\n"
" add. detail: %d (0x%02x)\r\n"
" area : %d (0x%02x)\r\n",
0,
pSdb->DeviceRef,
pErrorCon->Code, pErrorCon->Code,
pErrorCon->Detail, pErrorCon->Detail,
pErrorCon->AdditionalDetail, pErrorCon->AdditionalDetail,
pErrorCon->AreaCode, pErrorCon->AreaCode
);
}
return -1;
}
int unpack_download_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local)
{
if (pSdb->Result == PNAK_RESULT_POS) {
T_PN_SERVICE_DOWNLOAD_CON* pDownloadCon;
T_PN_IOCR_INFO* pIOCRInfo;
PN_U16 NumberIOCRs;
PN_U16 IOCRIndex;
unsigned short device_ref, ii, jj;
PnDeviceData *device;
device_ref = pSdb->DeviceRef;
/* Find configured device */
for (ii = 0; ii < local->device_data.size(); ii++) {
if (local->device_data[ii]->device_ref == device_ref) {
device = local->device_data[ii];
break;
}
}
if (ii == local->device_data.size()) return -1; // ERR_NODEV_FOUND;
pDownloadCon = (T_PN_SERVICE_DOWNLOAD_CON*) (pSdb + 1);
pIOCRInfo = (T_PN_IOCR_INFO*) (pDownloadCon + 1);
NumberIOCRs = _HIGH_LOW_BYTES_TO_PN_U16 (pDownloadCon->NumberOfIOCRHighByte, pDownloadCon->NumberOfIOCRLowByte);
device->alarm_ref = _HIGH_LOW_BYTES_TO_PN_U16(pDownloadCon->AlarmRefHighByte, pDownloadCon->AlarmRefLowByte);
for (IOCRIndex = 0u; IOCRIndex < NumberIOCRs; IOCRIndex++) {
T_PN_API_INFO* pAPIInfo = (T_PN_API_INFO*) (pIOCRInfo + 1);
PN_U16 NumberAPIs;
PN_U16 APIIndex;
PnIOCRData *iocr_data;
unsigned short type;
type = _HIGH_LOW_BYTES_TO_PN_U16(pIOCRInfo->TypeHighByte, pIOCRInfo->TypeLowByte);
for (ii = 0; ii < device->iocr_data.size(); ii++) {
if (device->iocr_data[ii]->type == type) {
iocr_data = device->iocr_data[ii];
break;
}
}
if (ii == device->iocr_data.size()) {
/* This iocr is not found, log some thing and continue */
printf("iocr not found %d \n", type);
continue;
}
iocr_data->type = _HIGH_LOW_BYTES_TO_PN_U16 (pIOCRInfo->TypeHighByte, pIOCRInfo->TypeLowByte);
iocr_data->identifier = _HIGH_LOW_BYTES_TO_PN_U16 (pIOCRInfo->IOCRIdentifierHighByte, pIOCRInfo->IOCRIdentifierLowByte);
iocr_data->io_data_length = _HIGH_LOW_BYTES_TO_PN_U16 (pIOCRInfo->IODataLengthHighByte, pIOCRInfo->IODataLengthLowByte);
iocr_data->io_data = (unsigned char *) calloc(1, iocr_data->io_data_length);
printf(" iocr (0x%04x) 0x%04x %d\r\n",
_HIGH_LOW_BYTES_TO_PN_U16 (pIOCRInfo->TypeHighByte, pIOCRInfo->TypeLowByte),
_HIGH_LOW_BYTES_TO_PN_U16 (pIOCRInfo->IOCRIdentifierHighByte, pIOCRInfo->IOCRIdentifierLowByte),
_HIGH_LOW_BYTES_TO_PN_U16 (pIOCRInfo->IODataLengthHighByte, pIOCRInfo->IODataLengthLowByte));
NumberAPIs = _HIGH_LOW_BYTES_TO_PN_U16 (pIOCRInfo->NumberOfAPIsHighByte, pIOCRInfo->NumberOfAPIsLowByte);
for (APIIndex = 0u; APIIndex < NumberAPIs; APIIndex++) {
T_PN_DATA_INFO* pDataInfo = (T_PN_DATA_INFO*) (pAPIInfo + 1);
PN_U16 NumberIODatas;
PN_U16 IODataIndex;
printf(" api 0x%04x%04x\r\n"
" data\r\n",
_HIGH_LOW_BYTES_TO_PN_U16 (pAPIInfo->APIHighWordHighByte, pAPIInfo->APIHighWordLowByte),
_HIGH_LOW_BYTES_TO_PN_U16 (pAPIInfo->APILowWordHighByte, pAPIInfo->APILowWordLowByte));
NumberIODatas = _HIGH_LOW_BYTES_TO_PN_U16 (pAPIInfo->NumberOfIODataHighByte, pAPIInfo->NumberOfIODataLowByte);
for (IODataIndex = 0u; IODataIndex < NumberIODatas; IODataIndex++) {
printf(" slot: %d subslot: %d offset: %d\r\n",
_HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->SlotNumberHighByte, pDataInfo->SlotNumberLowByte),
_HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->SubSlotNumberHighByte, pDataInfo->SubSlotNumberLowByte),
_HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->OffsetHighByte, pDataInfo->OffsetLowByte));
for (ii = 0; ii < device->module_data.size(); ii++) {
PnModuleData *module_data;
module_data = device->module_data[ii];
if (module_data->slot_number == _HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->SlotNumberHighByte, pDataInfo->SlotNumberLowByte)) {
for (jj = 0; jj < module_data->submodule_data.size(); jj++) {
PnSubmoduleData *submodule_data;
submodule_data = module_data->submodule_data[jj];
if (submodule_data->subslot_number == _HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->SubSlotNumberHighByte, pDataInfo->SubSlotNumberLowByte)) {
if (PROFINET_IO_CR_TYPE_INPUT == type) {
submodule_data->offset_io_in = _HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->OffsetHighByte, pDataInfo->OffsetLowByte);
} else {
submodule_data->offset_io_out = _HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->OffsetHighByte, pDataInfo->OffsetLowByte);
}
}
}
}
}
pDataInfo++;
}
printf (" status\r\n");
NumberIODatas = _HIGH_LOW_BYTES_TO_PN_U16 (pAPIInfo->NumberOfIOStatusHighByte, pAPIInfo->NumberOfIOStatusLowByte);
for (IODataIndex = 0u; IODataIndex < NumberIODatas; IODataIndex++) {
printf(" slot: %d subslot: %d offset: %d\r\n",
_HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->SlotNumberHighByte, pDataInfo->SlotNumberLowByte),
_HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->SubSlotNumberHighByte, pDataInfo->SubSlotNumberLowByte),
_HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->OffsetHighByte, pDataInfo->OffsetLowByte));
for (ii = 0; ii < device->module_data.size(); ii++) {
PnModuleData *module_data;
module_data = device->module_data[ii];
if (module_data->slot_number == _HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->SlotNumberHighByte, pDataInfo->SlotNumberLowByte)) {
for (jj = 0; jj < module_data->submodule_data.size(); jj++) {
PnSubmoduleData *submodule_data;
submodule_data = module_data->submodule_data[jj];
if (submodule_data->subslot_number == _HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->SubSlotNumberHighByte, pDataInfo->SubSlotNumberLowByte)) {
if (PROFINET_IO_CR_TYPE_INPUT == type) {
submodule_data->offset_status_in = _HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->OffsetHighByte, pDataInfo->OffsetLowByte);
} else {
submodule_data->offset_status_out = _HIGH_LOW_BYTES_TO_PN_U16 (pDataInfo->OffsetHighByte, pDataInfo->OffsetLowByte);
}
}
}
}
}
pDataInfo++;
}
pAPIInfo = (T_PN_API_INFO*) pDataInfo;
}
pIOCRInfo = (T_PN_IOCR_INFO*) pAPIInfo;
}
return PNAK_OK;
}
else if (pSdb->Result == PNAK_RESULT_NEG) {
T_PN_SERVICE_ERROR_CON* pErrorCon = (T_PN_SERVICE_ERROR_CON*) (pSdb + 1);
printf(
"channel %d: download.con [-] (%d)\r\n"
" code : %d (0x%02x)\r\n"
" detail : %d (0x%02x)\r\n"
" add. detail: %d (0x%02x)\r\n"
" area : %d (0x%02x)\r\n",
0,
pSdb->DeviceRef,
pErrorCon->Code, pErrorCon->Code,
pErrorCon->Detail, pErrorCon->Detail,
pErrorCon->AdditionalDetail, pErrorCon->AdditionalDetail,
pErrorCon->AreaCode, pErrorCon->AreaCode
);
}
return -1;
}
int handle_service_con(io_sAgentLocal *local, io_sAgent *ap)
{
T_PNAK_WAIT_OBJECT wait_object;
int sts;
unsigned short ii;
wait_object = PNAK_WAIT_OBJECT_SERVICE_CON;
sts = pnak_wait_for_multiple_objects(0, &wait_object, PNAK_INFINITE_TIMEOUT);
if (sts == PNAK_OK) {
memset(&local->service_con, 0, sizeof(T_PNAK_SERVICE_CON));
sts = pnak_get_service_con(0, &local->service_con);
if (sts == PNAK_NOTIFICATION_RECEIVED) {
for (ii = 0; ii < local->service_con.NumberEntries; ii++) {
T_PNAK_SERVICE_DESCRIPTION* pSdb;
unsigned int offset;
offset = local->service_con.ServiceEntry[ii].ServiceOffset;
pSdb = (T_PNAK_SERVICE_DESCRIPTION *) &local->service_con.ServiceChannel[offset];
if ((pSdb->Instance == PN) || (pSdb->Instance == PN_CONTROLLER)) {
switch (pSdb->Service) {
case PN_SERVICE_DOWNLOAD : {
sts = unpack_download_con(pSdb, local);
break;
}
case PN_SERVICE_SET_IDENTIFICATION:
case PN_SERVICE_READ :
case PN_SERVICE_WRITE : {
break;
}
case PN_SERVICE_GET_ALARM : {
sts = unpack_get_alarm_con(pSdb, local, ap);
break;
}
case PN_SERVICE_GET_DEVICE_STATE: {
sts = unpack_get_device_state_con(pSdb, local, ap);
break;
}
case PN_SERVICE_ALARM_ACK : {
break;
}
default: {
printf("channel %d: unhandled service confirmation [0x%x]\r\n",
0,
pSdb->Service
);
}
}
}
else if (pSdb->Instance == PN_SUPERVISOR) {
switch (pSdb->Service) {
case PN_SERVICE_GET_LIST_OF_STATION: {
sts = unpack_get_los_con(pSdb, local);
break;
}
case PN_SERVICE_SET_IDENTIFICATION:
case PN_SERVICE_SET_IP_SETTINGS :
case PN_SERVICE_SET_DEVICE_NAME : {
if (pSdb->Result == PNAK_RESULT_NEG) {
T_PN_SERVICE_ERROR_CON* pErrorCon = (T_PN_SERVICE_ERROR_CON*) (pSdb + 1);
printf(
"channel %d: get_los.con [-] (%d)\r\n"
" code : %d (0x%02x)\r\n"
" detail : %d (0x%02x)\r\n"
" add. detail: %d (0x%02x)\r\n"
" area : %d (0x%02x)\r\n",
0,
pSdb->DeviceRef,
pErrorCon->Code, pErrorCon->Code,
pErrorCon->Detail, pErrorCon->Detail,
pErrorCon->AdditionalDetail, pErrorCon->AdditionalDetail,
pErrorCon->AreaCode, pErrorCon->AreaCode
);
}
break;
}
default: {
printf("channel %d: unhandled service confirmation [0x%x]\r\n",
0,
pSdb->Service
);
}
}
}
}
}
}
return sts;
}
void handle_exception (io_sAgentLocal *local) {
return;
}
void handle_state_changed (io_sAgentLocal *local) {
return;
}
void handle_device_state_changed (io_sAgentLocal *local, io_sAgent *ap) {
int sts;
unsigned short ii, jj;
T_PNAK_EVENT_DEVICE_STATE dev_state;
sts = pnak_get_device_state_ind(0, &dev_state);
if (sts == PNAK_NOTIFICATION_RECEIVED) {
/* Check state for all devices */
for (ii = 1; ii < local->device_data.size(); ii++) {
printf("Dev_ref %d, State, %d \r\n", ii, dev_state.State[ii]);
// for (ii = 0; ii < 1; ii++) {
if (dev_state.State[ii] != local->device_data[ii]->device_state) {
local->device_data[ii]->device_state = dev_state.State[ii];
if (ap) {
/* Find corresponding device */
io_sRack *slave_list;
for (slave_list = ap->racklist, jj = 0;
(slave_list != NULL) && jj < ii - 1;
slave_list = slave_list->next, jj++) {}
if (slave_list) {
pwr_sClass_PnDevice *dev;
dev = (pwr_sClass_PnDevice *) slave_list->op;
dev->State = dev_state.State[ii];
}
}
// if ( dev_state.State[ii] == PNAK_DEVICE_STATE_CONNECTED) {
if (1) {
pack_get_device_state_req(&local->service_req_res, local->device_data[ii]->device_ref);
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, ap);
}
}
}
}
}
return;
}
void handle_alarm_indication (io_sAgentLocal *local, io_sAgent *ap) {
T_PNAK_EVENT_ALARM pAlarm;
int sts;
unsigned short ii, index, bit_no;
sts = pnak_get_alarm_ind(0, &pAlarm);
if (sts == PNAK_NOTIFICATION_RECEIVED) {
for (ii = 0; ii < local->device_data.size(); ii++) {
index = ii / 8;
bit_no = ii % 8;
if (pAlarm.DeviceReference[index] & (1 << bit_no)) {
printf("New alarm for device: %d\r\n", ii);
pack_get_alarm_req(&local->service_req_res, local->device_data[ii]->alarm_ref, local->device_data[ii]->device_ref);
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, ap);
if (sts == PNAK_OK) {
pack_alarm_ack_req(&local->service_req_res, local->device_data[ii]->alarm_ref, local->device_data[ii]->alarm_data.alarm_prio, local->device_data[ii]->device_ref);
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, ap);
}
}
}
break;
}
}
}
}
/* Supervision thread */
void *handle_events(void *ptr) {
agent_args *args;
io_sAgentLocal *local;
io_sAgent *ap;
T_PNAK_WAIT_OBJECT wait_object;
int sts;
args = (agent_args *) ptr;
local = (io_sAgentLocal *) args->local;
ap = args->ap;
/* Do forever ... */
while (1) {
wait_object = PNAK_WAIT_OBJECTS_EVENT_IND | PNAK_WAIT_OBJECTS_OTHER;
sts = pnak_wait_for_multiple_objects(0, &wait_object, 0);
//PNAK_INFINITE_TIMEOUT
if (sts == PNAK_OK) {
if (wait_object & PNAK_WAIT_OBJECT_EXCEPTION) {
handle_exception (local);
}
if (wait_object & PNAK_WAIT_OBJECT_STATE_CHANGED) {
handle_state_changed (local);
}
if (wait_object & PNAK_WAIT_OBJECT_DEVICE_STATE_CHANGED) {
handle_device_state_changed (local, ap);
}
if (wait_object & PNAK_WAIT_OBJECT_ALARM) {
printf("Alarm !!");
handle_alarm_indication (local, ap);
}
if (wait_object & PNAK_WAIT_OBJECT_CHANNEL_CLOSED) {
// What to do if channel closes ???;
}
if (wait_object & PNAK_WAIT_OBJECT_ETHERNET_STATE_CHANGED) {
// What to do if ethernet state changes ???;
}
if (wait_object & PNAK_WAIT_OBJECT_INTERRUPTED) {
// What to do if interrupted ???;
}
}
else if ( (sts == PNAK_ERR_FATAL_ERROR ) ||
(sts == PNAK_EXCEPTION_THROWN) ) {
// user_handle_exception (ChannelId);
}
else {
// pThisSmObject->Running = PN_FALSE;
}
}
}
/*
* Proview $Id$
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**/
/* rt_pn_iface.h -- Profinet driver interface routines */
#ifndef rt_pn_iface_h
#define rt_pn_iface_h
#ifndef pwr_h
# include "pwr.h"
#endif
#ifndef rt_pn_gsdml_data_h
#include "rt_pn_gsdml_data.h"
#endif
#ifndef rt_io_pn_locals_h
# include "rt_io_pn_locals_h.h"
#endif
void pack_set_ip_settings_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, PnDeviceInfo *dev_info);
void pack_set_device_name_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, PnDeviceInfo *dev_info);
void pack_set_identification_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes);
void pack_get_device_state_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, unsigned short device_ref);
void pack_get_los_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes);
void pack_get_alarm_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, unsigned short ref);
void pack_alarm_ack_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, unsigned short ref, unsigned short prio);
void pack_download_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, GsdmlDeviceData *dev_data, unsigned short device_ref);
int unpack_get_los_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local);
int unpack_get_alarm_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local, io_sAgent *ap);
int unpack_get_device_state_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local, io_sAgent *ap);
int unpack_download_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local);
int handle_service_con(io_sAgentLocal *local, io_sAgent *ap);
void handle_exception (io_sAgentLocal *local);
void handle_state_changed (io_sAgentLocal *local);
void handle_device_state_changed (io_sAgentLocal *local, io_sAgent *ap);
void handle_alarm_indication (io_sAgentLocal *local, io_sAgent *ap);
void *handle_events(void *ptr);
#endif
Volume Profibus $ClassVolume 0.0.250.7
Body SysBody 05-SEP-2005 17:51:40.00
Attr NextOix = "_X173"
Attr NextCix = "_X18"
Attr NextTix[0] = "_X9"
Attr NextOix = "_X176"
Attr NextCix = "_X19"
Attr NextTix[0] = "_X10"
EndBody
Object Type $TypeHier 55 16-JAN-2006 10:07:43.21
Object PbNumberRepEnum $TypeDef 1 16-JAN-2006 10:08:18.34
......@@ -293,7 +293,7 @@ Volume Profibus $ClassVolume 0.0.250.7
EndObject
EndObject
Object PnModuleStateEnum $TypeDef 8 12-JAN-2010 17:13:25.79
Body SysBody 12-JAN-2010 17:03:21.67
Body SysBody 10-JUN-2010 10:44:06.67
Attr TypeRef = "pwrs:Type-$Enum"
Attr Elements = 1
EndBody
......@@ -325,6 +325,32 @@ Volume Profibus $ClassVolume 0.0.250.7
EndBody
EndObject
EndObject
Object PnAlarmPrioEnum $TypeDef 9 10-JUN-2010 10:52:14.50
Body SysBody 10-JUN-2010 10:44:11.25
Attr TypeRef = "pwrs:Type-$Enum"
Attr Elements = 1
EndBody
Object None $Value 174 10-JUN-2010 10:44:28.58
Body SysBody 10-JUN-2010 10:44:47.90
Attr Text = "None"
Attr PgmName = "None"
EndBody
EndObject
Object Low $Value 175 10-JUN-2010 10:45:01.28
Body SysBody 10-JUN-2010 10:45:04.64
Attr Text = "Low"
Attr PgmName = "Low"
Attr Value = 1
EndBody
EndObject
Object High $Value 176 10-JUN-2010 10:45:11.89
Body SysBody 10-JUN-2010 10:45:17.29
Attr Text = "High"
Attr PgmName = "High"
Attr Value = 2
EndBody
EndObject
EndObject
EndObject
Object Class $ClassHier 1 16-JAN-2006 10:07:45.26
Object Pb_Ai $ClassDef 2 16-JAN-2006 09:46:40.49
......@@ -2412,6 +2438,79 @@ Volume Profibus $ClassVolume 0.0.250.7
EndBody
EndObject
EndObject
Object PnAlarm $ClassDef 18 10-JUN-2010 10:39:40.30
Body SysBody 10-JUN-2010 10:39:35.83
Attr Editor = 0
Attr Method = 0
Attr Flags = 16
EndBody
Object RtBody $ObjBodyDef 1 10-JUN-2010 10:40:04.61
Body SysBody 10-JUN-2010 10:40:04.61
Attr StructName = "PnAlarm"
Attr NextAix = "_X9"
EndBody
Object Type $Attribute 1 10-JUN-2010 10:53:19.20
Body SysBody 30-JUN-2010 11:02:27.88
Attr PgmName = "Type"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
Object Prio $Attribute 2 10-JUN-2010 10:53:36.41
Body SysBody 30-JUN-2010 11:02:47.21
Attr PgmName = "Prio"
Attr Flags = 1024
Attr TypeRef = "Profibus:Type-PnAlarmPrioEnum"
EndBody
EndObject
Object Remaining $Attribute 3 10-JUN-2010 10:54:32.69
Body SysBody 30-JUN-2010 11:02:51.79
Attr PgmName = "Remaining"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
Object SlotNumber $Attribute 4 10-JUN-2010 11:48:57.48
Body SysBody 30-JUN-2010 11:02:56.16
Attr PgmName = "SlotNumber"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
Object SubslotNumber $Attribute 5 10-JUN-2010 11:49:10.13
Body SysBody 30-JUN-2010 11:03:00.65
Attr PgmName = "SubslotNumber"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
Object ModuleIdentNumber $Attribute 6 10-JUN-2010 11:49:40.15
Body SysBody 30-JUN-2010 11:03:04.71
Attr PgmName = "ModuleIdentNumber"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
Object SubmoduleIdentNumber $Attribute 7 10-JUN-2010 11:49:56.34
Body SysBody 30-JUN-2010 11:03:09.13
Attr PgmName = "SubmoduleIdentNumber"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
Object Specifier $Attribute 8 10-JUN-2010 12:52:57.01
Body SysBody 30-JUN-2010 11:03:34.57
Attr PgmName = "Specifier"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
EndObject
Object Template PnAlarm 2152431616 01-JAN-1970 01:00:00.00
Body RtBody 01-JAN-1970 01:00:00.00
EndBody
EndObject
EndObject
Object PnControllerSoftingPNAK $ClassDef 15 21-APR-2009 13:41:08.17
Body SysBody 21-APR-2009 13:41:08.17
Attr Editor = 0
......@@ -2420,7 +2519,7 @@ Volume Profibus $ClassVolume 0.0.250.7
EndBody
Object RtBody $ObjBodyDef 1 21-APR-2009 13:41:08.17
Body SysBody 21-APR-2009 13:41:08.17
Attr StructName = "Pb_Profiboard"
Attr StructName = "PnControllerSoftingPNAK"
Attr NextAix = "_X57"
EndBody
Object Description $Attribute 53 21-APR-2009 13:41:08.17
......@@ -2477,7 +2576,8 @@ Volume Profibus $ClassVolume 0.0.250.7
EndObject
EndObject
Object Template PnControllerSoftingPNAK 2151645184 01-JAN-1970 01:00:00.00
Body RtBody 01-JAN-1970 01:00:00.00
Body RtBody 30-JUN-2010 11:04:06.73
Attr Process = 1
EndBody
EndObject
EndObject
......@@ -2490,7 +2590,7 @@ Volume Profibus $ClassVolume 0.0.250.7
Object RtBody $ObjBodyDef 1 21-APR-2009 13:41:08.17
Body SysBody 21-APR-2009 13:41:08.17
Attr StructName = "PnDevice"
Attr NextAix = "_X102"
Attr NextAix = "_X105"
EndBody
Object Description $Attribute 87 21-APR-2009 13:41:08.17
Body SysBody 21-APR-2009 13:41:08.17
......@@ -2555,10 +2655,10 @@ Volume Profibus $ClassVolume 0.0.250.7
EndBody
EndObject
Object State $Attribute 97 12-JAN-2010 17:06:58.08
Body SysBody 12-JAN-2010 17:09:22.26
Body SysBody 10-JUN-2010 10:30:30.44
Attr PgmName = "State"
Attr Flags = 3072
Attr TypeRef = "pwrs:Type-$UInt16"
Attr TypeRef = "Profibus:Type-PnDeviceStateEnum"
EndBody
EndObject
Object NoDiffModules $Attribute 98 12-JAN-2010 17:09:39.73
......@@ -2576,7 +2676,7 @@ Volume Profibus $ClassVolume 0.0.250.7
EndBody
EndObject
Object ErrModuleState $Attribute 100 12-JAN-2010 17:11:23.49
Body SysBody 12-JAN-2010 17:13:58.39
Body SysBody 10-JUN-2010 10:30:12.41
Attr PgmName = "ErrModuleState"
Attr Flags = 3072
Attr TypeRef = "Profibus:Type-PnModuleStateEnum"
......@@ -2589,6 +2689,25 @@ Volume Profibus $ClassVolume 0.0.250.7
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
Object ByteOrdering $Attribute 102 09-JUN-2010 10:31:22.82
Body SysBody 09-JUN-2010 10:31:22.82
Attr PgmName = "ByteOrdering"
Attr TypeRef = "pwrb:Type-ByteOrderingEnum"
EndBody
EndObject
Object FloatRepresentation $Attribute 103 09-JUN-2010 10:31:22.82
Body SysBody 09-JUN-2010 10:31:22.82
Attr PgmName = "FloatRepresentation"
Attr TypeRef = "pwrb:Type-FloatRepEnum"
EndBody
EndObject
Object Alarm $Attribute 104 10-JUN-2010 11:50:27.33
Body SysBody 10-JUN-2010 11:51:43.64
Attr PgmName = "Alarm"
Attr Flags = 131072
Attr TypeRef = "Profibus:Class-PnAlarm"
EndBody
EndObject
EndObject
Object ConfiguratorPosnn $Menu 122 21-APR-2009 13:41:08.17
Object Pointed $Menu 123 21-APR-2009 13:41:08.17
......@@ -2720,7 +2839,10 @@ Volume Profibus $ClassVolume 0.0.250.7
EndObject
EndObject
Object Template PnDevice 2151907328 01-JAN-1970 01:00:00.00
Body RtBody 01-JAN-1970 01:00:00.00
Body RtBody 30-JUN-2010 11:04:35.19
Attr Process = 1
Attr ErrorSoftLimit = 100
Attr ErrorHardLimit = 1000
EndBody
EndObject
EndObject
......@@ -2816,7 +2938,8 @@ Volume Profibus $ClassVolume 0.0.250.7
EndObject
EndObject
Object Template PnModule 2152169472 01-JAN-1970 01:00:00.00
Body RtBody 01-JAN-1970 01:00:00.00
Body RtBody 30-JUN-2010 11:04:44.11
Attr Process = 1
EndBody
EndObject
EndObject
......
......@@ -34,6 +34,11 @@
#include "pwr_baseclasses.h"
#endif
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct io_sCtx *io_tCtx;
#ifndef rt_io_supervise_h
......@@ -274,4 +279,8 @@ int io_CheckClassIoType(
void io_methods_print();
#ifdef __cplusplus
}
#endif
#endif
......@@ -592,10 +592,13 @@ void io_card_write(
value = chan_ao->ActValRangeLow;
rawvalue = chan_ao->OutPolyCoef1 * value + chan_ao->OutPolyCoef0;
if ( rawvalue > 0)
rawvalue = rawvalue + 0.5;
else
rawvalue = rawvalue - 0.5;
if (chan_ao->Representation != pwr_eDataRepEnum_Float32) {
if ( rawvalue > 0)
rawvalue = rawvalue + 0.5;
else
rawvalue = rawvalue - 0.5;
}
// sig_ao->RawValue = 0;
......
......@@ -34,6 +34,11 @@
#include "pwr_baseclasses.h"
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef rt_io_supervise_h
#include "rt_io_supervise.h"
#endif
......@@ -78,4 +83,8 @@ void io_card_write(
pwr_tFloatRepEnum float_rep
);
#ifdef __cplusplus
}
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment