header problems with xcc compiler

Technical questions regarding the XTC tools and programming with XMOS.
mashc5
Member
Posts: 10
Joined: Sat May 29, 2010 6:06 am

header problems with xcc compiler

Post by mashc5 »

I'm trying to use a FAT library I found here http://www.robs-projects.com/filelib.html but I can't get it to compile in XDE. It keeps claiming that there's parse errors. I havent modified the code at all and have searched everywhere trying to find it. Could this be a problem with the xcc? Can header files contain pointer declarations and function definitions with pointer arguments? The first parse error happens at the first instance of a pointer definition, which is what made me think this might be the problem.


JohnR
Experienced Member
Posts: 93
Joined: Fri Dec 11, 2009 1:39 pm

Post by JohnR »

From page 10 in Programming XC on Xcoew XS1 devices,
XC provides many of the same capabilities as C, the main exception being the removal
of support for pointers and aliases.
Later in the same paragraph
The extensions for
passbyreference
parameters and multiplereturn
functions provide an alternative
to the use of pointers. XC’s scope and linkage rules are the same as with C and both
languages share the same preprocessor (see Chapter ??)
John
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

As John points out there are no pointers in XC, and so it will error as if it encounters a prototype using pointers in a header.

If you have a function that takes a pointer such as:

Code: Select all

void f(int *a);
Then, depending on if a is a pointer to a single element or to the start of an array, you can change it to:

Code: Select all

void f(int a[]);
or

Code: Select all

#ifdef __XC__
void f(int &a);
#else
void f(int *a);
#endif
<xccompat.h> defines a macro which allows you to write the last example as:

Code: Select all

void f(REFERENCE_PARAM(int,a));
Some C functions still won't be callable from XC however you change prototype. For example it isn't possible to call a function that returns a pointer from XC. You can prevent these functions from causing parse errors by wrapping them in:

Code: Select all

#ifndef __XC__
// function prototype here
#end
Depending on the library you may be able to write wrapper functions in C with XC friendly prototypes that allow you the indirectly use the uncallable functions.
mashc5
Member
Posts: 10
Joined: Sat May 29, 2010 6:06 am

Post by mashc5 »

Thanks everybody for your responses, I appreciate the help. After re-reading my post I realized I was extremely vague about what I was trying to do. I get that I need to write wrapper functions to call functions with pointers from xc, but what about functions called from c? Can they still have pointer arguments in the prototype? What about function pointers and structs with pointer members definded in the header file?
mashc5
Member
Posts: 10
Joined: Sat May 29, 2010 6:06 am

Post by mashc5 »

Tell me if this looks right

Code: Select all

//program.h

#ifdef __XC__
int function1(char &pntr);
#endif

#ifndef __XC__
int function1(char *pntr);

//function only called from c
char* function2(char *s_pntr);

//This is only used in c
typedef struct myStruct
{
    char *ptr1;
    myStruct *ptr;
}

#endif
Would this work? Could I call function1() from both c and xc?
JohnR
Experienced Member
Posts: 93
Joined: Fri Dec 11, 2009 1:39 pm

Post by JohnR »

#ifdef __XC__
int function1(char &pntr);
#endif

#ifndef __XC__
int function1(char *pntr);
Wouldn't you then have to implement separate code in each function one to be used in a C file, the other in an XC file.
for instance in XC
// assuming char &pntr is null-terminated
int function1(char &pntr){
int ctr = 0;
while(pntr[ctr] != NULL)


}
JohnR
Experienced Member
Posts: 93
Joined: Fri Dec 11, 2009 1:39 pm

Post by JohnR »

Sorry about that - pressed the wrong button while thinking about the code differences between C and XC.

I'll try again later.

John.
mashc5
Member
Posts: 10
Joined: Sat May 29, 2010 6:06 am

Post by mashc5 »

After some trial and error, I got it figured out and actually got the library working to the point where it will initialize the Fat file system, open files, and read. (write isn't working but i don't think it's related to the xcc compiler)

My setup looks something like this:

all of the C API prototypes look like

Code: Select all

#ifndef __XC__
int fl_blahblah(char *blah,blah....,void *file);
//or
void* fl_fopen(char *blahblah);//returns a pointer to the file structure your opening
                                           //that you later pass back in for reads and writes and such
#endif                        
I made my wrapper function prototypes look like this

Code: Select all

#ifdef __XC__ //This section makes the wrappers callable from XC
int xcfl_blahblah(char blah[],blah...,int fd);

int xcfl_fopen(char blah[]);//returns a file descriptor integer (~similar to stdio fopen())
                                    //because you can't pass a pointer back into xc
#endif
#ifndef __XC__ // This section contains the prototypes that will actually be used in c
int xcfl_blahblah(char *blah,blah...,int fd);

int xcfl_fopen(char *blah[]);
#endif
Some functions were safe to call from xc and c, but to make the xc API consistent I defined macros for them

Code: Select all

//This is not in either of the #if(n)def sections
void fl_init(void);
#define xcfl_init() fl_init()
I created a look up table of file structure pointers called fd_files and the xcfl_fopen() wrapper looks like this

Code: Select all

//fat_filelibs.c

FL_FILE fd_files[MAX_OPEN_FILES];
fd_index = 0;

int xcfl_fopen(char path*,char *modifiers)
{
    FL_FILE *file = NULL;
    if(fd_index==(MAX_OPEN_FILES-1)) return 0;

    if((file =fl_fopen(char,modifiers))==NULL)
    {
        return -1;
    }

    fd_files[fd_index] = file;
    
    fd_index++;

    return fd_index;
}

//wrapper functions for operations on the fd are like this

int xcfl_fileop(char *blah,int blah2,int fd)
{
    return fl_fileop(blah,blah2,fd_files[fd-1]);
}
Using the wrappers looks something like this (I'm using multicore, but for the example pretend im not)

Code: Select all

//main.xc

#include "fat_filelib.h"

int main(void)
{
    int fd;

    xcfl_init();
    
    if((fd = xcfl_fopen("/dir1/subdir2/file.txt","w"))<1) 
    {
        printf("ERROR: File not opened);
        return 0;
    }

    xcfl_fputs("The sea is full of stars...\n",fd);

    xcfl_shutdown();

    return 0;
}
Additionally, an globally declared pointers or struct definitions need to be enclosed with #ifndef __XC__

When I get the library working well I'll post it as a project.

Another question: Do you think it would be possible to cast a pointer as an int and pass it back to XC? I'm not an expert on the compiliation and linking process but I would think that if a pointer represents a 32-bit address I could just cast it as a 32 bit integer and send it back into XC. For my purposes it wouldn't need to be modified in XC, just passed back into the file operation functions were it could be recast into a pointer. you could even make it a const int to protect it from being changed.
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

mashc5 wrote:Another question: Do you think it would be possible to cast a pointer as an int and pass it back to XC? I'm not an expert on the compiliation and linking process but I would think that if a pointer represents a 32-bit address I could just cast it as a 32 bit integer and send it back into XC. For my purposes it wouldn't need to be modified in XC, just passed back into the file operation functions were it could be recast into a pointer. you could even make it a const int to protect it from being changed.
This should be fine. You might want to use the intptr_t type defined in <stdint.h> instead of int. This type is guaranteed to be big enough to store a pointer. The code will be more portable and, IMHO, the intent will be clearer.