C library which covers most (all?) XMOS features

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

C library which covers most (all?) XMOS features

Post by skoe »

Hi all,

There's an idea in my mind I want to share with you and ask you for your opinion:

During the last days (or better: nights) I read lots of XMOS documentation, searched in the forums and checked some projects to get an impression about the XMOS and the development software.

One thing I got aware of seems to come up in this forum (and xmoslinkers) from time to time: Interoperability with C code.

XC is a very well designed programming language with up-to-date techniques. But it is not C. The advantages of XC can easily become to disadvantages for experienced C programmers.

Of course, there is always the possibility to mix C and XC and to use inline assembly. But this looks a bit like a workaround and is done in a different way from project to project.

I started to implement a library to be used in C which hopefully can make use of the most features (or even all?) of the XMOS. This should make it easier for C programmers to port and extend their software. Possibly for high-end applications pure assembly or XC will always be more suitable.

Currently I have implemented some code snippets for input/output (ports, channels) and for event handlers (aka XC select). It looks like it should be possible to do them with minimal or no performance differences from XC. As I'm new to XMOS it'll take a while until I find all stumbling blocks.

Currently I implement the stuff in separate source files, later it will most probably become a header file with inline assembly.

Before I go on: Do I re-invent the wheel? Will there be major unresolvable problems?

Looking forward to your comments,
Thomas


User avatar
shawn
XCore Addict
Posts: 238
Joined: Thu Dec 17, 2009 5:15 am

Post by shawn »

Very cool of you, it shall be very beneficial for the C programing community.
What a valuable ideal, C programmers can start cutting holistic code in there native environment.
C has always been the bane of my existence. So for me its XC and Xasm. I love C C++ STL it history
and I am still learning so much from C. So strange from such a simple language, sure is nefarious.
Make sense when you start realizing with it's birth came the first major cross platform compilations.
The very hack they used has become more important than the language. I doubt Bell Labs wanted everyone to have a copy at no cost.

Shawn,
User avatar
skoe
Experienced Member
Posts: 94
Joined: Tue Apr 27, 2010 10:55 pm

Post by skoe »

So, there are some first results. Not much, because I had to get familiar with the inline assembler, didn't do this kind of stuff for long.

There are only a few functions now, I implemented only a few to check the feasibility. A beginning of something like documentation can be found there:
http://skoe.de/libxm/doc/html/

How does it look like? This is the main entry point:

Code: Select all

int main(void)
{
    unsigned i = 0;
    uart_init();
    
    for (;;)
    {
        uart_puts("\r\nHello, world...");
        uart_putdec(++i);
        uart_putcrlf();
    }
}
btw: The uart_* functions are code I wrote a long time ago for memory limited platforms. They look a bit bloated but are much smaller than a printf implementation. And suitable for simple debug output.

The low level uart implementation looks like this in C:

Code: Select all

unsigned txd = PORT_UART_TX;
unsigned rxd = PORT_UART_RX;

/*******************************************************************************
 * Init everything needed to get the rest of the UART functions running.
 *
 ******************************************************************************/
void uart_init(void)
{
    unsigned time;
    
    uart_chanend = xchan_alloc();

    xthread_create(uart_thread_stack + UART_THREAD_STACK_ENTRIES - 1,
                   uart_thread, 0);

    xport_start(txd);
    
    // idle = tx high for at least one bit time, to be sure...
    time = xport_out_get_time(txd, 1);
    xport_out_at_time(txd, 1, time + BIT_TIME);
}

void uart_thread(void)
{
    unsigned time;
    int byte;
    int i;

    for (;;)
    {
        // get byte and end token from channel
        byte = xchan_in(uart_chanend);
        xchan_inct(uart_chanend);

        // add one stop bit, it is set two times because we have no pause 
        // after the last bit in the loop below
        byte |= 0x300;

        // send startbit (same as txd <: 0 @ time);
        time = xport_out_get_time(txd, 0);

        // send data and stop bit 
        for (i = 0; i < 10; ++i)
        {
            time += BIT_TIME;
            // output bit and shift right (same as txd @ time <: >> byte);
            byte = xport_outshr_at_time(txd, byte, time);
        }
    }
}

/*******************************************************************************
 * Print the given character to UART. Wait if the FIFO is full.
 *
 ******************************************************************************/
void uart_putc(char c)
{
    unsigned chend;
    
    chend = xchan_alloc();
    
    if (chend)
    {
        xchan_set_dest(chend, uart_chanend);
        xchan_out(chend, c);
        xchan_outct(chend, XS1_CT_END);
        xchan_free(chend);
    }
}
The function uart_putc can be called from any thread. As you can see it allocated the channel end each time it is called. I'll have to check later what locking mechanisms are needed for the channel stuff. I'm really a XMOS novice :)

The next step will be to implement something like XC select in C. It's not simple, but I've got some ideas already.

If somebody is interested, the sources are also on the server. Just go up a few levels. But please don't use them for anything yet. The API will most probably change and it may be still buggy because I still don't have very much XMOS knowledge.

Let me know if you find mistakes or have other remarks about it.

Thomas