Create a single channel end in XC

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
skoe
Experienced Member
Posts: 94
Joined: Tue Apr 27, 2010 10:55 pm

Create a single channel end in XC

Post by skoe »

If I want to send messages to a thread from various other threads it's useful to take a single channel end instead of having a whole bunch of channels. (There was somebody else in the last days with a similar problem) Is there another possibility to do this than in the code snippet below?

Code: Select all

/* ... */
unsigned uart_chanend;

void uart_thread(void)
{
    unsigned ret;
    asm (
            "getr   %0, %1          \n"
            : "=r"(ret)
            : "i"(XS1_RES_TYPE_CHANEND) /* why does this not work? */
    );
    // todo: check if ressource was available
    uart_chanend = ret;
    
    asm (
            "mov    r0, %0               \n"
            "bl     uart_thread_internal \n"
            : /* no output */
            : "r"(ret)
            : "r0"
    );
}

static void uart_thread_internal(chanend uart_chanend)
{
/* .... */
Edit: The code snippet doesn't compile, what's wrong with the "i"? It's too late today *yawn*

(Remark: When I implementet the event handling in C I found that it's not as elegant as the select statement in XC, that's why I'm trying XC again.)

The XMOS toolchain has a great compiler backend, very well done. But I feel like XC degrades the possibilities of the XMOS. Is there hope that it will be extended soon to allow features like asynchronous threads, runtime channel setup and other things that are possible on the XMOS?

Regards,
Thomas


User avatar
larry
Respected Member
Posts: 275
Joined: Fri Mar 12, 2010 6:03 pm

Post by larry »

The code snippet doesn't compile, what's wrong with the "i"?
Immediates are currently not supported in XC inline assembly. They are in C inline assembly. Please see my post at http://www.xcore.com/forum/viewtopic.php?f=25&t=405
User avatar
skoe
Experienced Member
Posts: 94
Joined: Tue Apr 27, 2010 10:55 pm

Post by skoe »

Thanks, larry.

Sorry, I didn't read the post in the other thread careful enough, because the question I asked initially was solved already. Shame on me ;)

This works:

Code: Select all

         
"getr   %0, 2 \n"
However, this doesn't answer my basic question. At night I got an idea. I'll tell it here, maybe it helps others and maybe somebody can improve it:

If you have n threads which all may communicate to each other (*), there would be ehhm... a lot of channels involved in XC.

(*) In my project not all do this, but only some of them. This example is the worst case.

As the speed/latency of this communication is not very critical in my case, I'll do this: For n threads I use n channels. The main thread (the one which allocates the channels) keeps one end of each channel, the other threads get the other end.

Each time a thread wants to send a message to another thread, it puts a virtual address into it. Then the main thread can route it to the other channels. The address is just a simple software-defined enumeration which is defined at compile-time. With this mechanism even unicast, multicast and broadcast messages can be implemented.

As my messages are really small, they'll look like this:
0xssssttaa

aa = address, e.g. THREAD_IP, THREAD_UART, THREAD_FOOBAR, THREAD_BROADCAST (send to all)
tt = type, an application specific enumeration
ssss = size, if != 0 there are more int values coming which shall be sent to the same receiver.

Maybe another feature (transactions?) of the channels I didn't read about yet will help to improve this mechanism.

Thomas