Add RT examples

pull/457/head^2
Ben Haines 2 years ago
parent 1153336818
commit 8187e434ee

@ -0,0 +1,20 @@
set(goose_subscriber_example_SRCS
goose_subscriber_example_RT.c
)
IF(MSVC)
set_source_files_properties(${goose_subscriber_example_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(MSVC)
add_executable(goose_subscriber_example_RT
${goose_subscriber_example_SRCS}
)
target_link_libraries(goose_subscriber_example_RT
iec61850
)

@ -0,0 +1,17 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = goose_subscriber_example_RT
PROJECT_SOURCES = goose_subscriber_example_RT.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

@ -0,0 +1,98 @@
/*
* goose_subscriber_example.c
*
* This is an example for a standalone GOOSE subscriber
*
* Has to be started as root in Linux.
*
* BPH - 11-8-21
* Adapted from original goose publlisher example to implement realtime threading and priorities
*
*/
#include "goose_receiver.h"
#include "goose_subscriber.h"
#include "hal_thread.h"
#include "linked_list.h"
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
static int running = 1;
static void
sigint_handler(int signalId)
{
running = 0;
}
static void
gooseListener(GooseSubscriber subscriber, void* parameter)
{
printf("GOOSE event:\n");
printf(" stNum: %u sqNum: %u\n", GooseSubscriber_getStNum(subscriber),
GooseSubscriber_getSqNum(subscriber));
printf(" timeToLive: %u\n", GooseSubscriber_getTimeAllowedToLive(subscriber));
uint64_t timestamp = GooseSubscriber_getTimestamp(subscriber);
printf(" timestamp: %u.%u\n", (uint32_t) (timestamp / 1000), (uint32_t) (timestamp % 1000));
printf(" message is %s\n", GooseSubscriber_isValid(subscriber) ? "valid" : "INVALID");
MmsValue* values = GooseSubscriber_getDataSetValues(subscriber);
char buffer[1024];
MmsValue_printToBuffer(values, buffer, 1024);
printf(" allData: %s\n", buffer);
}
int
main(int argc, char** argv)
{
// BPH Notes: Single receiver on interface with potentially multiple subscribers.
GooseReceiver receiver = GooseReceiver_create(); //BPH Notes: Mallocs Receiver Struct and Eth Buffer
if (argc > 1) {
printf("Set interface id: %s\n", argv[1]);
GooseReceiver_setInterfaceId(receiver, argv[1]);
}
else {
printf("Using interface eth0\n");
GooseReceiver_setInterfaceId(receiver, "eth0");
}
GooseSubscriber subscriber = GooseSubscriber_create("simpleIOGenericIO/LLN0$GO$gcbAnalogValues", NULL);
uint8_t dstMac[6] = {0x01,0x0c,0xcd,0x01,0x00,0x01};
GooseSubscriber_setDstMac(subscriber, dstMac);
GooseSubscriber_setAppId(subscriber, 1000);
// BPH Notes: Attach listner function to subscriber struct, called when goose received that matches
GooseSubscriber_setListener(subscriber, gooseListener, NULL);
// BPH Notes: add subscriber struct to receiver list
GooseReceiver_addSubscriber(receiver, subscriber);
// BPH Notes: call when all subscribers added
GooseReceiver_start_RT(receiver); // Create receive thread with RT priority
if (GooseReceiver_isRunning(receiver)) {
signal(SIGINT, sigint_handler);
while (running) {
Thread_sleep(100);
}
}
else {
printf("Failed to start GOOSE subscriber. Reason can be that the Ethernet interface doesn't exist or root permission are required.\n");
}
GooseReceiver_stop(receiver);
GooseReceiver_destroy(receiver);
return 0;
}

@ -0,0 +1,20 @@
set(sv_subscriber_example_SRCS
sv_subscriber_example_RT.c
)
IF(MSVC)
set_source_files_properties(${sv_subscriber_example_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(MSVC)
add_executable(sv_subscriber_example_RT
${sv_subscriber_example_SRCS}
)
target_link_libraries(sv_subscriber_example_RT
)

@ -0,0 +1,21 @@
LIBIEC_HOME=../..
PROJECT_BINARY_NAME = sv_subscriber_RT
PROJECT_SOURCES += sv_subscriber_example_RT.c
INCLUDES += -I.
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)

@ -0,0 +1,95 @@
/*
* sv_subscriber_example.c
*
* Example program for Sampled Values (SV) subscriber
*
*/
#include "hal_thread.h"
#include <signal.h>
#include <stdio.h>
#include "sv_subscriber.h"
static bool running = true;
void sigint_handler(int signalId)
{
running = 0;
}
/* Callback handler for received SV messages */
static void
svUpdateListener (SVSubscriber subscriber, void* parameter, SVSubscriber_ASDU asdu)
{
printf("svUpdateListener called\n");
const char* svID = SVSubscriber_ASDU_getSvId(asdu);
if (svID != NULL)
printf(" svID=(%s)\n", svID);
printf(" smpCnt: %i\n", SVSubscriber_ASDU_getSmpCnt(asdu));
printf(" confRev: %u\n", SVSubscriber_ASDU_getConfRev(asdu));
/*
* Access to the data requires a priori knowledge of the data set.
* For this example we assume a data set consisting of FLOAT32 values.
* A FLOAT32 value is encoded as 4 bytes. You can find the first FLOAT32
* value at byte position 0, the second value at byte position 4, the third
* value at byte position 8, and so on.
*
* To prevent damages due configuration, please check the length of the
* data block of the SV message before accessing the data.
*/
if (SVSubscriber_ASDU_getDataSize(asdu) >= 8) {
printf(" DATA[0]: %f\n", SVSubscriber_ASDU_getFLOAT32(asdu, 0));
printf(" DATA[1]: %f\n", SVSubscriber_ASDU_getFLOAT32(asdu, 4));
}
}
int
main(int argc, char** argv)
{
SVReceiver receiver = SVReceiver_create();
if (argc > 1) {
SVReceiver_setInterfaceId(receiver, argv[1]);
printf("Set interface id: %s\n", argv[1]);
}
else {
printf("Using interface eth0\n");
SVReceiver_setInterfaceId(receiver, "eth0");
}
/* Create a subscriber listening to SV messages with APPID 4000h */
SVSubscriber subscriber = SVSubscriber_create(NULL, 0x4000);
/* Install a callback handler for the subscriber */
SVSubscriber_setListener(subscriber, svUpdateListener, NULL);
/* Connect the subscriber to the receiver */
SVReceiver_addSubscriber(receiver, subscriber);
/* Start listening to SV messages - starts a new receiver background thread */
SVReceiver_start_RT(receiver);
if (SVReceiver_isRunning(receiver)) {
signal(SIGINT, sigint_handler);
while (running)
Thread_sleep(1);
/* Stop listening to SV messages */
SVReceiver_stop(receiver);
}
else {
printf("Failed to start SV subscriber. Reason can be that the Ethernet interface doesn't exist or root permission are required.\n");
}
/* Cleanup and free resources */
SVReceiver_destroy(receiver);
return 0;
}
Loading…
Cancel
Save