XC: how to pass buffer reference through interface

Technical questions regarding the XTC tools and programming with XMOS.
babazaroni
Experienced Member
Posts: 94
Joined: Sun Feb 10, 2013 4:47 am

XC: how to pass buffer reference through interface

Post by babazaroni »

I am using a single tile device and would like to pass a buffer address thru an interface, but get the error "cannot pass remote reference as a function argument".

How can I pass a buffer address thru an interface and use it as a buffer in the server?

Here is some sample code showing what I am trying to do:

Code: Select all

interface background_if {
  void i2c_master_write_reg(int dest_address, int dest_reg,unsigned char buffer[], int len);
};

void background_task(server interface background_if i){

  for(;;)
  {
       select {

           case i.i2c_master_write_reg(int dest_address, int dest_reg,unsigned char buffer[], int len):
// the following line generates the error "cannot pass remote reference as a function argument"
                i2c_master_write_reg(dest_address, dest_reg, buffer, len, r_i2c_if);
            break;
         }
     }
}

void calling_function(client interface background_if i){
    unsigned char buffer[5];
    i.i2c_master_write_reg(0x60,0,mybuffer,sizeof(my_buffer));
}


krishnabalan
Member++
Posts: 24
Joined: Thu Aug 14, 2014 10:55 am

Post by krishnabalan »

Indeed a very good question!

Passing buffer (arrays) as references over interfaces has this limitation i.e. the reference array passed as argument to a server interface (called as remote reference) cannot be passed on as normal references to other functions. Because, technically the server task running in one core and the client task running in other core implicitly uses the underlying channels for communication.
So when a server task accesses the elements of the referenced array i.e when buffer[0] is used in the server task, a channel communication happens at the back to fetch the first value of the array from the client task. If you access all the elements of the array in the server tasks' case statement itself, then there will not be any issue, but you cannot pass on this reference to some other function which doesn't know that a channel access is required at the back for fetching any value of the array/buffer.

What are the other possible ways to overcome this?
- Use a memcpy in the server task's case statement to copy the whole buffer to another local buffer so as to pass reference to the local buffer to other functions. (Yes time consuming).
- Using shared memory; there are multiple ways exists for using shared memory.
- Using movable pointers.
- Using distributable tasks.
- Using unsafe pointers but you have to take the whole pain in making buffer access mutually exclusive.

Hope it hepls! There might be better ways which experts in this forum can help with.

Cheers,

Krishna