Language Interoperability

Technical questions regarding the XTC tools and programming with XMOS.
Post Reply
User avatar
jonathan
Respected Member
Posts: 377
Joined: Thu Dec 10, 2009 6:07 pm
Contact:

Language Interoperability

Post by jonathan »

Does anyone have any good example projects or bits of code where C/C++ modules call various bits of XC to perform port/channel communication?

I can't at the moment get my head around what the programming model looks like - for example, if you have C programs calling bits of XC I can't see how those bits of XC can be made to communicate with each other without resorting to assembler (though I can see how they might use ports).

A few examples would be really helpful. There's always a "hack" but some guidance as to the least ugly method would be cool.

By the way, in the Tools User Guide there seems to be a mistake:
19.1.2 Passing Arguments from C/C++ to XC

A function defined in XC with a parameter of type port, chanend or timer can be declared in XC as taking a parameter of type unsigned int.
Shouldn't that say "C/C++"?


Image
User avatar
jonathan
Respected Member
Posts: 377
Joined: Thu Dec 10, 2009 6:07 pm
Contact:

Post by jonathan »

A great - and hopefully simple - example would be to demonstrate a recommended way of using one of the XMOS UART implementations from C/C++. As I said, I can think of a few ways to refactor code between C/C++/XC and assembler to make this work but would appreciate some advice on the "recommended" way.
Image
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

Post by Heater »

Have a look at compat.h.

Using that you can pass channel ends and other XC things in to C/C++ functions called from XC.
And of course C/C++ can pass them back to XC functions.

I have found this very useful when I have a large chunk of C code that needs to input/output on a channel at some point.
User avatar
Andy
Respected Member
Posts: 279
Joined: Fri Dec 11, 2009 1:34 pm

Post by Andy »

I define the channel in main.xc and pass it to the C function as a chanend. As long as you include
#include <xccompat.h>
in the top level header file, you can use chanend as a type in C.

Generally, I then implement the channel communication as a function in an XC file and share this function in a header included in both the C and XC file. Then you can just call the function and pass the data you want to send as an array or parameter.
User avatar
jonathan
Respected Member
Posts: 377
Joined: Thu Dec 10, 2009 6:07 pm
Contact:

Post by jonathan »

OK for the benefit of others, here's an example that I put together to me (not tested properly, but it compiles at least).

uart.xc has an XC implementation of a UART.
main.c is a C program that uses uart.xc

This kind of thing needs a few examples like this written by the pros if possible...

PS Jason if you're reading this I couldn't upload a .c file, hence why I "tar"ed it up. It would have been better to place all the source files (.h .xc .c) inline! If you fix this then you might as well add ".cpp" too.
Attachments
demo.tar
(20 KiB) Downloaded 234 times
demo.tar
(20 KiB) Downloaded 234 times
Image
User avatar
monk_is_batman
Active Member
Posts: 38
Joined: Wed Jun 09, 2010 3:20 am
Location: Maine, USA
Contact:

Post by monk_is_batman »

I compiled it and tested your code and it does not run as expected. The problem is that the main of the program is in C. When a par block is started non of the threads can continue until all of them have completed. This means since one of your functions has a while (1) in it, the program will never leave the par block.

The solution to this is to start the program in XC and call your main C function from it. I would recommend something structured as follows.

on stdcore[0]: port p_rx = PORT_UART_RX;
on stdcore[0]: port p_tx = PORT_UART_TX;

int main(void)
{
chan txData_ch;
chan rxData_ch;

par {
on stdcore[0]: uartbody (p_tx, txData_ch, p_rx, rxData_ch);
on stdcore[0]: c_program(txData_ch, rxData_ch);
}
}

This way your C program will have both chanends as well as be able to continue running in parallel of your uart thread.
User avatar
jonathan
Respected Member
Posts: 377
Joined: Thu Dec 10, 2009 6:07 pm
Contact:

Post by jonathan »

Ah yes, of course, you're right.

However, let's suppose I don't want to have the main in XC, for whatever reason. How else can I achieve this effect? I'll have another look at the code and see if I can find another good "pattern" for solving this problem.

I think this boils down to how you initiate a non-terminating, concurrent process in XC from within C.
Image
User avatar
jonathan
Respected Member
Posts: 377
Joined: Thu Dec 10, 2009 6:07 pm
Contact:

Post by jonathan »

Ah, can't you just move the code that "does stuff" into the callback routine in the C file main.c?

Code: Select all

#include <xccompat.h>
#include "main.h"
#include "uart.h"

chanend txChan;
chanend rxChan;

unsigned char getByte();
void putByte(unsigned char b);

int main()
{
  uart_init();

  return 0;
}

void setup_channels(chanend txDataIn, chanend rxDataIn) {
  txChan = txDataIn;
  rxChan = rxDataIn;

  // Do stuff here that calls getByte and putByte
  // for example, TX everything on RX
  unsigned char c;

  while (1) {
    c = getByte();
    putByte(c);
  }

}

unsigned char getByte()
{
    unsigned char c;
    c = uart_getc(rxChan);
    return c;
}

void putByte(unsigned char b)
{
    uart_putc(b, txChan);
}
I'll test this later but just thought of it.
Attachments
demo.tar
(20 KiB) Downloaded 217 times
demo.tar
(20 KiB) Downloaded 217 times
Image
User avatar
monk_is_batman
Active Member
Posts: 38
Joined: Wed Jun 09, 2010 3:20 am
Location: Maine, USA
Contact:

Post by monk_is_batman »

You're right that should work, haven't tested it though. I had't thought of that approach, would work fine for L1s, but would limit to 1 core on the G4.

As far as starting a thread in XC that can continue on. I have spend a lot of time trying to create asynchronous threads and have yet to figure out a method that will do it in XC. That being said I wrote a single thread_create() using inline assembly to launch a thread in C and this seems to work pretty well for the most part, I use it often.
User avatar
jason
XCore Expert
Posts: 577
Joined: Tue Sep 08, 2009 5:15 pm
Contact:

Post by jason »

Added support to attach .c .xc .cpp
Post Reply