"service" functions in XC. How to?

Technical questions regarding the XTC tools and programming with XMOS.
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

"service" functions in XC. How to?

Post by Heater »

It has been suggested to me that functions declared as "service" in XC will be able to communicate with any device that provides an XMOS link. There is an example in section 3.7 of the XC manual. This looks exactly what I want to configure communications with an external CPU.

Trouble is the "magic" behind service functions is to be specified in the .xn file. So far I have failed to figure out how this may be done.

I think I need something like this to say where the channel end points are and tweak the link speed:

Code: Select all

   <Links>
        <Link Encoding="2wire" Delays="4,4">
            <LinkEndpoint NodeId="Master" Link="X0LD"/>
            <LinkEndpoint NodeId="Service" Link="X0LC"/>
        </Link>
    </Links>

But this only see work out if the NodeIds are XMOS devices. I cannot just have 1 end point here either. So I need an imaginary device of some kind to represent the alien hardware.

Also I have no idea how to match up what is defined in the .xn file with the channel used in the service function parameter.

Anyone have an example of a simple XC and .xn combo that demonstrates this "service" feature?


User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm
Contact:

Post by Folknology »

I am also interested in understanding the 'Service' magic, anyone got any pointers?

regards
Al
User avatar
trousers
Active Member
Posts: 44
Joined: Fri Dec 11, 2009 10:20 am
Contact:

Post by trousers »

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.
User avatar
that_awesome_guy
Member
Posts: 10
Joined: Mon Dec 14, 2009 7:06 pm
Contact:

Post by that_awesome_guy »

Found a way to stop your code running all night...

Code: Select all

waffleMix.yeast  = 7;
should in fact be

Code: Select all

waffleMix.yeast  = 0;
I also found a good page about further optimisations to your waffle algorithm - http://www.waffle-recipe.com/recipes/be ... le-recipe/

:lol:
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

Post by Heater »

Thanks for the info.

I just tried building the waffle iron code but I get the error:

Code: Select all

../XC-1.xn:16 Error: XN11018 Unrecognised attribute "Id" in Service node.
xmake: *** [main.o] Error 1
Removing the Id attribute, not for any good reason, gets me a segfault:

Code: Select all

[xcc -O3 -Wall -c -o "main.o" "../main.xc" "../XC-1.xn"
xmake: *** [main.o] Segmentation fault
I'm using XDE Version: 9.9.0 (build 1453).
User avatar
trousers
Active Member
Posts: 44
Joined: Fri Dec 11, 2009 10:20 am
Contact:

Post by trousers »

Heater wrote:I'm using XDE Version: 9.9.0 (build 1453).
I'm afraid you need to upgrade to the latest version. Services weren't working at all in 9.9.0.
Best friends with the code fairy.
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

Post by Heater »

OK, thanks, now it compiles with XDE 9.9.2

How quickly we fall behind here:)

Now I just have to wait to get hold of some hardware to test with.

Jumping the gun a bit but the next question is - What do I need to do for a service that may not be powered up at the same time as the XMOS device or may be on a pluggable connection, on a different board say?
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

Post by Heater »

I just realized I am missing a point here.

In the service example in the XC manual section 3.7 it shows a function prototype declared with the "service" attribute.

In the wafflebaker example there is no such "service" declaration. Instead the prototype is defined in the .xn file.

Has this changed or is this just a different way to do it or is the "service" declaration auto-generated into some header file I can't find yet?
User avatar
trousers
Active Member
Posts: 44
Joined: Fri Dec 11, 2009 10:20 am
Contact:

Post by trousers »

Heater wrote:Jumping the gun a bit but the next question is - What do I need to do for a service that may not be powered up at the same time as the XMOS device or may be on a pluggable connection, on a different board say?
You can add attribute to the Link node: Flags="noinit"

i.e. the link section becomes:

Code: Select all

  <Links>
    <Link Encoding="2wire" Delays="1,1" Flags="noinit">
      <LinkEndpoint NodeId="master" Link="X0LC"/>
      <LinkEndpoint NodeId="1" Link="X1LC"/>
    </Link>
  </Links>
This will cause the mapper to not initialise the xlink in question on the assumption that the application will enable and initialise it later.

XC IO will block if attempted before the xlink is activated.
Best friends with the code fairy.
User avatar
trousers
Active Member
Posts: 44
Joined: Fri Dec 11, 2009 10:20 am
Contact:

Post by trousers »

Heater wrote:In the service example in the XC manual section 3.7 it shows a function prototype declared with the "service" attribute.
In the wafflebaker example there is no such "service" declaration. Instead the prototype is defined in the .xn file.
Has this changed or is this just a different way to do it or is the "service" declaration auto-generated into some header file I can't find yet?
The latter. The prototype is taken from the XN and put into "platform.h" which is automagically generated at compile time.
Best friends with the code fairy.
Post Reply