Protocol Integration Stack: IEC 61850 Protocol API User Manual
Protocol Integration Stack: IEC 61850 Protocol API User Manual
Protocol Integration Stack: IEC 61850 Protocol API User Manual
Overview
Protocol Stack
Examples
IEC 61850 Protocol
API User Manual
Copyright: All rights reserved. None of the information contained in this document may be reproduced or stored in a
database or retrieval system or disclosed to others without written authorization by SystemCORP Pty Ltd.
The information in this document is subject to change without prior notice and should not be construed as a commitment by
SystemCORP Pty Ltd. SystemCORP Pty Ltd do not assume responsibility for any errors, which may be in this document.
Documentation Control
Table of Contents
1 Introduction..................................................................................................................4
1.1 IEC 61850 ........................................................................................................................................ 4
1.2 Document Reference ....................................................................................................................... 6
1.3 List of Abbreviations ......................................................................................................................... 7
2 Overview .....................................................................................................................9
2.1 Protocol Integration Stack – API Overview ....................................................................................10
2.2 Protocol Integration Stack –Configuration Overview .....................................................................10
3 User Data Attributes (DA)..........................................................................................11
3.1 Configuration of User Data Attribute Information (DAI)..................................................................11
3.1.1 Single Point Status (SPS) common data class example ..............................................................11
3.1.2 Single Point Command (SPC) common data class example.........................................................11
3.2 User Data Attributes Access via API..............................................................................................12
4 Protocol Stack ...........................................................................................................13
4.1 Server.............................................................................................................................................14
4.2 Client ..............................................................................................................................................16
5 API Module Reference and Usage ............................................................................18
5.1 Client/Server Management ............................................................................................................18
5.1.1 Enumeration Type Documentation.................................................................................................19
5.1.2 Function Documentation ................................................................................................................19
5.2 Data IO ...........................................................................................................................................21
5.2.1 Function Documentation ................................................................................................................22
6 API Data Structure.....................................................................................................24
6.1 IEC61850_ObjectData Struct Reference .......................................................................................24
6.2 IEC61850_ObjectID Struct Reference ...........................................................................................24
6.3 IEC61850_Parameters Struct Reference.......................................................................................25
6.4 IEC61850TimeStamp Struct Reference.........................................................................................25
7 Appendix ...................................................................................................................26
7.1 IEC 61850 Error Codes..................................................................................................................26
7.2 IEC 61850 Data Types ...................................................................................................................28
7.3 Examples........................................................................................................................................29
7.3.1 Server Source ................................................................................................................................29
7.3.2 CID File for Server..........................................................................................................................36
7.3.3 Client Source..................................................................................................................................45
7.4 Schema for the Private Elements...................................................................................................46
1 Introduction
A Substation Automation System (SAS) has depended upon the development and availability of microprocessor-
based systems. Thus, the substation equipment evolved from simple electro-mechanical devices to robust digital
devices. This in turn provided the possibility of implementing SAS using several intelligent electronic devices
(IEDs) to perform the required functions (e.g. protection, local and remote monitoring and control). Consequently,
the need arose for efficient communication protocols among the IEDs. Until recently, specific proprietary
communication protocols developed by each manufacturer have been used requiring complicated and costly
protocol converters when using IEDs from different vendors.
The industry’s experiences have demonstrated the need for developing a standard communication protocol,
which would support interoperability of IEDs from different manufacturers. Interoperability is the ability to operate
on the same network or communication path sharing information and commands. Interoperability should not be
confused with interchange-ability of IEDs (i.e. the ability to replace an IED supplied by one manufacturer with an
IED supplied by another manufacturer without having to change other elements in the system). Interchange-ability
is beyond the scope of a communication standard.
Interoperability is a common goal for electric utilities, equipment vendors and standardisation bodies. All
communications must allow for the seamless integration of IEDs that allow devices from multiple vendors to be
integrated together. A consensus must be found between IED manufacturers and users in a way that such
devices can freely exchange information. As a result the International Electro-technical Commission (IEC) has
published the IEC 61850 standard (in 10 parts, see Document Reference list).
SystemCORP Pty Ltd has a Protocol Integration Stack (PIS) that will allow you to build custom client/server
applications via SystemCORP’s API that meets the functional and performance communications requirements
compliant with the IEC 61850 standards, therefore supporting current IEDs, future IEDs, and further substation
technological developments regardless of the vendor.
Substation
The GOOSE messages contain information that allow the receiving device to know that a status has changed and
the time of the last status change. The time of the last status change allows a receiving device to set local timers
relating to a given event.
A newly activated device, upon power-up or reinstatement to service, will send current data (status) or values as
the initial GOOSE message. Moreover, all devices sending GOOSE messages will continue to send the message
with a long cycle time, even if no status/value change has occurred. This ensures that devices that have been
activated recently will know the current status values of their peer devices. [IEC 61850-7-2]
MMS services and protocol are specified to operate over full OSI and TCP compliant communications profiles.
The use of MMS allows provisions for supporting both centralized and distributed architectures. This standard
includes the exchange of real-time data indications, control operations, report notification.
The Manufacturing Message Specification (MMS) protocol suite provides the information modelling methods and
services required by the Abstract Communication Service Interface (ACSI). This mapping of ACSI to MMS
defines how the concepts, objects, and services of the ACSI are to be implemented using MMS concepts,
objects, and services. This allows interoperability across functions implemented by different IEDs regardless of
the manufacturer. [IEC 61850-7-2, IEC 61850-8-1]
SNTP (Simple Network Time Protocol) is a time synchronization protocol providing time synchronization with
other IEDs. SNTP protocol is widely used in synchronizing computer systems within a network. The SNTP-
servers themselves are synchronized to timeservers traceable to international standards. UTC time accuracy from
SNTP systems is usually in the millisecond range. SNTP provides the current time, the current number of leap
seconds, and the warning flags marking the introduction of a leap second correction. [ICE 61850-8-1]
The transmission of Sampled Values (SV) requires special attention with regard to the time constraints. The
model provides transmission of sampled values in an organized and time controlled way so that the combined
jitter of sampling and transmission is minimized to a degree that an unambiguous allocation of the samples,
times, and sequence is provided.
The SV model applies to the exchange of values of a dataset. The data of the dataset are of the common data
class Sampled Analog Value (SV as defined in IEC 61850-7-3). A buffer structure is defined for the transmission
of the sampled values.
The information exchange is based on a publisher/subscriber mechanism. The publisher writes the values in a
local buffer at the sending side. The subscriber reads the values from a local buffer at the receiving side. A time
stamp is added to the values, so that the subscriber can check the timeliness of the values. The communication
system is responsible to update the local buffers of the subscribers. A sampled value control (SVC) in the
publisher is used to control the communication procedure. [IEC 61850-7-2]
In general, the IEC 61850 approach is to blend the strengths of the following three methods: functional
decomposition, data flow, and information modelling.
Functional decomposition is used to understand the logical relationship between components of a distributed
function, and is presented in terms of logical nodes that describe the functions, sub-functions and functional
interfaces.
Data flow is used to understand the communication interfaces that must support the exchange of information
between distributed functional components and the functional performance requirements.
Information modelling is used to define the abstract syntax and semantics of the information exchanged, and is
presented in terms of data object classes and types, attributes, abstract object methods (services), and their
relationships.
PD = Physical Device
PICS = Protocol Implementation Conformance Statement
PIS = Protocol Integration Stack
PIXIT = Protocol Implementation eXtra Information for Testing
RTOS = Real Time Operating System
RTU = Remote Terminal Unit
SAS = Substation Automation System
SAT = Site Acceptance Test
SAV = Sampled Analogue Value (IEC 61850-9 series)
SBO = Select Before Operate
SCADA = Supervisory Control And Data Acquisition
SCD = Substation Configuration Description.
SCL = Substation Configuration Language
SCSM = Specific Communication Service Mapping
SGCB = Setting Group Control Block
SoE = Sequence-of-Events
SPS = Single Point Status information
SSD = System Specification Description
SUT = System Under Test
SV = Sampled Values
SVC = Sampled Value Control
TCP = Transport Control Protocol
TPAA = Two Party Application Association
URCB = Unbuffered Report Control Block
USVCB = Unicast Sampled Value Control Block
UTC = Coordinated Universal Time
VT = Voltage Transducer
WDS = WebCAN Designer Studio
XML = eXtensible Markup Language
2 Overview
User Application
API
The API “Calls” and “Call-backs” access
the data within the data module via the
Data Attribute (DA) ID.
Call-backs Calls
IEC 61850
Protocol
The SCL File contains the
Integration
Stack – 010
object model that holds the
SCL Data Attribute (DA) ID’s
File used to indentify each data
object.
Set time
An independent SNTP
Operating System SNTP Client sets the Operating
Client System time.
Ethernet Packet
TCP/IP Driver
Ethernet
The PIS -010 implementation allows users to integrate a Server or Client applications easily. It uses the
Substation Configuration Language (SCL) XML file format using “Private Elements” for mapping the 61850
objects to User Application objects using the Data Attribute ID. The call-back functions must be provided to the
PIS-010 for converting the mapped objects to 61850 objects.
Protocol
User Integration
Application API Stack 010
Update (C)
Object C DA – Z
The user application objects are read, written or updated using the call-back functions with Data Attribute (DA) ID.
PIS – 010
User Stack
Application
Uses Private SCL XML with XML Parser
Element to Private Element
identify within Data Attributes MMS
Data
Attributes
GOOSE
An SCL configuration must be provided to the PIS-010 for it to configure an IEC 61850 data template.
The SCL uses “Private Elements” as part of the Data Attribute Information (DAI). Private Elements describe and
link user application objects, which are part of the user application, with IEC 61850 Data Attributes (DA). This can
also be described as the mapping mechanism between user application and the IEC 61850 stack. Use either the
SystemCORP WebCAN ICD Designer or any third-party tool that can read the XML schema to generate the SCL
file. The WebCAN ICD Designer uses “SystemCorp_Generic” as Private Elements.
Example Server Program is in Appendix 7.3.1. Also, see “Appendix 7.3.2 – CID File for Server” for an example
SCL (a CID – Configured IED Description) file created by the SystemCORP WebCAN ICD Designer.
The SCL (Substation Configuration Language) files include all the information needed to configure IEDs,
communication networks and substation topologies. The SCL file is described in a XML format so it can be easily
interpreted and transformed. The schema restricts the information allowed and it assures that its information can
be processed by different tools. As an example, below is the Omicron IED Scout showing one possible mapping
from a source.
DNP 3
Index: 10
IEC 101
IOA: 1000
Mobus
Register: 100
User
Object: X
Using “Private Elements”, the 61850 data attributes can than be mapped by any user configuration tool into
objects such as a DNP 3 Index, IEC 101 Information Object Address, Modbus Register and any other user
specific object as the Private Element as part of the configuration.
The Private section is included inside the “DAI” element. Below is an example of how it is used. The examples
describe the use for a generic application when Private type="SystemCORP_Generic" is used. In the
examples all the information has been included at the DAI level:
</Private>
</DAI>
</SDI>
<DAI name="ctlModel" valKind="Set">
<Val>direct-with-normal-security</Val>
</DAI>
</DOI>
Note: Both the above examples shows a xmlns:SystemCorp_Generic http link that is not active. It is an XML
name space (xmlns) used for validation only according to the IEC 61850 specification.
Field Attributes:
Both the SPS and SPC examples above use the SystemCorp_Generic:GenericPrivateObject Field
attributes. “Field1” to “Field5” are used to identify the mapping between IEC 61850 data attributes and the user
data objects. The meaning and contents of this field attributes has to be defined by the application programmer.
For example, using the DK61 Development Kit the Field meanings and contents are:
Once loaded the user Data Attributes can be accessed via read, write, update functions by specifying the DA ID
that is assigned to the required DA.
4 Protocol Stack
This section describes the interface provided between the PIS-010 and user application. The API is divided into
two categories listed below.
Client/Server Management
Data Attributes Access
When integrating the IEC 61850 stack into a third party software application the programmer is provided with call-
back functions described below. No programming inside the stack software is required. Integration work is
required linking the stack to the Ethernet driver environment of the target system.
The tables below summaries all API functions needed for interfacing a user application to the PIS-10 IEC 61850
stack.
User Objects are managed by using call-back functions. In case of server the read and write call-back must be
provided by the user application when using the “IEC61850_Create” function so that PIS-010 call these functions
when it reads are writes. In case of client, the “IEC61850_Update” function call-back provided during the client
creation is used to update the user objects.
The following sections provided data flow between PIS-010 and a user application.
4.1 Server
The section describes how the data is exchanged between PIS-010 and server user application.
IEC61850_Create
IEC61850_LoadSCLFile
IEC61850_Start
Client
My_User_Write
Write
IEC61850_Update
Client
My_User_Read
New Read
Value
IEC61850_Stop
IEC61850_Free
Read
Call-back
Protocol Read
Integration
Stack 010
Read
Value
Response
Write
Call-back
Protocol Write
Integration
Stack 010
Perform
Drive
Output
Response
Protocol
New Update
Integration
Value API
Stack 010
Boolean:
False
LOG
The SCD file defines all subscribers for GOOSE services. GOOSE messages are then automatically generated
by the PIS-10 stack.
4.2 Client
The section describes how the data is exchanged between PIS-010 and client user application.
Client: Call-backs:
IEC61850_Create
IEC61850_LoadSCLFile
IEC61850_Start
IEC61850_Read New
IEC61850_Write My_User_Update
Value
IEC61850_Stop
IEC61850_Free
Read Protocol
API Integration
Stack 010
Read
Response
Return
Boolean:
True
Boolean:
True Write Protocol
API Integration
Stack 010
Write
Response
Return
Protocol
Integration
Stack 010
Update
Call-back
Boolean:
False
The SCD file defines all GOOSE services as subscriber. The PIS-10 stack then processes all incoming GOOSE
messages accordingly.
(See IEC 61850-7-2:2003 section 5.5.3.4 for Read Write and Update callbacks returned service error codes.).
Data Structures
struct IEC61850_Parameters
Create Server/client parameters structure.
Typedefs
Enumerations
Functions
Enumerator:
IEC61850_SERVER This IEC61850 Object is a Client
IEC61850_CLIENT This IEC61850 Object is a Server
Parameters:
ptParameters IEC 61850 Object Parameters.
errorCode pointer to return integer for error code if an error occurred.
Returns:
Pointer to a new IEC 61850 object
NULL if an error occurred (errorCode will contain an error code)
tServerParam.ClientServerFlag = IEC61850_SERVER;
tServerParam.ptReadCallback = MyReadFunction;
tServerParam.ptWriteCallback = MyWriteFunction;
tServerParam.ptUpdateCallback = NULL;
myServer = IEC61850_Create(&tServerParam,&error);
//Create a server
if(myServer == NULL)
{
printf("Server Failed to create: %i", error);
}
tClientParam.ClientServerFlag = IEC61850_CLIENT;
tClientParam.ptReadCallback = NULL;
tClientParam.ptWriteCallback = NULL;
tClientParam.ptUpdateCallback = MyUpdateFunction;
myClient = IEC61850_Create(&tClientParam,&error);
//Create a client
if(myClient == NULL)
{
printf("Client Failed to create:%i",error);
}
Parameters:
clientServerObject Server/Client object to free
Example Usage:
IEC61850_Free(myServer); //Frees myServer
Parameters:
clientServer client/Server object
SCLFileName File name of the SCL file
Returns:
IEC61850_ERROR_NONE on success otherwise error code
Example Usage:
error = IEC61850_LoadSCLFile(myServer,"myIDE.icd");
// Load in my IDE.icd file
if(error != IEC61850_ERROR_NONE)
{
printf("Loading SCL file has failed: %i",error);
}
Parameters:
clientServer client or Server object to start
Returns:
IEC61850_ERROR_NONE on success otherwise error code
Example Usage:
error = IEC61850_Start(myServer); // Starts myServer
if(error != IEC61850_ERROR_NONE)
{
printf("Can’t start server: %i",error);
}
Parameters:
clientServer client or Server object to stop
Returns:
IEC61850_ERROR_NONE on success otherwise error code
Example Usage:
error = IEC61850_Stop(myServer); // Stops myServer
if(error != IEC61850_ERROR_NONE)
{
printf("Can’t stop server: %i",error);
}
5.2 Data IO
Data Structures
• struct IEC61850_ObjectID
This structure holds the identification of a IEC61850 data object. This is an example structure
that matches the PIS10 schema. This can be customised to suit your requirements.
• struct IEC61850_ObjectData
A Data object structure used to exchange data objects between IEC61850 object and application.
Typedefs
Functions
• int _IEC61850_Update (IEC61850 server, IEC61850_-
ObjectID *ptObjectID, const IEC61850_ObjectData *ptNewValue)
Update a given Object of tObjectID with value of ptNewValue.
Parameters:
client Client object to read from
ptObjectID Pointer to Object ID that is to be read
ptReturnedValue Pointer to Object Data structure that hold the returned value of the tObjectID
Returns:
IEC61850_ERROR_NONE on success otherwise error code
Example Usage:
IEC61850_ObjectData Value;
IEC61850_ObjectID Object;
Unsigned32 u32Counter;
// Load Data
Value.ucType = IEC61850_DATATYPE_INT32;
Value.uiBitLength = sizeof(u32Counter)*8;
Value.pvData = &u32Counter;
// Load ID
Object.uiNumber = 43;
error = IEC61850_Read(myServer,&Object,&Value);
// Read object with uiNumber = 43
if(error != IEC61850_ERROR_NONE)
{
printf("error has occured: %i",error);
}
else
{
printf("Count = %u",u32Counter);
}
Parameters:
server Server/Client object to update
ptObjectID Pointer to Object ID that has been updated
ptNewValue Pointer to Object Data structure that hold the new value of the object
Returns:
Example Usage:
IEC61850_ObjectData Value;
IEC61850_ObjectID Object;
Unsigned32 u32Counter;
u32Counter = 34;
// Load Data
Value.ucType = IEC61850_DATATYPE_INT32;
Value.uiBitLength = sizeof(u32Counter)*8;
Value.pvData = &u32Counter;
// Load ID
Object.uiNumber = 596;
error = IEC61850_Update(myServer, &Object, &Value);
// Update object with uiNumber = 596 with value of 34
if(error != IEC61850_ERROR_NONE)
{
printf("Update failed: %i",error);
}
Parameters:
client Client object to write to
ptObjectID Pointer to Object ID structure that is to be written
ptNewValue Pointer to Object Data structure that hold the new value of the tObjectID
Returns:
Example Usage:
IEC61850_ObjectData Value;
IEC61850_ObjectID Object;
char bFlag;
bFlag = 1; // Set flag equal to True
// Load Data
Value.ucType = IEC61850_DATATYPE_BOOLEAN;
Value.uiBitLength = sizeof(bFlag)*8;
Value.pvData = &bFlag;
// Load ID
Object.uiNumber = 36;
error = IEC61850_Write(myServer, &Object, &Value);
// Update object with uiNumber = 36 with value of TRUE
if(error != IEC61850_ERROR_NONE)
{
printf("Write has failed: %i",error);
}
#include <IEC61850API.h>
Data Fields
A Data object structure. Used to exchange data objects between IEC61850 object and application.
#include <IEC61850API.h>
Data Fields
unsigned int uiCFENumber The ID Number of the CFE that this data
belongs. (Equal to CFENo attribute in the PIS10
schema)
unsigned int uiClass Data Class of this data instance (Equal to Class
attribute in the PIS10 schema)
unsigned int uiNumber The Object number of this data instance (Equal
to Number attribute in the PIS10 schema)
unsigned int uiField The data field this data belongs. (Data, Quality or
Timestamp) (Equal to Field attribute in the PIS10
schema)
unsigned int uiCommandPort The Command Port of this object
This structure hold the identification of a IEC61850 data object. This is an example structure that matches the
PIS10 schema. This can be customised to suit your requirements.
#include <IEC61850API.h>
Data Fields
#include <IEC61850API.h>
Data Fields
7 Appendix
enum IEC61850_ErrorCodes
Enumerator:
enum IEC61850_CallbackReturnServiceErrorCodes
Enumerator:
enum IEC61850_DataTypes
enum IEC61850QualityFlags
enum IEC61850TimeQualityFlags
IEC61850_TIMEQUALITY_LEAP_SECOND_KNOWN 0x0000000080
IEC61850_TIMEQUALITY_CLOCK_FAILURE 0x0000000040
IEC61850_TIMEQUALITY_CLOCK_NOT_SYNCHRONIZED 0x0000000020
IEC61850_TIMEQUALITY_0_BIT_OF_ACCURACY 0x0000000000
IEC61850_TIMEQUALITY_1_BIT_OF_ACCURACY 0x0000000001
IEC61850_TIMEQUALITY_24_BIT_OF_ACCURACY 0x0000000018
IEC61850_TIMEQUALITY_ACCURACY_UNSPECIFIED 0x000000001F
7.3 Examples
To run
SV61850.EXE <FILENAME.ICD>
e.g DK61.ICD
******************************************************/
#include <clib.h>
#include <stdio.h>
#include <mem.h>
//#define DEBUG_SV61850 1
/* Maximum Object types */
#define OBJECT_TYPES 2
/* Object Types */
enum
{
DIGITAL_INPUT = 1, // Digital Input (DIP Switch )
DIGITAL_OUTPUT = 2, // Digital Output (LED )
}eObjectTypes;
enum
{
DIGINPUT_INDEX = 0, // Digital Input
DIGOUTPUT_INDEX = 1, // Digital Output
}eObjectIndex;
/* Objects */
typedef struct tag_DK61Object
{
unsigned char ucObjectNo; /* Object Number */
unsigned char ucObjectType; /* Object Type */
unsigned char ucObjectValue; /* Object Value */
unsigned short int usiObjectQuality; /* Object Quality */
tNTPTimeStamp tObjectTime; /* Obect Time */
}tDK61Object;
/* Full Quality */
typedef struct tag_FullQuality
{
unsigned char ucvalidity; /* validity */
unsigned char ucdetailQual; /* detail quality */
unsigned char ucsource; /* source */
unsigned char uctest; /* testing ? */
unsigned char ucoperatorBlocked; /* operator blocked */
}tFullQuality;
/* Local Database */
tDK61Object atObj[OBJECT_TYPES][OBJECTS];
/* IO Handler Function */
void huge IOHandler(void);
/* IEC61850 Server */
IEC61850 myServer = 0;
/* Main Function */
int main(int argc, char *argv[])
{
tTimeDate.yr = 10;
tTimeDate.mn = 01;
tTimeDate.dy = 01;
tTimeDate.hr = 00;
tTimeDate.mn = 00;
tTimeDate.sec = 00;
RTX_Set_TimeDate(&tTimeDate);
do
{
tServerParam.ClientServerFlag = IEC61850_SERVER; // This is a Server
tServerParam.ptReadCallback = MyReadFunction; // Assign Read Callback function
tServerParam.ptWriteCallback = MyWriteFunction; // Assign Write Callback function
tServerParam.ptUpdateCallback = NULL; // No Update callback for Server
/* Do not Exit */
while(1)
{
RTX_Sleep_Time(30000);
}
}
else
{
/* If any errors in Create and Starting the Server */
return 0;
}
/* Initialise Value to 0 */
atObj[ucObjTypeCnt][ucObjects].ucObjectValue = 0;
Object.uiField3 = VALUE_INDEX;
UpdateValue.pvData = &atObj[ucObjTypeCnt][ucObjects].ucObjectValue;
UpdateValue.ucType = IEC61850_DATATYPE_BOOLEAN;
UpdateValue.uiBitLength = 8;
if(Object.uiField2 == DIGITAL_INPUT)
{
/* Initialise Quality */
atObj[ucObjTypeCnt][ucObjects].usiObjectQuality
= (IEC61850_QUALITY_FAILURE | IEC61850_QUALITY_INVALID |
IEC61850_QUALITY_OLDDATA | IEC61850_QUALITY_QUESTIONABLE );
Object.uiField3 = QUALITY_INDEX;
UpdateValue.pvData = &atObj[ucObjTypeCnt][ucObjects].usiObjectQuality;
UpdateValue.ucType = IEC61850_DATATYPE_QUALITY;
UpdateValue.uiBitLength = IEC61850_QUALITY_BITSIZE;
/* Initialise Time */
ConvertTo61850Time(&atObj[ucObjTypeCnt][ucObjects].tObjectTime);
Object.uiField3 = TIME_STAMP_INDEX;
UpdateValue.pvData = &atObj[ucObjTypeCnt][ucObjects].tObjectTime;
UpdateValue.ucType = IEC61850_DATATYPE_TIMESTAMP;
UpdateValue.uiBitLength = IEC61850_TIMESTAMP_BITSIZE;
}
}
}
if(ptObjectID->uiField3 == VALUE_INDEX)
{
/* Return Value */
memcpy(ptReturnedValue->pvData,
&atObj[DIGINPUT_INDEX][ucObjects].ucObjectValue,(ptReturnedValue->uiBitLength/8));
ucFound = 1;
}
if(ucFound) break;
if(ptObjectID->uiField3 == QUALITY_INDEX)
{
/* Return Value */
memcpy(ptReturnedValue->pvData,
&atObj[DIGINPUT_INDEX][ucObjects].usiObjectQuality,2);
ucFound = 1;
}
if(ucFound) break;
if(ptObjectID->uiField3 == TIME_STAMP_INDEX)
{
/* Return Value */
memcpy(ptReturnedValue->pvData,
&atObj[DIGINPUT_INDEX][ucObjects].tObjectTime,(IEC61850_TIMESTAMP_BITSIZE/8));
ucFound = 1;
}
if(ucFound) break;
if(ucFound) break;
}
return (0);
}
/* Write Function */
int MyWriteFunction(IEC61850_ObjectID * ptObjectID, const IEC61850_ObjectData * ptNewValue)
{
// static unsigned char ucPrevLED = 0;
unsigned char ucLED = 0;
unsigned char ucObjects = 0;
unsigned char blLEDChange = 0;
unsigned char ucFound = 0;
if(ptObjectID->uiField3 == VALUE_INDEX)
{
/* Get the Value of the */
memcpy(&ucLED, ptNewValue->pvData, sizeof(unsigned char));
if(ucFound) break;
}
/* LED Changed */
if(blLEDChange)
{
ucLED = 0;
/* Get all the values of the LED */
for(ucObjects = 0; ucObjects < OBJECTS; ucObjects++)
{
/* Form Byte to Output */
ucLED = (ucLED | (atObj[DIGOUTPUT_INDEX][ucObjects].ucObjectValue << ucObjects));
}
#ifdef DEBUG_SV61850
printf("\r\n Write LED : %X ", ucLED);
#endif
/* Output the LED */
outportb(IO_ADDR,ucLED);
}
return(0);
}
/* IO Handler Task */
void huge IOHandler(void)
{
unsigned char ucDIPValue = 0; // DIP Switch Value
unsigned char ucPrevDIPValue = 0; // Previous DIP Swithc Value
unsigned char nucObjects = 0; // Total Objects
IEC61850_ObjectData UpdateValue = {0}; // Value to send on Change
IEC61850_ObjectID Object = {0}; // ID of the Object
unsigned char ucObjectVal = 0; // Local Object Value
unsigned short int usiQuality = 0; // Local Quality
tNTPTimeStamp tNTPTime = {0}; // Local Time Stamp
/* Object Value */
UpdateValue.pvData = &ucObjectVal;
UpdateValue.ucType = IEC61850_DATATYPE_BOOLEAN;
UpdateValue.uiBitLength = 8;
/* Object Quality */
/* Send Time */
/* Convert to 61850 Time */
ConvertTo61850Time(&tNTPTime);
UpdateValue.pvData = &tNTPTime;
UpdateValue.ucType = IEC61850_DATATYPE_TIMESTAMP;
UpdateValue.uiBitLength = IEC61850_TIMESTAMP_BITSIZE;
Object.uiField3 = TIME_STAMP_INDEX;
RTX_Get_TimeDate (&tTimeDate);
tTime.ti_hour = tTimeDate.hr;
tTime.ti_min = tTimeDate.min;
tTime.ti_sec = tTimeDate.sec;
tDate.da_day = tTimeDate.dy;
tDate.da_mon = tTimeDate.mn;
tDate.da_year = tTimeDate.yr + 2000;
ptObjectTime->uliFractionsOfSecond = 0;
{
uliMicrosec = uliMicrosec * 2; // Check for a muilt of fraction
if(uliMicrosec >= 1000000L)
{
ptObjectTime->uliFractionsOfSecond = ptObjectTime->uliFractionsOfSecond | uliDigit;
// Set bit to 1
uliMicrosec = uliMicrosec - 1000000L; // Remove 1000000
}
}
<DAI name="t">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="3" Field2="1" Field3="3" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</DOI>
<DOI name="Ind4">
<DAI name="stVal">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="4" Field2="1" Field3="1" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
<DAI name="q">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="4" Field2="1" Field3="2" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
<DAI name="t">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="4" Field2="1" Field3="3" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</DOI>
</LN>
<LN lnClass="GGIO" inst="2" prefix="DIPS_" lnType="GGIO_10">
<DOI name="Alm5">
<DAI name="stVal">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="5" Field2="1" Field3="1" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
<DAI name="q">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="5" Field2="1" Field3="2" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
<DAI name="t">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="5" Field2="1" Field3="3" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</DOI>
<DOI name="Alm6">
<DAI name="stVal">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="6" Field2="1" Field3="1" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
<DAI name="q">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="6" Field2="1" Field3="2" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
<DAI name="t">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="6" Field2="1" Field3="3" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</DOI>
<DOI name="Alm7">
<DAI name="stVal">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="7" Field2="1" Field3="1" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
<DAI name="q">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="7" Field2="1" Field3="2" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
<DAI name="t">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="7" Field2="1" Field3="3" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</DOI>
<DOI name="Alm8">
<DAI name="stVal">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="8" Field2="1" Field3="1" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
<DAI name="q">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="8" Field2="1" Field3="2" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
<DAI name="t">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="8" Field2="1" Field3="3" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</DOI>
</LN>
<LN lnClass="GGIO" inst="3" prefix="LEDO_" lnType="GGIO_17">
<DOI name="SPCSO1">
<SDI name="Oper">
<DAI name="ctlVal">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="1" Field2="2" Field3="1" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</SDI>
<DAI name="ctlModel" valKind="Set">
<Val>direct-with-normal-security</Val>
</DAI>
</DOI>
<DOI name="SPCSO2">
<SDI name="Oper">
<DAI name="ctlVal">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="2" Field2="2" Field3="1" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</SDI>
<DAI name="ctlModel" valKind="Set">
<Val>direct-with-normal-security</Val>
</DAI>
</DOI>
<DOI name="SPCSO3">
<SDI name="Oper">
<DAI name="ctlVal">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="3" Field2="2" Field3="1" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</SDI>
<DAI name="ctlModel" valKind="Set">
<Val>direct-with-normal-security</Val>
</DAI>
</DOI>
<DOI name="SPCSO4">
<SDI name="Oper">
<DAI name="ctlVal">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="4" Field2="2" Field3="1" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</SDI>
<DAI name="ctlModel" valKind="Set">
<Val>direct-with-normal-security</Val>
</DAI>
</DOI>
<DOI name="SPCSO5">
<SDI name="Oper">
<DAI name="ctlVal">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="5" Field2="2" Field3="1" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</SDI>
<DAI name="ctlModel" valKind="Set">
<Val>direct-with-normal-security</Val>
</DAI>
</DOI>
<DOI name="SPCSO6">
<SDI name="Oper">
<DAI name="ctlVal">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="6" Field2="2" Field3="1" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</SDI>
<DAI name="ctlModel" valKind="Set">
<Val>direct-with-normal-security</Val>
</DAI>
</DOI>
<DOI name="SPCSO7">
<SDI name="Oper">
<DAI name="ctlVal">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="7" Field2="2" Field3="1" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</SDI>
<DAI name="ctlModel" valKind="Set">
<Val>direct-with-normal-security</Val>
</DAI>
</DOI>
<DOI name="SPCSO8">
<SDI name="Oper">
<DAI name="ctlVal">
<Private type="SystemCorp_Generic">
<SystemCorp_Generic:GenericPrivateObject Field1="8" Field2="2" Field3="1" Field4="0" Field5="0"
xmlns:SystemCorp_Generic="http://www.systemcorp.com.au/61850/SCL/Generic"/></Private>
</DAI>
</SDI>
<DAI name="ctlModel" valKind="Set">
<Val>direct-with-normal-security</Val>
</DAI>
</DOI>
</LN>
</LDevice>
</Server>
</AccessPoint>
</IED>
<DataTypeTemplates>
<LNodeType lnClass="LLN0" id="LLN0_0">
<DO name="Mod" type="INC_1"/>
<DO name="Beh" type="INS_2"/>
<DO name="Health" type="INS_3"/>
<DO name="NamPlt" type="LPL_0"/>
</LNodeType>
<LNodeType lnClass="GGIO" id="GGIO_0">
<DO name="Mod" type="INC_0"/>
<DO name="Beh" type="INS_0"/>
<DO name="Health" type="INS_1"/>
<DO name="NamPlt" type="LPL_1"/>
<DO name="Ind1" type="SPS_0"/>
<DO name="Ind2" type="SPS_0"/>
<DO name="Ind3" type="SPS_0"/>
<DO name="Ind4" type="SPS_0"/>
</LNodeType>
<LNodeType lnClass="GGIO" id="GGIO_1">
<DO name="Mod" type="INC_2"/>
<DO name="Beh" type="INS_4"/>
<DO name="Health" type="INS_5"/>
<DO name="NamPlt" type="LPL_2"/>
<DO name="Alm1" type="SPS_1"/>
<DO name="Alm2" type="SPS_1"/>
<DO name="Alm3" type="SPS_1"/>
<DO name="Alm4" type="SPS_1"/>
</LNodeType>
<LNodeType lnClass="GGIO" id="GGIO_2">
<DO name="Mod" type="INC_2"/>
<DO name="Beh" type="INS_4"/>
<DO name="Health" type="INS_5"/>
<DO name="NamPlt" type="LPL_2"/>
</DOType>
<DOType cdc="LPL" id="LPL_0">
<DA fc="DC" name="vendor" bType="VisString255"/>
<DA fc="DC" name="swRev" bType="VisString255"/>
<DA fc="DC" name="d" bType="VisString255"/>
</DOType>
<DOType cdc="INC" id="INC_0" desc="Controllable integer status">
<DA dchg="true" fc="ST" name="stVal" bType="INT32"/>
<DA qchg="true" fc="ST" name="q" bType="Quality"/>
<DA fc="ST" name="t" bType="Timestamp"/>
<DA fc="CF" name="ctlModel" bType="Enum" type="CtlModels"/>
</DOType>
<DOType cdc="INS" id="INS_0" desc="Integer status">
<DA dchg="true" fc="ST" name="stVal" bType="INT32"/>
<DA qchg="true" fc="ST" name="q" bType="Quality"/>
<DA fc="ST" name="t" bType="Timestamp"/>
</DOType>
<DOType cdc="INS" id="INS_1" desc="Integer status">
<DA dchg="true" fc="ST" name="stVal" bType="INT32"/>
<DA qchg="true" fc="ST" name="q" bType="Quality"/>
<DA fc="ST" name="t" bType="Timestamp"/>
</DOType>
<DOType cdc="LPL" id="LPL_1" desc="Logical Node name plate">
<DA fc="DC" name="vendor" bType="VisString255"/>
<DA fc="DC" name="swRev" bType="VisString255"/>
<DA fc="DC" name="d" bType="VisString255"/>
</DOType>
<DOType cdc="SPS" id="SPS_0" desc="Single point status">
<DA dchg="true" fc="ST" name="stVal" bType="BOOLEAN"/>
<DA qchg="true" fc="ST" name="q" bType="Quality"/>
<DA fc="ST" name="t" bType="Timestamp"/>
</DOType>
<DOType cdc="INC" id="INC_2" desc="Controllable integer status">
<DA dchg="true" fc="ST" name="stVal" bType="INT32"/>
<DA qchg="true" fc="ST" name="q" bType="Quality"/>
<DA fc="ST" name="t" bType="Timestamp"/>
<DA fc="CF" name="ctlModel" bType="Enum" type="CtlModels"/>
</DOType>
<DOType cdc="INS" id="INS_4" desc="Integer status">
<DA dchg="true" fc="ST" name="stVal" bType="INT32"/>
<DA qchg="true" fc="ST" name="q" bType="Quality"/>
<DA fc="ST" name="t" bType="Timestamp"/>
</DOType>
<DOType cdc="INS" id="INS_5" desc="Integer status">
<DA dchg="true" fc="ST" name="stVal" bType="INT32"/>
<DA qchg="true" fc="ST" name="q" bType="Quality"/>
<DA fc="ST" name="t" bType="Timestamp"/>
</DOType>
<DOType cdc="LPL" id="LPL_2" desc="Logical Node name plate">
<DA fc="DC" name="vendor" bType="VisString255"/>
<DA fc="DC" name="swRev" bType="VisString255"/>
<DA fc="DC" name="d" bType="VisString255"/>
</DOType>
<DOType cdc="SPS" id="SPS_1" desc="Single point status">
<DA dchg="true" fc="ST" name="stVal" bType="BOOLEAN"/>
<DA qchg="true" fc="ST" name="q" bType="Quality"/>
<DA fc="ST" name="t" bType="Timestamp"/>
</DOType>
<DOType cdc="SPS" id="SPS_2" desc="Single point status">
<DA dchg="true" fc="ST" name="stVal" bType="BOOLEAN"/>
<DA qchg="true" fc="ST" name="q" bType="Quality"/>
<DA fc="ST" name="t" bType="Timestamp"/>
</DOType>
<DOType cdc="SPS" id="SPS_3" desc="Single point status">
<DA dchg="true" fc="ST" name="stVal" bType="BOOLEAN"/>
<DA qchg="true" fc="ST" name="q" bType="Quality"/>
<DA fc="ST" name="t" bType="Timestamp"/>
</DOType>
<DOType cdc="SPS" id="SPS_4" desc="Single point status">
<DA dchg="true" fc="ST" name="stVal" bType="BOOLEAN"/>
<DA qchg="true" fc="ST" name="q" bType="Quality"/>
<DA fc="ST" name="t" bType="Timestamp"/>
</DOType>
<DOType cdc="SPS" id="SPS_5" desc="Single point status">
<DA dchg="true" fc="ST" name="stVal" bType="BOOLEAN"/>
<DA qchg="true" fc="ST" name="q" bType="Quality"/>
void main()
{
// Create Client
IEC61850 myClient;
IEC61850_Parameters tClientParam;
int error;
tClientParam.ClientServerFlag = IEC61850_CLIENT;
tClientParam.ptReadCallback = NULL;
tClientParam.ptWriteCallback = NULL;
tClientParam.ptUpdateCallback = UpdateFunction;
// Do something else
// ...
// Read in a value
IEC61850_ObjectData Value;
IEC61850_ObjectID Object;
Unsigned32 u32Counter;
// Load Data
Value.ucType = IEC61850_DATATYPE_INT32;
Value.uiBitLength = sizeof(u32Counter)*8;
Value.pvData = &u32Counter;
// Load Object ID
Object.uiNumber = 43;
error = IEC61850_Read(myClient, &Object, &Value);
if(error != IEC61850_ERROR_NONE)
{
printf("error has occured: %i",error);
}
else
{
printf("Count = %u",u32Counter);
}
// Do something else
// ...
// End of program
IEC61850_Free(myClient);
}
// Update Function