mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
rtds: added new RTDS module
This commit is contained in:
parent
3206f918c1
commit
d27a148721
7 changed files with 194 additions and 100 deletions
|
@ -33,7 +33,7 @@
|
|||
|
||||
#include "node.h"
|
||||
#include "list.h"
|
||||
#include "rscad.h"
|
||||
#include "rtds/rscad.h"
|
||||
|
||||
struct gtwif {
|
||||
struct sockaddr_in remote; /**< The IP / port address of the RTDS racks. */
|
||||
|
|
50
include/villas/rtds/gtwif.h
Normal file
50
include/villas/rtds/gtwif.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/** Parsers for RSCAD file formats
|
||||
*
|
||||
* @file
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
* @license GNU General Public License (version 3)
|
||||
*
|
||||
* VILLASnode
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define GTWIF_CMD_MODIFY 0x004D
|
||||
#define GTWIF_CMD_EXAMINE 0x0058
|
||||
#define GTWIF_CMD_READLIST2 0x0143
|
||||
#define GTWIF_CMD_PING 0x0136
|
||||
|
||||
/** Send command CMD_READLIST2 to a GTWIF card.
|
||||
*
|
||||
* This command reads a list of signals from the GTWIF card.
|
||||
*/
|
||||
int gtwif_cmd_readlist2(int sd, uint32_t cnt, uint32_t addrs[], uint32_t vals[]);
|
||||
|
||||
/** Send command CMD_EXAMINE to a GTWIF card.
|
||||
*
|
||||
* This command modifies a memory location in the GTWIF memory.
|
||||
*/
|
||||
int gtwif_cmd_examine(int sd, uint32_t addr, uint32_t *val);
|
||||
|
||||
int gtwif_cmd_modify(int sd, uint32_t addr, uint32_t val);
|
||||
|
||||
int gtwif_cmd_modify_many(int sd, uint32_t cnt, uint32_t addrs[], uint32_t vals[], uint32_t old_vals[]);
|
||||
|
||||
int gtwif_cmd_ping(int sd, char *name, size_t namelen, char *casename, size_t casenamelen);
|
|
@ -27,105 +27,10 @@
|
|||
#include "plugin.h"
|
||||
#include "timing.h"
|
||||
#include "nodes/gtwif.h"
|
||||
|
||||
#define GTWIF_CMD_MODIFY 0x004D
|
||||
#define GTWIF_CMD_READLIST2 0x0143
|
||||
#include "rtds/gtwif.h"
|
||||
|
||||
#define GTWIF_MAX_RATE 10.0
|
||||
|
||||
static int gtwif_cmd_readlist2(int sd, uint32_t cnt, uint32_t addrs[], uint32_t vals[])
|
||||
{
|
||||
ssize_t sent, recvd;
|
||||
|
||||
uint32_t buf[cnt + 4];
|
||||
|
||||
int retries = 3;
|
||||
|
||||
buf[0] = htons(GTWIF_CMD_READLIST2);
|
||||
buf[1] = 0;
|
||||
buf[2] = 0;
|
||||
buf[3] = cnt;
|
||||
|
||||
for (int i = 0; i < cnt; i++)
|
||||
buf[i+3] = addrs[i];
|
||||
|
||||
retry: sent = send(sd, buf, sizeof(buf), 0);
|
||||
if (sent < 0)
|
||||
return -1;
|
||||
|
||||
recvd = recv(sd, buf, sizeof(buf), 0);
|
||||
if (recvd < 0) {
|
||||
if (errno == ETIMEDOUT && retries > 0) {
|
||||
retries--;
|
||||
goto retry;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buf[0] != htons(GTWIF_CMD_READLIST2))
|
||||
return -1;
|
||||
|
||||
/* We update the number of values with the returned number of values */
|
||||
cnt = buf[1];
|
||||
|
||||
for (int i = 0; i < cnt; i++)
|
||||
vals[i] = buf[i+3];
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static int gtwif_cmd_modify(int sd, uint32_t addr, uint32_t val)
|
||||
{
|
||||
ssize_t sent, recvd;
|
||||
uint32_t buf[4];
|
||||
int retries = 3;
|
||||
|
||||
buf[0] = htons(GTWIF_CMD_MODIFY);
|
||||
buf[1] = htonl(addr);
|
||||
buf[2] = htonl(1);
|
||||
buf[3] = htonl(val);
|
||||
|
||||
retry: sent = send(sd, buf, sizeof(buf), 0);
|
||||
if (sent < 0)
|
||||
return -1;
|
||||
|
||||
recvd = recv(sd, buf, sizeof(buf), 0);
|
||||
if (recvd < 0) {
|
||||
if (errno == ETIMEDOUT && retries > 0) {
|
||||
retries--;
|
||||
goto retry;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Sends multiple CMD_MODIFY commands to the GTWIF card.
|
||||
*
|
||||
* We we only modify values which have been changed.
|
||||
* This is checked by comparing \p vals[] with \p old_vals[]
|
||||
*/
|
||||
static int gtwif_cmd_modify_many(int sd, uint32_t cnt, uint32_t addrs[], uint32_t vals[], uint32_t old_vals[])
|
||||
{
|
||||
int ret, mod = 0;
|
||||
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
if (old_vals && vals[i] == old_vals[i])
|
||||
continue;
|
||||
|
||||
ret = gtwif_cmd_modify(sd, addrs[i], vals[i]);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
mod++;
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
static int gtwif_parse_direction(struct gtwif_direction *d, config_setting_t *cfg)
|
||||
{
|
||||
if (config_setting_type(cfg) != CONFIG_TYPE_ARRAY)
|
||||
|
|
133
lib/rtds/gtwif.c
Normal file
133
lib/rtds/gtwif.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/** Node type: GTWIF - RSCAD protocol for RTDS
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
* @license GNU General Public License (version 3)
|
||||
*
|
||||
* VILLASnode
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "rtds/gtwif.h"
|
||||
|
||||
int gtwif_cmd_readlist2(int sd, uint32_t cnt, uint32_t addrs[], uint32_t vals[])
|
||||
{
|
||||
ssize_t sent, recvd;
|
||||
|
||||
uint32_t buf[cnt + 4];
|
||||
|
||||
int retries = 3;
|
||||
|
||||
buf[0] = htons(GTWIF_CMD_READLIST2);
|
||||
buf[1] = 0;
|
||||
buf[2] = 0;
|
||||
buf[3] = cnt;
|
||||
|
||||
for (int i = 0; i < cnt; i++)
|
||||
buf[i+3] = addrs[i];
|
||||
|
||||
retry: sent = send(sd, buf, sizeof(buf), 0);
|
||||
if (sent < 0)
|
||||
return -1;
|
||||
|
||||
recvd = recv(sd, buf, sizeof(buf), 0);
|
||||
if (recvd < 0) {
|
||||
if (errno == ETIMEDOUT && retries > 0) {
|
||||
retries--;
|
||||
goto retry;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buf[0] != htons(GTWIF_CMD_READLIST2))
|
||||
return -1;
|
||||
|
||||
/* We update the number of values with the returned number of values */
|
||||
cnt = buf[1];
|
||||
|
||||
for (int i = 0; i < cnt; i++)
|
||||
vals[i] = buf[i+3];
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int gtwif_cmd_modify(int sd, uint32_t addr, uint32_t val)
|
||||
{
|
||||
ssize_t sent, recvd;
|
||||
uint32_t buf[4];
|
||||
int retries = 3;
|
||||
|
||||
buf[0] = htons(GTWIF_CMD_MODIFY);
|
||||
buf[1] = htonl(addr);
|
||||
buf[2] = htonl(1);
|
||||
buf[3] = htonl(val);
|
||||
|
||||
retry: sent = send(sd, buf, sizeof(buf), 0);
|
||||
if (sent < 0)
|
||||
return -1;
|
||||
|
||||
recvd = recv(sd, buf, sizeof(buf), 0);
|
||||
if (recvd < 0) {
|
||||
if (errno == ETIMEDOUT && retries > 0) {
|
||||
retries--;
|
||||
goto retry;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Sends multiple CMD_MODIFY commands to the GTWIF card.
|
||||
*
|
||||
* We we only modify values which have been changed.
|
||||
* This is checked by comparing \p vals[] with \p old_vals[]
|
||||
*/
|
||||
int gtwif_cmd_modify_many(int sd, uint32_t cnt, uint32_t addrs[], uint32_t vals[], uint32_t old_vals[])
|
||||
{
|
||||
int ret, mod = 0;
|
||||
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
if (old_vals && vals[i] == old_vals[i])
|
||||
continue;
|
||||
|
||||
ret = gtwif_cmd_modify(sd, addrs[i], vals[i]);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
mod++;
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
int gtwif_cmd_ping(int sd, char *name, size_t namelen, char *casename, size_t casenamelen)
|
||||
{
|
||||
/**< @todo Implement */
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int gtwif_cmd_examine(int sd, uint32_t addr, uint32_t *val)
|
||||
{
|
||||
/**< @todo Implement */
|
||||
|
||||
return -1;
|
||||
}
|
|
@ -24,7 +24,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "rscad.h"
|
||||
#include "rtds/rscad.h"
|
||||
|
||||
static int rscad_inf_destroy_attribute(struct rscad_inf_attribute *a)
|
||||
{
|
|
@ -22,11 +22,17 @@
|
|||
|
||||
#include <criterion/criterion.h>
|
||||
|
||||
#include "rscad.h"
|
||||
#include "rtds/rscad.h"
|
||||
#include "rtds/gtwif.h"
|
||||
|
||||
#define PATH_INF "tests/data/rscad/vdiv.inf"
|
||||
|
||||
Test(rscad, inf)
|
||||
Test(rtds, gtwif)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Test(rtds, rscad_inf)
|
||||
{
|
||||
int ret;
|
||||
struct rscad_inf i;
|
Loading…
Add table
Reference in a new issue