struct containing channels

Technical discussions related to any XMOS development kit or reference design. Eg XK-1A, sliceKIT, etc.
extremeRider
Member++
Posts: 19
Joined: Tue Jun 16, 2015 10:50 pm

struct containing channels

Postby extremeRider » Tue Sep 22, 2015 6:28 pm

Hi,
I'm developing a software interface for a gps breakout board.
The GPS provides a uart port for tx/rx.

I would like to use the serial library for XMOs devices on https://github.com/xcore?utf8=%E2%9C%93&query=uart

I was thinking to organize all the stuffs about serial communication in a struct like this:

Code: Select all

typedef struct {
    in port  rx;
    out port tx;
    int baudrate;
    chan crx;
    chan ctx;
} uart_com;
But when I try to compile, I get a couple of errors saying


error: field `crx' has resource type
error: field `ctx' has resource type


Is it possible to include channels into a structure?
User avatar
Ross
XCore Expert
Posts: 768
Joined: Thu Dec 10, 2009 9:20 pm

Postby Ross » Thu Nov 26, 2015 11:44 am

What about a pointer to a channel? I've not tried it myself to be honest..
Endre
Active Member
Posts: 37
Joined: Fri Jan 01, 2016 10:13 am

Postby Endre » Tue May 03, 2016 12:21 am

It's very annoying that in xC it is impossible to group stuff (variables, resources, etc.), which logically belongs together, into structs.
The lack of this ability can result ugly codes.

E.g. I'd like to implement some packet based USB communication code for more endpoints. I'd use a structure like this for storing all the info required for handling an endpoint:

Code: Select all

typedef struct {
    chanend ch;
    XUD_ep outEp;
    PtrBuffer freeBuf;
    PtrBuffer usedBuf;
    server interface ComRxIf rxIf;
} RxDesc;
Unfortunately I cannot place the "chanend" and the "interface" into the struct.
Than what can I do?
1. Don't use structs, just pass every related variables and resources to every handler functions. -> This is ugly and bloated.
2. Implement as much as possible in C and provide xC callouts for the XMOS specific stuff. -> Even more ugly and bloated.
3. ?

I'd rather like to be able to write well structured xC code, than to expect extra safety from the compiler.
Maybe the code safety shouldn't be a compile time issue. The source also could be compiled in some debug mode which would add some run-time safety checkers (of course this approach would require deep testing which is an extra job).
Endre
Active Member
Posts: 37
Joined: Fri Jan 01, 2016 10:13 am

Postby Endre » Tue May 03, 2016 10:50 am

Sorry for the loud thinking, I just have an idea to group stuff together without using structs.
In my example before I attempted to handle more USB endpoints in one task, and I attempted to group all stuff of an endpoint into a struct (which is not possible).
Maybe it is possible to make a combinable task which handles only one endpoint and instantiate this task for each endpoint on the same core. Communication between the task instances could be handled by a distributable task. I don't know the feasibility of this, I haven't tried it out yet.
User avatar
ers35
Active Member
Posts: 62
Joined: Mon Jun 10, 2013 2:14 pm

Postby ers35 » Tue May 03, 2016 2:18 pm

As Ross indicated, movable pointers make this possible. See the following example:

Code: Select all

// xcc -target=XCORE-200-EXPLORER struct-res-pointers.xc -o struct-res-pointers.xe

interface bar
{
  void test();
};

struct foo {
  chanend *movable cptr;
  server interface bar *movable bar_if;
};

select handler(struct foo &f)
{
  case *f.cptr :> unsigned:
  {
    break;
  }
  
  // A bug in tools 14.1.2 prevents this from working.
  // I reported the bug.
  /*
  case *f.bar_if.test():
  {
    break;
  }
  */
}

void loop(chanend c, server interface bar bar_if)
{
  struct foo f;
  chanend *movable cptr = &c;
  f.cptr = move(cptr);
  server interface bar *movable barptr = &bar_if;
  f.bar_if = move(barptr);
  
  while (1)
  {
    select
    {
      case handler(f);
    }
  }
  
  // move back to original value
  cptr = move(f.cptr);
  barptr = move(f.bar_if);
}

int main()
{
  chan c;
  interface bar bar_if;
  loop(c, bar_if);
  
  return 0;
}
Endre
Active Member
Posts: 37
Joined: Fri Jan 01, 2016 10:13 am

Postby Endre » Tue May 03, 2016 3:08 pm

Thanks for the hint. I have only tried with unsafe pointer before.

Who is online

Users browsing this forum: No registered users and 2 guests