1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

fixed some byte ordering issues with OPAL

replaced custom htonf/ntohf() functions by existing msg_swap()

git-svn-id: https://zerberus.eonerc.rwth-aachen.de:8443/svn/s2ss/trunk@179 8ec27952-4edc-4aab-86aa-e87bb2611832
This commit is contained in:
Steffen Vogel 2014-08-31 15:25:59 +00:00
parent fd550e49c2
commit b171dfa3e0
9 changed files with 75 additions and 54 deletions

View file

@ -11,4 +11,6 @@
#define PROGNAME "S2SS"
#define VERSION "0.1"
#define MAX_VALUES 16
#endif /* _CONFIG_H_ */

View file

@ -0,0 +1,15 @@
/** Message related functions.
*
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014, Institute for Automation of Complex Power Systems, EONERC
*/
#ifndef _MSG_H_
#define _MSG_H_
#include "msg_format.h"
void msg_swap(struct msg *m);
#endif /* _MSG_H_ */

View file

@ -15,8 +15,10 @@
#include <endian.h>
#endif
#include "config.h"
/** Maximum number of dword values in a message */
#define MSG_VALUES 16
#define MSG_VALUES MAX_VALUES
/** The current version number for the message format */
#define MSG_VERSION 0
@ -56,16 +58,17 @@ struct msg
unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */
unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */
unsigned endian : 1; /**< Specifies the byteorder of the message (see MSG_ENDIAN_*) */
unsigned : 1; /**< Reserved padding bits */
unsigned : 1; /**< Reserved padding bits */
/** Number of valid dword values in msg::data[] */
uint8_t length;
/** The sequence number gets incremented by one for consecutive messages */
uint16_t sequence;
/** The message payload */
union {
float f;
uint32_t i;
float f; /**< Floating point values (note msg::endian) */
uint32_t i; /**< Integer values (note msg::endian) */
} data[MSG_VALUES];
} __attribute__((packed));

View file

@ -40,11 +40,13 @@ INTERNAL_LIBRARY3=-lOpalAsyncApiCore
s2ss.mk=Ascii
include\config.h=Ascii
include\interface.h=Ascii
include\msg.h=Ascii
include\msg_format.h=Ascii
include\sched.h=Ascii
include\socket.h=Ascii
src\s2ss.c=Ascii
src\interface.c=Ascii
src\msg.c=Ascii
src\sched.c=Ascii
src\socket.c=Ascii
[ExtraPutFilesComp_1_RT_LAB]

View file

@ -0,0 +1,22 @@
/** Message related functions.
*
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014, Institute for Automation of Complex Power Systems, EONERC
*/
#include <byteswap.h>
#include "msg.h"
void msg_swap(struct msg *m)
{
uint32_t *data = (uint32_t *) m->data;
/* Swap data */
for (int i = 0; i < m->length; i++)
data[i] = bswap_32(data[i]);
m->endian ^= 1;
}

View file

@ -39,7 +39,7 @@
/* This is the message format */
#include "config.h"
#include "msg_format.h"
#include "msg.h"
#include "socket.h"
#include "interface.h"
@ -51,10 +51,11 @@
static void *SendToIPPort(void *arg)
{
unsigned SendID = 1;
unsigned i, n;
unsigned int SendID = 1;
unsigned int ModelState;
unsigned int i, n;
unsigned short seq = 0;
int nbSend = 0;
unsigned ModelState;
/* Data from OPAL-RT model */
double mdldata[MSG_VALUES];
@ -97,13 +98,13 @@ static void *SendToIPPort(void *arg)
/******* FORMAT TO SPECIFIC PROTOCOL HERE *****************************/
// msg.dev_id = SendID; /* Use the SendID as a device ID here */
msg.sequence++;
msg.sequence = htons(seq++);
msg.length = mdldata_size / sizeof(double);
for (i = 0; i < msg.length; i++)
msg.data[i] = htonf((float) mdldata[i]);
msg.data[i] = (float) mdldata[i].f;
msg_size = 4 * (msg.length + 1);
msg_size = MSG_LEN(msg.length);
/**********************************************************************/
/* Perform the actual write to the ip port */
@ -159,6 +160,8 @@ static void *RecvFromIPPort(void *arg)
msg_size = sizeof(msg);
n = RecvPacket((char *) &msg, msg_size, 1.0);
/** @todo: Check and ntohs() sequence number! */
if (msg.version != MSG_VERSION) {
OpalPrint("%s: Received message with unknown version. Skipping..\n", PROGNAME);
continue;
@ -169,7 +172,7 @@ static void *RecvFromIPPort(void *arg)
continue;
}
msg_size = 4 * (msg.length + 1);
msg_size = MSG_LEN(msg.length);
/***********************************************************************/
if (n < 1) {
@ -208,8 +211,11 @@ static void *RecvFromIPPort(void *arg)
PROGNAME, RecvID, mdldata_size / sizeof(double), msg.length);
}
if (msg.endian != MSG_ENDIAN_HOST)
msg_swap(&msg);
for (i = 0; i < msg.length; i++)
mdldata[i] = (double) ntohf(msg.data[i]);
mdldata[i] = (double) msg.data[i].f;
/************************************************************************/
OpalSetAsyncRecvIconData(mdldata, mdldata_size, RecvID);

