mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
several smaller fixes and documentation updates
This commit is contained in:
parent
4ca0785095
commit
2757011e1b
26 changed files with 156 additions and 79 deletions
|
@ -7,7 +7,9 @@
|
|||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
/** @addtogroup fpga VILLASfpga @{ */
|
||||
/** @addtogroup fpga VILLASfpga
|
||||
* @{
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
/** @addtogroup fpga VILLASfpga @{ */
|
||||
/** @addtogroup fpga VILLASfpga
|
||||
* @{
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* @copyright 2017, Steffen Vogel
|
||||
**********************************************************************************/
|
||||
|
||||
/** @addtogroup fpga VILLASfpga @{ */
|
||||
/** @addtogroup fpga VILLASfpga
|
||||
* @{
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
* @copyright 2017, Steffen Vogel
|
||||
**********************************************************************************/
|
||||
|
||||
/** @addtogroup fpga VILLASfpga @{ */
|
||||
/** @addtogroup fpga VILLASfpga
|
||||
* @{
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
* @copyright 2017, Steffen Vogel
|
||||
**********************************************************************************/
|
||||
|
||||
/** @addtogroup fpga VILLASfpga @{ */
|
||||
/** @addtogroup fpga VILLASfpga
|
||||
* @{
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
* @copyright 2017, Steffen Vogel
|
||||
**********************************************************************************/
|
||||
|
||||
/** @addtogroup fpga VILLASfpga @{ */
|
||||
/** @addtogroup fpga VILLASfpga
|
||||
* @{
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* @copyright 2017, Steffen Vogel
|
||||
*********************************************************************************/
|
||||
|
||||
/** @addtogroup fpga VILLASfpga @{ */
|
||||
/** @addtogroup fpga VILLASfpga
|
||||
* @{
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* @copyright 2017, Steffen Vogel
|
||||
**********************************************************************************/
|
||||
|
||||
/** @addtogroup fpga VILLASfpga @{ */
|
||||
/** @addtogroup fpga VILLASfpga
|
||||
* @{
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
* @copyright 2017, Steffen Vogel
|
||||
**********************************************************************************/
|
||||
|
||||
/** @addtogroup fpga VILLASfpga @{ */
|
||||
/** @addtogroup fpga VILLASfpga
|
||||
* @{
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
* @copyright 2017, Steffen Vogel
|
||||
**********************************************************************************/
|
||||
|
||||
/** @addtogroup fpga VILLASfpga @{ */
|
||||
/** @addtogroup fpga VILLASfpga
|
||||
* @{
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
/** @addtogroup fpga VILLASfpga @{ */
|
||||
/** @addtogroup fpga VILLASILLASfpga
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _FPGA_VLNV_H_
|
||||
#define _FPGA_VLNV_H_
|
||||
|
|
|
@ -148,11 +148,12 @@ void * hook_storage(struct hook *h, int when, size_t len, ctor_cb_t ctor, dtor_c
|
|||
*/
|
||||
int hook_parse_list(struct list *list, config_setting_t *cfg);
|
||||
|
||||
/** Parse a single hook and append it to the list.
|
||||
/** Parse a single hook.
|
||||
*
|
||||
* A hook definition is composed of the hook name and optional parameters
|
||||
* seperated by a colon.
|
||||
*
|
||||
* Examples:
|
||||
* "print:stdout"
|
||||
*/
|
||||
int hook_parse(config_setting_t *cfg, struct list *list);
|
||||
int hook_parse(struct hook *h, config_setting_t *cfg);
|
|
@ -45,11 +45,19 @@ struct node
|
|||
config_setting_t *cfg; /**< A pointer to the libconfig object which instantiated this node */
|
||||
};
|
||||
|
||||
/** Destroy node by freeing dynamically allocated memory.
|
||||
int node_init(struct node *n, struct node_type *vt);
|
||||
|
||||
/** Parse a single node and add it to the global configuration.
|
||||
*
|
||||
* @see node_type::destroy
|
||||
* @param cfg A libconfig object pointing to the node.
|
||||
* @param nodes Add new nodes to this linked list.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int node_destroy(struct node *n);
|
||||
int node_parse(struct node *n, config_setting_t *cfg);
|
||||
|
||||
/** Validate node configuration. */
|
||||
int node_check(struct node *n);
|
||||
|
||||
/** Start operation of a node.
|
||||
*
|
||||
|
@ -63,6 +71,12 @@ int node_start(struct node *n);
|
|||
*/
|
||||
int node_stop(struct node *n);
|
||||
|
||||
/** Destroy node by freeing dynamically allocated memory.
|
||||
*
|
||||
* @see node_type::destroy
|
||||
*/
|
||||
int node_destroy(struct node *n);
|
||||
|
||||
/** Return a pointer to a string which should be used to print this node.
|
||||
*
|
||||
* @see node::_name‚
|
||||
|
@ -103,16 +117,4 @@ int node_write(struct node *n, struct sample *smps[], unsigned cnt);
|
|||
*/
|
||||
int node_parse_list(struct list *list, config_setting_t *cfg, struct list *all);
|
||||
|
||||
/** Parse a single node and add it to the global configuration.
|
||||
*
|
||||
* @param cfg A libconfig object pointing to the node.
|
||||
* @param nodes Add new nodes to this linked list.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int node_parse(struct node *n, config_setting_t *cfg);
|
||||
|
||||
/** Validate node configuration. */
|
||||
int node_check(struct node *n);
|
||||
|
||||
/** @} */
|
|
@ -25,7 +25,7 @@
|
|||
#include "list.h"
|
||||
#include "config.h"
|
||||
#include "msg.h"
|
||||
#include "cfg.h"
|
||||
#include "super_node.h"
|
||||
#include "node.h"
|
||||
|
||||
struct node;
|
||||
|
|
|
@ -33,19 +33,32 @@ struct pool {
|
|||
|
||||
#define INLINE static inline __attribute__((unused))
|
||||
|
||||
/** Initiazlize a pool */
|
||||
/** Initiazlize a pool
|
||||
*
|
||||
* @param[inout] p The pool data structure.
|
||||
* @param[in] cnt The total number of blocks which are reserverd by this pool.
|
||||
* @param[in] blocksz The size in bytes per block.
|
||||
* @param[in] mem The type of memory which should be used for this pool.
|
||||
* @retval 0 The pool has been successfully initialized.
|
||||
* @retval <>0 There was an error during the pool initialization.
|
||||
*/
|
||||
int pool_init(struct pool *p, size_t cnt, size_t blocksz, const struct memtype *mem);
|
||||
|
||||
/** Destroy and release memory used by pool. */
|
||||
int pool_destroy(struct pool *p);
|
||||
|
||||
/** Pop cnt values from the stack an place them in the array blocks */
|
||||
/** Pop up to \p cnt values from the stack an place them in the array \p blocks.
|
||||
*
|
||||
* @return The number of blocks actually retrieved from the pool.
|
||||
* This number can be smaller than the requested \p cnt blocks
|
||||
* in case the pool currently holds less than \p cnt blocks.
|
||||
*/
|
||||
INLINE ssize_t pool_get_many(struct pool *p, void *blocks[], size_t cnt)
|
||||
{
|
||||
return queue_pull_many(&p->queue, blocks, cnt);
|
||||
}
|
||||
|
||||
/** Push cnt values which are giving by the array values to the stack. */
|
||||
/** Push \p cnt values which are giving by the array values to the stack. */
|
||||
INLINE ssize_t pool_put_many(struct pool *p, void *blocks[], size_t cnt)
|
||||
{
|
||||
return queue_push_many(&p->queue, blocks, cnt);
|
||||
|
|
|
@ -86,6 +86,17 @@ int queue_push(struct queue *q, void *ptr);
|
|||
|
||||
int queue_pull(struct queue *q, void **ptr);
|
||||
|
||||
/** Enqueue up to \p cnt pointers of the \p ptr array into the queue.
|
||||
*
|
||||
* @return The number of pointers actually enqueued.
|
||||
* This number can be smaller then \p cnt in case the queue is filled.
|
||||
*/
|
||||
int queue_push_many(struct queue *q, void *ptr[], size_t cnt);
|
||||
|
||||
/** Dequeue up to \p cnt pointers from the queue and place them into the \p ptr array.
|
||||
*
|
||||
* @return The number of pointers actually dequeued.
|
||||
* This number can be smaller than \p cnt in case the queue contained less than
|
||||
* \p cnt elements.
|
||||
*/
|
||||
int queue_pull_many(struct queue *q, void *ptr[], size_t cnt);
|
|
@ -7,11 +7,12 @@
|
|||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#ifndef _WEBMSG_FORMAT_H_
|
||||
#define _WEBMSG_FORMAT_H_
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "msg_format.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#define _BSD_SOURCE 1
|
||||
#include <endian.h>
|
||||
|
@ -39,16 +40,16 @@
|
|||
#endif
|
||||
|
||||
/** The total size in bytes of a message */
|
||||
#define WEBMSG_LEN(values) (sizeof(struct msg) + MSG_DATA_LEN(values))
|
||||
#define WEBMSG_LEN(values) (sizeof(struct webmsg) + MSG_DATA_LEN(values))
|
||||
|
||||
/** The length of \p values values in bytes. */
|
||||
#define WEBMSG_DATA_LEN(values) (sizeof(float) * (values))
|
||||
|
||||
/** The offset to the first data value in a message. */
|
||||
#define WEBMSG_DATA_OFFSET(msg) ((char *) (msg) + offsetof(struct msg, data))
|
||||
#define WEBMSG_DATA_OFFSET(msg) ((char *) (msg) + offsetof(struct webmsg, data))
|
||||
|
||||
/** Initialize a message with default values */
|
||||
#define WEBMSG_INIT(len, seq) (struct msg) {\
|
||||
#define WEBMSG_INIT(len, seq) (struct webmsg) {\
|
||||
.version = WEBMSG_VERSION, \
|
||||
.type = WEBMSG_TYPE_DATA, \
|
||||
.endian = WEBMSG_ENDIAN_HOST, \
|
||||
|
@ -97,6 +98,4 @@ struct webmsg
|
|||
float f; /**< Floating point values (note msg::endian) */
|
||||
uint32_t i; /**< Integer values (note msg::endian) */
|
||||
} data[];
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif /* _WEBMSG_FORMAT_H_ */
|
||||
} __attribute__((packed));
|
|
@ -25,8 +25,7 @@ int fpga_card_init(struct fpga_card *c, struct pci *pci, struct vfio_container *
|
|||
|
||||
fpga_card_check(c);
|
||||
|
||||
if (c->state == STATE_INITIALIZED)
|
||||
return 0;
|
||||
assert(c->state != STATE_DESTROYED);
|
||||
|
||||
/* Search for FPGA card */
|
||||
pdev = pci_lookup_device(pci, &c->filter);
|
||||
|
|
41
lib/hook.c
41
lib/hook.c
|
@ -113,14 +113,21 @@ void * hook_storage(struct hook *h, int when, size_t len, ctor_cb_t ctor, dtor_c
|
|||
*/
|
||||
int hook_parse_list(struct list *list, config_setting_t *cfg)
|
||||
{
|
||||
struct hook h;
|
||||
|
||||
switch (config_setting_type(cfg)) {
|
||||
case CONFIG_TYPE_STRING:
|
||||
hook_parse(cfg, list);
|
||||
hook_parse(&h, cfg);
|
||||
list_push(list, memdup(&h, sizeof(h)));
|
||||
break;
|
||||
|
||||
case CONFIG_TYPE_ARRAY:
|
||||
for (int i = 0; i < config_setting_length(cfg); i++)
|
||||
hook_parse(config_setting_get_elem(cfg, i), list);
|
||||
for (int i = 0; i < config_setting_length(cfg); i++) {
|
||||
config_setting_t *cfg_hook = config_setting_get_elem(cfg, i);
|
||||
|
||||
hook_parse(&h, cfg_hook);
|
||||
list_push(list, memdup(&h, sizeof(h)));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -130,27 +137,35 @@ int hook_parse_list(struct list *list, config_setting_t *cfg)
|
|||
return list_length(list);
|
||||
}
|
||||
|
||||
int hook_parse(config_setting_t *cfg, struct list *list)
|
||||
int hook_parse(struct hook *h, config_setting_t *cfg)
|
||||
{
|
||||
struct hook *hook;
|
||||
struct plugin *plg;
|
||||
|
||||
int ret;
|
||||
const char *hookline;
|
||||
char *name, *param;
|
||||
const char *hookline = config_setting_get_string(cfg);
|
||||
struct plugin *p;
|
||||
|
||||
hookline = config_setting_get_string(cfg);
|
||||
if (!hookline)
|
||||
cerror(cfg, "Invalid hook function");
|
||||
|
||||
name = strtok((char *) hookline, ":");
|
||||
param = strtok(NULL, "");
|
||||
|
||||
plg = plugin_lookup(PLUGIN_TYPE_HOOK, name);
|
||||
if (!plg)
|
||||
p = plugin_lookup(PLUGIN_TYPE_HOOK, name);
|
||||
if (!p)
|
||||
cerror(cfg, "Unknown hook function '%s'", name);
|
||||
|
||||
hook = memdup(&plg->hook, sizeof(plg->hook));
|
||||
hook->parameter = param;
|
||||
if (p->hook.type & HOOK_AUTO)
|
||||
cerror(cfg, "Hook '%s' is built-in and can not be added manually.", name);
|
||||
|
||||
hook_copy(&p->hook, h);
|
||||
|
||||
h->parameter = param;
|
||||
|
||||
list_push(list, hook);
|
||||
/* Parse hook arguments */
|
||||
ret = h->cb(h, HOOK_PARSE, NULL);
|
||||
if (ret)
|
||||
cerror(cfg, "Failed to parse arguments for hook '%s'", name);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -35,7 +35,7 @@ static int hook_convert(struct hook *h, int when, struct hook_info *k)
|
|||
|
||||
case HOOK_READ:
|
||||
for (int i = 0; i < k->cnt; i++) {
|
||||
for (int j = 0; j < k->smps[0]->length; j++) {
|
||||
for (int j = 0; j < k->smps[i]->length; j++) {
|
||||
switch (private->mode) {
|
||||
case TO_FIXED: k->smps[i]->data[j].i = k->smps[i]->data[j].f * 1e3; break;
|
||||
case TO_FLOAT: k->smps[i]->data[j].f = k->smps[i]->data[j].i; break;
|
||||
|
@ -57,7 +57,7 @@ static struct plugin p = {
|
|||
.priority = 99,
|
||||
.history = 0,
|
||||
.cb = hook_convert,
|
||||
.type = HOOK_STORAGE | HOOK_DESTROY | HOOK_READ
|
||||
.type = HOOK_STORAGE | HOOK_READ
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -13,10 +13,15 @@
|
|||
#include "config.h"
|
||||
#include "plugin.h"
|
||||
|
||||
int node_init(struct node *n)
|
||||
int node_init(struct node *n, struct node_type *vt)
|
||||
{
|
||||
assert(n->state == STATE_DESTROYED);
|
||||
|
||||
n->_vt = vt;
|
||||
n->_vd = alloc(vt->size);
|
||||
|
||||
list_push(&vt->instances, n);
|
||||
|
||||
n->state = STATE_INITIALIZED;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -20,7 +20,7 @@ int node_type_start(struct node_type *vt, int argc, char *argv[], config_setting
|
|||
|
||||
assert(vt->state != STATE_STARTED);
|
||||
|
||||
info("Initializing " YEL("%s") " node type", plugin_name(vt));
|
||||
info("Initializing " YEL("%s") " node type which is used by %zu nodes", plugin_name(vt), list_length(&vt->instances));
|
||||
{ INDENT
|
||||
ret = vt->init ? vt->init(argc, argv, cfg) : 0;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "plugin.h"
|
||||
|
||||
/* Forward declartions */
|
||||
static struct node_type vt;
|
||||
static struct plugin p;
|
||||
|
||||
/* Private static storage */
|
||||
struct list interfaces;
|
||||
|
@ -45,7 +45,10 @@ int socket_init(int argc, char * argv[], config_setting_t *cfg)
|
|||
list_init(&interfaces);
|
||||
|
||||
/* Gather list of used network interfaces */
|
||||
list_foreach(struct node *n, &vt.instances) {
|
||||
list_foreach(struct node *n, &p.node.instances) {
|
||||
if (n->state != STATE_INITIALIZED)
|
||||
continue;
|
||||
|
||||
struct socket *s = n->_vd;
|
||||
struct rtnl_link *link;
|
||||
|
||||
|
@ -114,11 +117,12 @@ char * socket_print(struct node *n)
|
|||
|
||||
if (s->header == SOCKET_HEADER_DEFAULT)
|
||||
endian = "auto";
|
||||
else
|
||||
else {
|
||||
switch (s->endian) {
|
||||
case MSG_ENDIAN_LITTLE: endian = "little"; break;
|
||||
case MSG_ENDIAN_BIG: endian = "big"; break;
|
||||
}
|
||||
}
|
||||
|
||||
char *local = socket_print_addr((struct sockaddr *) &s->local);
|
||||
char *remote = socket_print_addr((struct sockaddr *) &s->remote);
|
||||
|
|
|
@ -12,15 +12,15 @@
|
|||
|
||||
#include <libconfig.h>
|
||||
|
||||
#include "nodes/websocket.h"
|
||||
#include "super_node.h"
|
||||
#include "webmsg_format.h"
|
||||
#include "timing.h"
|
||||
#include "utils.h"
|
||||
#include "msg.h"
|
||||
#include "config.h"
|
||||
#include "plugin.h"
|
||||
|
||||
#include "nodes/websocket.h"
|
||||
|
||||
/* Internal datastructures */
|
||||
struct destination {
|
||||
char *uri;
|
||||
|
@ -33,7 +33,7 @@ static int id = 0; /**< Highest assigned ID to websocket nodes. */
|
|||
struct list connections; /**< List of active libwebsocket connections which receive samples from all nodes (catch all) */
|
||||
|
||||
/* Forward declarations */
|
||||
static struct node_type vt;
|
||||
static struct plugin p;
|
||||
|
||||
__attribute__((unused)) static int websocket_connection_init(struct websocket_connection *c)
|
||||
{
|
||||
|
@ -143,7 +143,7 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi
|
|||
char *node = uri + 1;
|
||||
|
||||
/* Search for node whose name matches the URI. */
|
||||
c->node = list_lookup(&vt.instances, node);
|
||||
c->node = list_lookup(&p.node.instances, node);
|
||||
if (c->node == NULL) {
|
||||
warn("LWS: Closing Connection for non-existent node: %s", uri + 1);
|
||||
return -1;
|
||||
|
|
|
@ -143,8 +143,10 @@ int sample_scan(const char *line, struct sample *s, int *fl)
|
|||
*fl = flags;
|
||||
if (flags & SAMPLE_OFFSET) {
|
||||
struct timespec off = time_from_double(offset);
|
||||
s->ts.received = time_diff(&s->ts.origin, &off);
|
||||
s->ts.received = time_add(&s->ts.origin, &off);
|
||||
}
|
||||
else
|
||||
s->ts.received = s->ts.origin;
|
||||
|
||||
return s->length;
|
||||
}
|
||||
|
|
28
lib/web.c
28
lib/web.c
|
@ -125,6 +125,8 @@ static void logger(int level, const char *msg) {
|
|||
int web_init(struct web *w, struct api *a)
|
||||
{
|
||||
info("Initialize web sub-system");
|
||||
|
||||
lws_set_log_level((1 << LLL_COUNT) - 1, logger);
|
||||
|
||||
w->api = a;
|
||||
|
||||
|
@ -154,11 +156,6 @@ int web_parse(struct web *w, config_setting_t *cfg)
|
|||
|
||||
int web_start(struct web *w)
|
||||
{
|
||||
/* update web root of mount point */
|
||||
mounts[0].origin = w->htdocs;
|
||||
|
||||
lws_set_log_level((1 << LLL_COUNT) - 1, logger);
|
||||
|
||||
/* Start server */
|
||||
struct lws_context_creation_info ctx_info = {
|
||||
.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS | LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT,
|
||||
|
@ -176,14 +173,21 @@ int web_start(struct web *w)
|
|||
.ssl_private_key_filepath = w->ssl_private_key
|
||||
};
|
||||
|
||||
w->context = lws_create_context(&ctx_info);
|
||||
if (w->context == NULL)
|
||||
error("WebSocket: failed to initialize server");
|
||||
|
||||
w->vhost = lws_create_vhost(w->context, &vhost_info);
|
||||
if (w->vhost == NULL)
|
||||
error("WebSocket: failed to initialize server");
|
||||
info("Starting web sub-system");
|
||||
|
||||
{ INDENT
|
||||
/* update web root of mount point */
|
||||
mounts[0].origin = w->htdocs;
|
||||
|
||||
w->context = lws_create_context(&ctx_info);
|
||||
if (w->context == NULL)
|
||||
error("WebSocket: failed to initialize server");
|
||||
|
||||
w->vhost = lws_create_vhost(w->context, &vhost_info);
|
||||
if (w->vhost == NULL)
|
||||
error("WebSocket: failed to initialize server");
|
||||
}
|
||||
|
||||
w->state = STATE_STARTED;
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue