Mixing languages C + Spin + pasm
ManAtWork
Posts: 2,176
in Propeller 2
Until now, I have written everything that has to run fast (hardware drivers) in pasm and evrything else (command interpreter, string processing) in Spin. The big performance gain of the P2 makes it possible to code more and more in highlevel language. Even control loops that have to run several 1000 times a second can be written in Spin (at least in fastspin), now.
Because C has better support for data types (struct and float) I'm currently experimenting with C. I saw that there are lots of include files in the FlexGui/include folder, some samples and documentastion in /sample and /doc. But unfortunatelly it doesn't answer all of my questions so I have to ask here.
How can I include C objects into Spin code? Declaring an OBJ doesn't work for a .c file. Do I have to use
How can I declare a DAT section in a .c file to be used as assembler code to COGNEW()? I tried __pasm{} at the global scope but I fear it doesn't do exacly what I want. It doesn't allow ORG or RES.
Because C has better support for data types (struct and float) I'm currently experimenting with C. I saw that there are lots of include files in the FlexGui/include folder, some samples and documentastion in /sample and /doc. But unfortunatelly it doesn't answer all of my questions so I have to ask here.
How can I include C objects into Spin code? Declaring an OBJ doesn't work for a .c file. Do I have to use
PUB FILE "myfile.c" myfunction(arg)for each function?
How can I declare a DAT section in a .c file to be used as assembler code to COGNEW()? I tried __pasm{} at the global scope but I fear it doesn't do exacly what I want. It doesn't allow ORG or RES.
Comments
Think I found how to do the other way and include spin in c:
struct __using("PropSerial/SmartSerial.spin2") fds;
...
fds.start(63, 62, 0, 23400);
And org and res should work in c pasm sections, if for some reason they dont thats a new bug.
The following file compiles with errors. It says "unexpected constant" in the line of the "ORG 0". If I remove the "0" the ORG seems OK but it complains "res not valid after orgh".
I think you have pasm instead of asm...
* I had to add a header file. Otherwise the including into the main (Spin) file doesn't work
* I had to convert all function idetifiers to lowercase
* I replaced RES by LONG
But it still doesn't work. Somehow the assembler thinks that my assembler code is meant to go to hub ram, not cog ram. is compiled to which is complete nonsense. The ORG is ignored. It seems that I'm doing something fundamentally wrong. __pasm{} is probably not meant for code running in a cog.
Also, I think the documentation says that Spin can be mixed case, but you have to use the lowercase in C.
If you really want the code to be in a cog, you need to do a coginit on it and start in another cog.
At least, I think so.
I think Spin2 inline assembly is in the cog...
... WOW, wait! I just moved the __pasm{} section to the beginning of the file right after the #include and #defines. And now it suddenly works, at least the compiler no longer complains.
There must be some unintended mode change when __pasm{} is placed after variable or function definitions. I'm not good at finding problems in hexdumps or .lst files. I'm not sure if it's a compiler bug or if I did something wrong.
I always get error messages like "error: unknown identifier LoadParameters used in function call". I double checked that I've included "parameters.h" and the spelling of the identifier. If I add some garbage characters after the declaration of LoadParameters() I get a different error so I'm sure that the file is really included and the declaration is not commented out. However, the compiler seems to ignore it completely.
Would be really nice if somebody could tell me what I'm doing wrong.
Just include the .h file...
Either that or build a "header file" with _IMPL statements for all of your functions. For example the libc.a that comes with fastspin is just that: it contains declarations for all of the standard C functions and a pointer to where they're implemented. You can put that libc.a on the command line, although generally it won't be necessary if you #include the appropriate header files.
Eric, I think you mentioned somewhere in the documentation that there is no real linker but as there are no explanations of the consequences I haven't drawn any conclusions about what I have to do. I thought the compiler would automatically search for a *.c file if I include the matching .h file the same way it does when I define an object in Spin.
_IMPL is not mentioned at all in C.pdf. I urgently recommend that you extend the documentation so that anyone who is familiar with a standard C compiler but new to Fastspin is able to use it without always asking you. Sorry for complaining... I don't want to steal your time. But exactly for that reason it's important to have good documentation. Especially if more users start to use Fastspin answering all that questions over and over again will be surely more work than writing a detailed documentation once.
In the long term I think the best solution would be to add some sort of "add file to project" feature to FlexGUI as it exists in many other IDEs.
So I fear FlexGUI doesn't allow projects with more than one .c file, at least not without requiring substantial changes to the code. One solution was to split the headers into one separate include file for the importing (higher level) file and one for it's own body (.c source). But that is a mess for larger projects.
Another solution is stop using FlexGUI for the compiler invokation and to manually write a makefile. I will try that next. If I can't use FlexGUI anymore I could probably take an editor that supports syntax highlighting.
What you want is "__fromfile" instead of "_IMPL".
_IMPL() is only defined if you include compiler.h, and all that does is "#define _IMPL(x) __fromfile(x)"
I have no problem adding a filename to a list (makefile) each time I add a file to a project. That does not happen very often and it requires a lot of writing anyway.
But I'd like to be able to press a single button to (re-)compile a project even if I changed the project. That should be possible to be automated somehow. I think I'm just to stupid figuring out the right MSDOS commands...
Changing the command line in FlexGUI to doesn't work because the filename arguments can't be fetched from std-input but must be present at the command line.
Changing the command line to and putting the actual command line into the batch file also doesnt work. The batch file is called but it can't do anything because W7 denies access to almost anything. I think I had to edit the access right policies but I don't know how.
I guess VS puts all the C++ files on the compile command line automatically. Or, maybe compiles and links them all. I don't actually know.
Anyway... Some type of project file may be the only clean way of doing this...
On the other hand, "__fromfile" seems like a nice workaround, once you know about it.
The documentation and error messages of fastspin certainly need a lot of work. I'm always happy to get pull requests .
In general if you're comfortable with using the command line and makefiles, then you might as well use those. There's nothing special about FlexGUI, it's just something I threw together for the benefit of people who wanted an IDE. But all of the "interesting" language and loader stuff is in fastspin and loadp2, and you can invoke those from a makefile or directly from the command line.