Services aren't described in the official 9.2 documentation because it's not well tested, but here's a worked example the compiles and appears to do the Right Thing.
Suppose you'd attached a waffle iron to your xcore. Sadly I don't have such a device attached to my system so I haven't been able to run this example to completion. Anyway, your XN file would end up something like the code below.
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<Network xmlns="http://www.xmos.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.xmos.com http://www.xmos.com">
<Type>Board</Type>
<Declarations>
<Declaration>core stdcore[2]</Declaration>
</Declarations>
<Nodes>
<Node Id="master" Type="XS1-L1A-LQ64">
<Core Number="0" Reference="stdcore[0]"/>
</Node>
<Node Id="1" Type="device:waffle_iron">
<Service Id="0" Proto="waffleBaker( chanend cIn )">
<Chanend identifier="cIn" end="0:0:6" remote="0:1:0"/>
</Service>
</Node>
</Nodes>
<Links>
<Link Encoding="2wire" Delays="1,1">
<LinkEndpoint NodeId="master" Link="X0LC"/>
<LinkEndpoint NodeId="1" Link="X1LC"/>
</Link>
</Links>
<JTAGChain>
<JTAGDevice NodeId="master"/>
</JTAGChain>
</Network>
The waffle iron gets a Node node. Unlike xcore nodes the node id is restricted to being an integer. The Type value has to be "device:<something>". The waffle iron provides a service so it has a Service node inside it. The service id has to be an integer too. The function prototype may contain only channel ends and effectively enumerates all the channels which will be instantiated across the xlink.
For each channel end in the prototype you need to specify the channel end it's going to use at the xcore end and the channel end it's going to use at the device end. On G4, these are of the form "<node>:<core>:<end>". With L1 the node/core dichotomy is removed at so it should be of the form "0:<node>:<end>".
In the example, at the xcore end channel end six will be used whilst at the device end channel end 0 will be used. Thus your device should expect to receive packets destined for node id 1, channel end 0. To send to the xcore it should address its packets to node id 0, channel end 6. The tool chain will hide these details from XC; the chanend will automatically be connected to the correct ends.
The links section is pretty much the same as if there were two xcores. The non-xcore device does not appear in the jtag chain section.
The XC code (below) is nothing special. In the top-level par statment the service is "called" with the appropriate channel end argument. The program can then foward a list of ingredients to the waffle iron and receive back a token which acknowledges the waffle has been made and eaten.
Code: Select all
#include <platform.h>
typedef struct
{
int flour;
int sugar;
int egg;
int milk;
int yeast;
} WaffleMix;
void bakeWaffle( chanend c )
{
int waffleToken;
WaffleMix waffleMix;
waffleMix.flour = 500;
waffleMix.sugar = 100;
waffleMix.egg = 4;
waffleMix.milk = 100;
waffleMix.yeast = 7;
c <: waffleMix;
c :> waffleToken;
}
int main()
{
chan waffleChan;
par
{
on stdcore[0]:
{
for( int i=0; i<6; i++ )
{
bakeWaffle( waffleChan );
}
}
waffleBaker( waffleChan );
}
return(0);
}
Best friends with the code fairy.