View file

@ -1,24 +0,0 @@
#include "utils.h"
static union fi {
float f;
uint32_t i;
};
inline float ntohf(float flt)
{
union fi u = { .f = flt };
u.i = ntohl(u.i);
return u.f;
}
inline float htonf(float flt)
{
union u = { .f = flt };
u.i = htonl(u.i);
return u.f;
}

View file

@ -38,7 +38,7 @@
#endif
/** The total length of a message */
#define MSG_LEN(values) (4 * (values + 1))
#define MSG_LEN(values) (4 * (values + 1))
/** Initialize a message */
#define MSG_INIT(i) { \
@ -55,17 +55,11 @@
**/
struct msg
{
#if BYTE_ORDER == BIG_ENDIAN
unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */
unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */
unsigned endian : 1; /**< Specifies the byteorder of the message (see MSG_ENDIAN_*) */
unsigned : 1; /**< Reserved padding bits */
#else
unsigned : 1; /**< Reserved padding bits */
unsigned endian : 1; /**< Specifies the byteorder of the message (see MSG_ENDIAN_*) */
unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */
unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */
#endif
unsigned : 1; /**< Reserved padding bits */
/** Number of valid dword values in msg::data[] */
uint8_t length;
/** The sequence number gets incremented by one for consecutive messages */
@ -73,8 +67,8 @@ struct msg
/** The message payload */
union {
float f;
uint32_t i;
float f; /**< Floating point values (note msg::endian) */
uint32_t i; /**< Integer values (note msg::endian) */
} data[MSG_VALUES];
} __attribute__((packed));

View file

@ -18,8 +18,6 @@ void msg_swap(struct msg *m)
{
uint32_t *data = (uint32_t *) m->data;
/* Swap sequence number */
m->sequence = bswap_16(m->sequence);
/* Swap data */
for (int i = 0; i < m->length; i++)
@ -58,19 +56,19 @@ int msg_fscan(FILE *f, struct msg *m)
void msg_random(struct msg *m)
{
assert(m->endian == MSG_ENDIAN_HOST);
for (int i = 0; i < m->length; i++)
m->data[i].f += (float) random() / RAND_MAX - .5;
m->endian = MSG_ENDIAN_HOST;
m->sequence++;
}
int msg_send(struct msg *m, struct node *n)
{
/* We dont care about the endianess of outgoing messages */
/* Convert headers to network byte order */
m->sequence = ntohs(m->sequence);
if (sendto(n->sd, m, (m->length+1) * 4, 0,
if (sendto(n->sd, m, MSG_LEN(m->length), 0,
(struct sockaddr *) &n->remote,
sizeof(struct sockaddr_in)) < 0)
perror("Failed sendto");
@ -88,6 +86,9 @@ int msg_recv(struct msg *m, struct node *n)
if (recv(n->sd, m, sizeof(struct msg), 0) < 0)
perror("Failed recv");
/* Convert headers to host byte order */
m->sequence = htons(m->sequence);
/* Convert message to host endianess */
if (m->endian != MSG_ENDIAN_HOST)
msg_swap(m);