Examples
This example shows how to create a simple SpaceWire Router and a Grspw2 device and connect them.
import BusModels
import TEMUGrspw2
object-create class=Grspw2 name=grspw0
object-create class=SpwRouter name=spwRouter
spw-connect port1=grspw0:SpwPortIface[0] port2=spwRouter:SpwPortIface[0]
The next example shows how to implement a simple SpaceWire device
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "temu-c/Support/Objsys.h"
#include "temu-c/Support/Attributes.h"
#include "temu-c/Support/Logging.h"
#include "temu-c/Bus/Spacewire.h"
typedef struct {
temu_Object Super;
int TransmitterDataRate;
temu_SpwLinkState LinkState;
temu_SpwPortIfaceRef Uplink;
} SpwDevice;
void*
create(const char *Name,
int Argc TEMU_UNUSED,
const temu_CreateArg *Argv TEMU_UNUSED)
{
void *Obj = malloc(sizeof(SpwDevice));
memset(Obj, 0, sizeof(SpwDevice));
printf("Creating Object '%s'\n", Name);
return Obj;
}
void
destroy(void *Obj)
{
free(Obj);
}
static void
spwDeviceChangeLinkState(SpwDevice *Device, temu_SpwLinkState LinkState)
{
Device->LinkState = LinkState;
if ((Device->Uplink.Iface != NULL) && (Device->Uplink.Obj != NULL)) {
Device->Uplink.Iface->signalLinkStateChange(
Device->Uplink.Obj, LinkState);
}
}
///////////////////////////////////////////////////////////////////////////////
// SpwPortIface 0 implementation
///////////////////////////////////////////////////////////////////////////////
static void
spwPortIfaceReceive0(void *Obj, void *Sender, temu_SpwPacket *Pkt)
{
// Handle packet received.
SpwDevice *Dev = (SpwDevice*)(Obj);
temu_logInfo(Dev, "Received SpaceWire packet");
}
static void
spwPortIfaceSignalLinkStateChange0(void *Obj, temu_SpwLinkState LinkState)
{
// The other side notified us that its link state changed.
SpwDevice *Dev = (SpwDevice*)(Obj);
temu_logInfo(Dev, "Other side link state changed");
// Depending on the other side link state change update this
// device link state.
}
static temu_SpwLinkState
spwPortIfaceGetOtherSideLinkState0(void *Obj)
{
// Other side request this device state.
SpwDevice *Dev = (SpwDevice*)(Obj);
return (temu_SpwLinkState)Dev->LinkState;
}
static void
spwPortIfaceConnect0(void *Obj, temu_SpwPortIfaceRef PortIf)
{
SpwDevice *Dev = (SpwDevice*)(Obj);
Dev->Uplink = PortIf;
// When two ports are connected the device goes to ready state.
spwDeviceChangeLinkState(Dev, teSPWLS_Ready);
}
static void
spwPortIfaceDisconnect0(void *Obj)
{
SpwDevice *Dev = (SpwDevice*)(Obj);
Dev->Uplink.Iface = NULL;
Dev->Uplink.Obj = NULL;
// When two ports are diconnected the device goes to error reset state.
spwDeviceChangeLinkState(Dev, teSPWLS_ErrorReset);
}
static uint64_t
spwPortIfaceTimeToSendPacketNs0(void* Obj, uint64_t PacketSize)
{
SpwDevice *Dev = (SpwDevice*)(Obj);
// Return the time required to transmit the packet through this port.
return PacketSize / Dev->TransmitterDataRate;
}
temu_SpwPortIface SpwPortIface0 = {
spwPortIfaceReceive0,
spwPortIfaceSignalLinkStateChange0,
spwPortIfaceGetOtherSideLinkState0,
spwPortIfaceConnect0,
spwPortIfaceDisconnect0,
spwPortIfaceTimeToSendPacketNs0
};
TEMU_PLUGIN_INIT
{
temu_Class *Cls = temu_registerClass("SpwDevice", create, destroy);
// Reference to the port interface of the other end.
temu_addProperty(Cls, "Uplink",
offsetof(SpwDevice, Uplink),
teTY_IfaceRef,
1, // Number of elements (1 = scalar)
NULL, NULL,
"Other end port interface");
// Port interface.
temu_addInterface(Cls, "SpwPortIface", "SpwPortIface", &SpwPortIface0,
0, "SpaceWire port interface");
}