Random thoughts on Channels & Ports

New to XMOS and XCore? Get started here.
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am
Contact:

Random thoughts on Channels & Ports

Post by Interactive_Matter »

Hi,

I recently needed to rework a lot of code provided by XMOS - since I wnated to reuse parts of it.
While digging through the code I noticed some specifics of XC that makes code analysis really hard:

You have a lot of methods that start or use threads, that simpy pass a bunch of Ports and Channels around and it is really hard to understand what is going on for several reasons:
  • There are allways a number of Ports that fulfill a certain function: like RX/TX for UART - they are passed as single function arguments - so it is hard to understand what Ports define a functional block.
  • Normally two channel ends are in completely different source files and decoding the protocol that is spoken over the channel is quite hard to understand.
What do you think/is it possible to:

Define functional blocks of Ports as a struct. So that you got for example a UART_Ports - struct. Or does this reduce flexibility too much?

Redefine Channels e.g. with a typedef or similar to make sure which protocol is used - you can then implement the reader and writer routines for a Channel in a single source file. So that you see: This function is using a UART-Communication-Channel. Theoretically a Channel would be a great example for a classical object (as in C++) - but C++ would probably eat up too much precious RAM.

Or did I just not understand reading XC code well enough?

Marcus


Corin
Experienced Member
Posts: 66
Joined: Fri Dec 11, 2009 3:38 pm

Post by Corin »

Hi,

This is already possible with XC. e.g. a structure to hold some ports is declared as:

Code: Select all

typedef struct fram_interface_t
{
	in port p_miso;
	out port p_ss;
	out port p_sclk;
	out port p_mosi;
	clock clk;
} fram_interface_t;
This can then by used and populated with ports as follows:

Code: Select all

on stdcore[0] : fram_interface_t fram_ports = { PORT_SPI_MISO, PORT_SPI_SS, PORT_SPI_CLK, PORT_SPI_MOSI, XS1_CLKBLK_1 };
A function can then be called which accepts this structure, uses it and also passes it to another function:

Code: Select all

void fram_write_enable ( fram_interface_t &p )
{
	p.p_ss <: 0;
	byte_out(p, WREN);
	p.p_ss <: 1;
}
These examples are taken from sc_fram_if in the github repository.

Kind Regards,
Corin
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am
Contact:

Post by Interactive_Matter »

Cool,

this example is much more understandable than the code I have seen in the LED Tile code.

Is there also already a best practice to make Channels more understandable?

Thanks

Marcus
User avatar
davelacey
Experienced Member
Posts: 104
Joined: Fri Dec 11, 2009 8:29 pm

Post by davelacey »

Interactive_Matter wrote: Is there also already a best practice to make Channels more understandable?


Marcus

Putting related ports in structs is definitely best practice. For channel communication, I'm not sure there is no best practice as such. You can put all your communication primitives (from an application perspective) in a single source file e.g.

Code: Select all

/** Uart server functions **/

/** Send a byte from the server to the client **/
void uart_server_send(chanend c, char byte) {
   c <: byte;
}

/** Uart client functions **/

/** Receive a byte from the server */
void uart_client_receive(chanend c, char &byte) {
   c :> byte;
}

I think this hints towards your want to have the protocol in one place. However, this gets a bit more complex as the protocol gets more complex and I know some people explicitly don't like this style and prefer having the channel operations directly in their application code.
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am
Contact:

Post by Interactive_Matter »

davelacey wrote: ...

I think this hints towards your want to have the protocol in one place. However, this gets a bit more complex as the protocol gets more complex and I know some people explicitly don't like this style and prefer having the channel operations directly in their application code.
Why?
Having the channels cluttered over your code does not really help in terms of understandability.
I am not critizing having it in your code instead in one place. But if other people do it they must have reasons for it.

I think you can try to type the channel with a typef, so that the UART.h file would look like something like:

Code: Select all

typedef chanend uart_channel;

/** Send a byte from the server to the client **/
void uart_server_send(uart_channel c, char byte);
/** Uart client functions **/

/** Receive a byte from the server */
void uart_client_receive(uart_channel c, char &byte);
This would make the code a bit more understandable (for me)

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

Post by Folknology »

Definitely use structs for ports, I think that SPI code uses this.

As for the channel typing issues I have brought this up before and what we really need in XC is protocols from Occam

For more around these issues :
Also look here https://www.xcore.com/forum/viewtopic.p ... =protocols
And here https://www.xcore.com/forum/viewtopic.p ... =protocols

The other approach using struct to wrap channels/channends also doesn't work.

One can create structures used to pass the data and perhaps use naming conventions to hint at types but again these are really very poor bandages

Edit : Also using input functions adds calls to the event loop and is less efficient in cases where perhaps a select is used.

regards
Al
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am
Contact:

Post by Interactive_Matter »

Folknology wrote:Definitely use structs for ports, I think that SPI code uses this.

As for the channel typing issues I have brought this up before and what we really need in XC is protocols from Occam

...
Yep. That came to my mind too. Since to be honest I am also plainly too lazy to define a protocol - and that is what you do in your chanend handlers all day long.
I know, I come from a very high end world (Java Enterprise Web Applications) – but not to have to reinvent the wheel everytime yourself gives you more speed in development. And that is what we want to, isn't it?

Update: It would be great if dave could chime in to give us an update on that topic. But probably he had other things to do than this.

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

Post by Folknology »

but not to have to reinvent the wheel everytime yourself gives you more speed in development. And that is what we want to, isn't it?
I'm having fun with this at the moment on Amino, trying to find good ways to build modular components to support the modular hardware, but its early days and I'm spending more time on the hardware at the moment. Once the interfaces are finalised this month I will be able to spend more time on the software and perhaps start showing some of my ideas to get the conversation moving, definitely relevant to your comment above.

regards
Al
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am
Contact:

Post by Interactive_Matter »

Folknology wrote:
but not to have to reinvent the wheel everytime yourself gives you more speed in development. And that is what we want to, isn't it?
I'm having fun with this at the moment on Amino, trying to find good ways to build modular components to support the modular hardware, but its early days and I'm spending more time on the hardware at the moment. Once the interfaces are finalised this month I will be able to spend more time on the software and perhaps start showing some of my ideas to get the conversation moving, definitely relevant to your comment above.

regards
Al
If you want early feedback feel free to ask. There is absolutely the need for typesafe channels and protocols. I don't know if the tools currently check the correct handling of channel protocols

Thought myself about implementing some easy command/packet communication. Commands have a number and data to trigger actions - hello REST APIs and packets have a ID and some data - hello UDP. But that would be a lot of work and I am real busy know.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm
Contact:

Post by Folknology »

Channel protocols aren't currently implemented in XC and channels are not checked for type safety.
Post Reply