The goal of this software is to automatically generate C/C++ code which reads and writes GOOSE and Sampled Value packets. Any valid IEC 61850 Substation Configuration Description (SCD) file, describing GOOSE and/or SV communications, can be used as the input. The output code is lightweight and platform-independent, so it can run on a variety of devices, including low-cost microcontrollers. It\'s ideal for rapid-prototyping new protection and control systems that require communications. This mbed project is a simple example of this functionality. Other code: https://github.com/stevenblair/rapid61850 Project homepage: http://personal.strath.ac.uk/steven.m.blair/

Committer:
sblair
Date:
Fri Oct 07 13:48:18 2011 +0000
Revision:
1:9399d44c2b1a
Parent:
0:230c10b228ea

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sblair 1:9399d44c2b1a 1 /**
sblair 1:9399d44c2b1a 2 * Rapid-prototyping protection schemes with IEC 61850
sblair 1:9399d44c2b1a 3 *
sblair 1:9399d44c2b1a 4 * Copyright (c) 2011 Steven Blair
sblair 1:9399d44c2b1a 5 *
sblair 1:9399d44c2b1a 6 * This program is free software; you can redistribute it and/or
sblair 1:9399d44c2b1a 7 * modify it under the terms of the GNU General Public License
sblair 1:9399d44c2b1a 8 * as published by the Free Software Foundation; either version 2
sblair 1:9399d44c2b1a 9 * of the License, or (at your option) any later version.
sblair 1:9399d44c2b1a 10
sblair 1:9399d44c2b1a 11 * This program is distributed in the hope that it will be useful,
sblair 1:9399d44c2b1a 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
sblair 1:9399d44c2b1a 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
sblair 1:9399d44c2b1a 14 * GNU General Public License for more details.
sblair 1:9399d44c2b1a 15
sblair 1:9399d44c2b1a 16 * You should have received a copy of the GNU General Public License
sblair 1:9399d44c2b1a 17 * along with this program; if not, write to the Free Software
sblair 1:9399d44c2b1a 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
sblair 1:9399d44c2b1a 19 */
sblair 1:9399d44c2b1a 20
sblair 1:9399d44c2b1a 21 #include "svEncodeBasic.h"
sblair 1:9399d44c2b1a 22 #include "ied.h"
sblair 0:230c10b228ea 23 #include "svEncode.h"
sblair 0:230c10b228ea 24
sblair 0:230c10b228ea 25
sblair 0:230c10b228ea 26
sblair 1:9399d44c2b1a 27 int encode_myAnalogValue(unsigned char *buf, struct myAnalogValue *myAnalogValue) {
sblair 1:9399d44c2b1a 28 int offset = 0;
sblair 1:9399d44c2b1a 29
sblair 1:9399d44c2b1a 30 offset += ENCODE_CTYPE_FLOAT32(&buf[offset], &myAnalogValue->f);
sblair 1:9399d44c2b1a 31
sblair 1:9399d44c2b1a 32 return offset;
sblair 0:230c10b228ea 33 }
sblair 1:9399d44c2b1a 34 int encode_ScaledValueConfig(unsigned char *buf, struct ScaledValueConfig *ScaledValueConfig) {
sblair 1:9399d44c2b1a 35 int offset = 0;
sblair 1:9399d44c2b1a 36
sblair 1:9399d44c2b1a 37 offset += ENCODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->scaleFactor);
sblair 1:9399d44c2b1a 38 offset += ENCODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->offset);
sblair 1:9399d44c2b1a 39
sblair 1:9399d44c2b1a 40 return offset;
sblair 0:230c10b228ea 41 }
sblair 1:9399d44c2b1a 42 int encode_myVector(unsigned char *buf, struct myVector *myVector) {
sblair 1:9399d44c2b1a 43 int offset = 0;
sblair 1:9399d44c2b1a 44
sblair 1:9399d44c2b1a 45 offset += encode_myAnalogValue(&buf[offset], &myVector->mag);
sblair 1:9399d44c2b1a 46 offset += encode_myAnalogValue(&buf[offset], &myVector->ang);
sblair 1:9399d44c2b1a 47
sblair 1:9399d44c2b1a 48 return offset;
sblair 0:230c10b228ea 49 }
sblair 1:9399d44c2b1a 50 int encode_simpleVector(unsigned char *buf, struct simpleVector *simpleVector) {
sblair 1:9399d44c2b1a 51 int offset = 0;
sblair 1:9399d44c2b1a 52
sblair 1:9399d44c2b1a 53 offset += encode_myAnalogValue(&buf[offset], &simpleVector->mag);
sblair 1:9399d44c2b1a 54 offset += encode_myAnalogValue(&buf[offset], &simpleVector->ang);
sblair 1:9399d44c2b1a 55
sblair 1:9399d44c2b1a 56 return offset;
sblair 0:230c10b228ea 57 }
sblair 1:9399d44c2b1a 58 int encode_myMod(unsigned char *buf, struct myMod *myMod) {
sblair 1:9399d44c2b1a 59 int offset = 0;
sblair 1:9399d44c2b1a 60
sblair 1:9399d44c2b1a 61 offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->ctlVal);
sblair 1:9399d44c2b1a 62 offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->stVal);
sblair 1:9399d44c2b1a 63 offset += ENCODE_CTYPE_QUALITY(&buf[offset], &myMod->q);
sblair 1:9399d44c2b1a 64 offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myMod->t);
sblair 1:9399d44c2b1a 65
sblair 1:9399d44c2b1a 66 return offset;
sblair 0:230c10b228ea 67 }
sblair 1:9399d44c2b1a 68 int encode_myHealth(unsigned char *buf, struct myHealth *myHealth) {
sblair 1:9399d44c2b1a 69 int offset = 0;
sblair 1:9399d44c2b1a 70
sblair 1:9399d44c2b1a 71 offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myHealth->stVal);
sblair 1:9399d44c2b1a 72
sblair 1:9399d44c2b1a 73 return offset;
sblair 0:230c10b228ea 74 }
sblair 1:9399d44c2b1a 75 int encode_myBeh(unsigned char *buf, struct myBeh *myBeh) {
sblair 1:9399d44c2b1a 76 int offset = 0;
sblair 1:9399d44c2b1a 77
sblair 1:9399d44c2b1a 78 offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myBeh->stVal);
sblair 1:9399d44c2b1a 79
sblair 1:9399d44c2b1a 80 return offset;
sblair 0:230c10b228ea 81 }
sblair 1:9399d44c2b1a 82 int encode_myINS(unsigned char *buf, struct myINS *myINS) {
sblair 1:9399d44c2b1a 83 int offset = 0;
sblair 1:9399d44c2b1a 84
sblair 1:9399d44c2b1a 85 offset += ENCODE_CTYPE_INT32(&buf[offset], &myINS->stVal);
sblair 1:9399d44c2b1a 86
sblair 1:9399d44c2b1a 87 return offset;
sblair 0:230c10b228ea 88 }
sblair 1:9399d44c2b1a 89 int encode_myLPL(unsigned char *buf, struct myLPL *myLPL) {
sblair 1:9399d44c2b1a 90 int offset = 0;
sblair 1:9399d44c2b1a 91
sblair 1:9399d44c2b1a 92 offset += ENCODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->ldNs);
sblair 1:9399d44c2b1a 93 offset += ENCODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->configRev);
sblair 1:9399d44c2b1a 94
sblair 1:9399d44c2b1a 95 return offset;
sblair 0:230c10b228ea 96 }
sblair 1:9399d44c2b1a 97 int encode_myDPL(unsigned char *buf, struct myDPL *myDPL) {
sblair 1:9399d44c2b1a 98 int offset = 0;
sblair 1:9399d44c2b1a 99
sblair 1:9399d44c2b1a 100 offset += ENCODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->vendor);
sblair 1:9399d44c2b1a 101 offset += ENCODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->hwRev);
sblair 1:9399d44c2b1a 102
sblair 1:9399d44c2b1a 103 return offset;
sblair 0:230c10b228ea 104 }
sblair 1:9399d44c2b1a 105 int encode_myPos(unsigned char *buf, struct myPos *myPos) {
sblair 1:9399d44c2b1a 106 int offset = 0;
sblair 1:9399d44c2b1a 107
sblair 1:9399d44c2b1a 108 offset += ENCODE_CTYPE_DBPOS(&buf[offset], &myPos->stVal);
sblair 1:9399d44c2b1a 109 offset += ENCODE_CTYPE_QUALITY(&buf[offset], &myPos->q);
sblair 1:9399d44c2b1a 110 offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myPos->t);
sblair 1:9399d44c2b1a 111 offset += ENCODE_CTYPE_BOOLEAN(&buf[offset], &myPos->ctlVal);
sblair 1:9399d44c2b1a 112
sblair 1:9399d44c2b1a 113 return offset;
sblair 0:230c10b228ea 114 }
sblair 1:9399d44c2b1a 115 int encode_mySPS(unsigned char *buf, struct mySPS *mySPS) {
sblair 1:9399d44c2b1a 116 int offset = 0;
sblair 1:9399d44c2b1a 117
sblair 1:9399d44c2b1a 118 offset += ENCODE_CTYPE_INT32(&buf[offset], &mySPS->stVal);
sblair 1:9399d44c2b1a 119 offset += ENCODE_CTYPE_QUALITY(&buf[offset], &mySPS->q);
sblair 1:9399d44c2b1a 120 offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &mySPS->t);
sblair 1:9399d44c2b1a 121
sblair 1:9399d44c2b1a 122 return offset;
sblair 0:230c10b228ea 123 }
sblair 1:9399d44c2b1a 124 int encode_myMV(unsigned char *buf, struct myMV *myMV) {
sblair 1:9399d44c2b1a 125 int offset = 0;
sblair 1:9399d44c2b1a 126
sblair 1:9399d44c2b1a 127 offset += encode_myAnalogValue(&buf[offset], &myMV->mag);
sblair 1:9399d44c2b1a 128 offset += ENCODE_CTYPE_QUALITY(&buf[offset], &myMV->q);
sblair 1:9399d44c2b1a 129 offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myMV->t);
sblair 1:9399d44c2b1a 130 offset += encode_ScaledValueConfig(&buf[offset], &myMV->sVC);
sblair 1:9399d44c2b1a 131
sblair 1:9399d44c2b1a 132 return offset;
sblair 0:230c10b228ea 133 }
sblair 1:9399d44c2b1a 134 int encode_simpleMV(unsigned char *buf, struct simpleMV *simpleMV) {
sblair 1:9399d44c2b1a 135 int offset = 0;
sblair 1:9399d44c2b1a 136
sblair 1:9399d44c2b1a 137 offset += ENCODE_CTYPE_FLOAT32(&buf[offset], &simpleMV->mag);
sblair 1:9399d44c2b1a 138 offset += ENCODE_CTYPE_QUALITY(&buf[offset], &simpleMV->q);
sblair 1:9399d44c2b1a 139 offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &simpleMV->t);
sblair 1:9399d44c2b1a 140 offset += encode_ScaledValueConfig(&buf[offset], &simpleMV->sVC);
sblair 1:9399d44c2b1a 141
sblair 1:9399d44c2b1a 142 return offset;
sblair 0:230c10b228ea 143 }
sblair 1:9399d44c2b1a 144 int encode_simpleCMV(unsigned char *buf, struct simpleCMV *simpleCMV) {
sblair 1:9399d44c2b1a 145 int offset = 0;
sblair 1:9399d44c2b1a 146
sblair 1:9399d44c2b1a 147 offset += encode_simpleVector(&buf[offset], &simpleCMV->cVal);
sblair 1:9399d44c2b1a 148 offset += ENCODE_CTYPE_QUALITY(&buf[offset], &simpleCMV->q);
sblair 1:9399d44c2b1a 149 offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &simpleCMV->t);
sblair 1:9399d44c2b1a 150
sblair 1:9399d44c2b1a 151 return offset;
sblair 0:230c10b228ea 152 }
sblair 1:9399d44c2b1a 153 int encode_simpleWYE(unsigned char *buf, struct simpleWYE *simpleWYE) {
sblair 1:9399d44c2b1a 154 int offset = 0;
sblair 1:9399d44c2b1a 155
sblair 1:9399d44c2b1a 156 offset += encode_simpleCMV(&buf[offset], &simpleWYE->phsA);
sblair 1:9399d44c2b1a 157 offset += encode_simpleCMV(&buf[offset], &simpleWYE->phsB);
sblair 1:9399d44c2b1a 158 offset += encode_simpleCMV(&buf[offset], &simpleWYE->phsC);
sblair 1:9399d44c2b1a 159
sblair 1:9399d44c2b1a 160 return offset;
sblair 0:230c10b228ea 161 }
sblair 1:9399d44c2b1a 162 int encode_myCMV(unsigned char *buf, struct myCMV *myCMV) {
sblair 1:9399d44c2b1a 163 int offset = 0;
sblair 1:9399d44c2b1a 164
sblair 1:9399d44c2b1a 165 offset += encode_myVector(&buf[offset], &myCMV->cVal);
sblair 1:9399d44c2b1a 166 offset += ENCODE_CTYPE_QUALITY(&buf[offset], &myCMV->q);
sblair 1:9399d44c2b1a 167 offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myCMV->t);
sblair 1:9399d44c2b1a 168
sblair 1:9399d44c2b1a 169 return offset;
sblair 0:230c10b228ea 170 }
sblair 1:9399d44c2b1a 171 int encode_mySEQ(unsigned char *buf, struct mySEQ *mySEQ) {
sblair 1:9399d44c2b1a 172 int offset = 0;
sblair 1:9399d44c2b1a 173
sblair 1:9399d44c2b1a 174 offset += encode_myCMV(&buf[offset], &mySEQ->c1);
sblair 1:9399d44c2b1a 175 offset += encode_myCMV(&buf[offset], &mySEQ->c2);
sblair 1:9399d44c2b1a 176 offset += encode_myCMV(&buf[offset], &mySEQ->c3);
sblair 1:9399d44c2b1a 177 offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &mySEQ->seqT);
sblair 1:9399d44c2b1a 178
sblair 1:9399d44c2b1a 179 return offset;
sblair 0:230c10b228ea 180 }
sblair 1:9399d44c2b1a 181 int encode_mySAV(unsigned char *buf, struct mySAV *mySAV) {
sblair 1:9399d44c2b1a 182 int offset = 0;
sblair 1:9399d44c2b1a 183
sblair 1:9399d44c2b1a 184 offset += encode_myAnalogValue(&buf[offset], &mySAV->instMag);
sblair 1:9399d44c2b1a 185 offset += ENCODE_CTYPE_QUALITY(&buf[offset], &mySAV->q);
sblair 1:9399d44c2b1a 186
sblair 1:9399d44c2b1a 187 return offset;
sblair 0:230c10b228ea 188 }
sblair 1:9399d44c2b1a 189 int encode_simpleSAV(unsigned char *buf, struct simpleSAV *simpleSAV) {
sblair 1:9399d44c2b1a 190 int offset = 0;
sblair 1:9399d44c2b1a 191
sblair 1:9399d44c2b1a 192 offset += encode_myAnalogValue(&buf[offset], &simpleSAV->instMag);
sblair 1:9399d44c2b1a 193 offset += ENCODE_CTYPE_QUALITY(&buf[offset], &simpleSAV->q);
sblair 1:9399d44c2b1a 194
sblair 1:9399d44c2b1a 195 return offset;
sblair 0:230c10b228ea 196 }
sblair 1:9399d44c2b1a 197 int encode_11(unsigned char *buf) {
sblair 1:9399d44c2b1a 198 int offset = 0;
sblair 1:9399d44c2b1a 199
sblair 1:9399d44c2b1a 200 offset += encode_myAnalogValue(&buf[offset], &E1Q1SB1.S1.C1.TVTR_1.Vol.instMag);
sblair 1:9399d44c2b1a 201 offset += encode_myMod(&buf[offset], &E1Q1SB1.S1.C1.CSWI_1.Mod);
sblair 1:9399d44c2b1a 202 offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &E1Q1SB1.S1.C1.MMXU_1.Mod.stVal);
sblair 1:9399d44c2b1a 203 offset += ENCODE_CTYPE_QUALITY(&buf[offset], &E1Q1SB1.S1.C1.MMXU_1.Volts.q);
sblair 1:9399d44c2b1a 204 offset += encode_myMV(&buf[offset], &E1Q1SB1.S1.C1.MMXU_1.Amps);
sblair 1:9399d44c2b1a 205 offset += encode_myPos(&buf[offset], &E1Q1SB1.S1.C1.CSWI_2.Pos);
sblair 1:9399d44c2b1a 206
sblair 1:9399d44c2b1a 207 return offset;
sblair 0:230c10b228ea 208 }
sblair 1:9399d44c2b1a 209 int encode_rmxu(unsigned char *buf) {
sblair 1:9399d44c2b1a 210 int offset = 0;
sblair 1:9399d44c2b1a 211
sblair 1:9399d44c2b1a 212 offset += encode_simpleSAV(&buf[offset], &E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsA);
sblair 1:9399d44c2b1a 213 offset += encode_simpleSAV(&buf[offset], &E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsB);
sblair 1:9399d44c2b1a 214 offset += encode_simpleSAV(&buf[offset], &E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsC);
sblair 1:9399d44c2b1a 215
sblair 1:9399d44c2b1a 216 return offset;
sblair 0:230c10b228ea 217 }
sblair 0:230c10b228ea 218
sblair 0:230c10b228ea 219