Spin and C interacting?
I have a robot that is controlled by the propellor chip. I have the location algorithm written in C and the movements of the robot are written in the spin language. Is it possible to call C functions in the spin language or is it necessary to write the entire program in either spin or C?
Comments
What one would do is have, for example, a Spin program running on one COG. Meanwhile a C program is being run by another COG. All communications between these two happen through a shared space in HUB RAM. Perhaps with a LONG indicating some command and a buffer to hold parameters and return values. The C code would be polling the command LONG until a valid command is set there by the Spin. The C code would then perform the work indicated by the command and write the results back to the shared HUB space.
This is basically how Spin and PASM code interacts on the Prop anyway.
This is easy to do with GCC and the Zog interpreter. No idea how easy it is with Catalina C.
That is fairly minimalist, but it is C running in two cogs.
Spin can run in another cog. So you are only using 3 cogs here. More can be added of course.
What you could do is define a parameter array in Spin. Find the location of that parameter array, and put that location right at the top of memory in $7FFC. Now you can use C to read this pointer, and get all the parameters from Spin. The parameter list could be as long as you like.
No-one has done this yet, but I think it is entirely possible, and it would be a cool hybrid system!
Yes they have. Ever since the beginning Zog has been running Spin and GCC compiled C code at the same time passing data between the two as described.
Now David and Jazzed have carried forward.
I must say, that is pretty cool! Chalk one up for Zog.
I have a utility called cspin that converts C code into Spin. I prefer writing in C, so I write code in C first and then convert it to Spin to run on the Prop. cspin has quite a few limitations, but I find it useful for me. Let me know if you want to convert your C code to Spin.
Dave
Sorry not to reply sooner. You can easily use the Catalina RESERVE_COG capability to run any SPIN function in parallel with a Catalina C program. Just put your SPIN function inside a Catalina_Reserved_Cog.spin wrapper (you'll find this wrapper in the Catalina\target directory).
Below is a working example of running a Spin function that toggles the VGA LED on the C3 at 1Hz. To compile it to run alongside a C program, I used the following command:
Here is the actual SPIN program: Note that you can pass parameters to the SPIN function on startup, or you can communicate via Hub variables (as described by Heater).
Ross.
That could open up some interesting possibilities. Can you explain a bit more how memory is allocated? I think Catalina starts from the top and works down, with the stack taking up whatever is needed.
Would Spin start from the bottom up?
Hi Dr_A,
The reason this works is that the SPIN function is started with its own dedicated stack space (the Block_Ptr parameter, which is initialied by the Catalina startup code to point to a block of BYTE_SIZE bytes). This space is allocated above (and separate to) the Catalina stack space.
I don't really care how SPIN uses this space - up down or sideways! But in fact, since you only pass a pointer to the start of it, it must use it bottom-up. And, in the words of the SPIN reference manual, this pointer ...
So make sure your BYTE_SIZE is large enough for the SPIN function (and divisible by 4)!
Oh - and be aware that this technique will only work for Catalina LMM programs (i.e. not XMM programs) - PASM programs can be easily started by a Catalina XMM program (as you are doing with your cogjects) but a bit more frigging about is required to invoke SPIN programs. This is because XMM programs normally assume they can use all of the Hub space for local variables and stack, leaving no space for SPIN code (which must reside in Hub RAM to be executed by the SPIN interpreter). If there were a demand for it I could make this work as well, but we are really getting into the realms where the total number of potential users of such functionality is in the single digits - and I'm talking binary digits here!
Ross.
The latest version of cspin is available at http://forums.parallax.com/showthread.php?119342-CSPIN-A-C-to-Spin-Converter&p=991970#post991970 . Let me know if you have any problems using it. I would be happy to do the conversion if you want to send me your C code.
Dave
Having got all the essential stuff working for the GUI (keyboard, video), I'm finding the actual coding in C is so much easier than in Spin. Never have to worry about running out of ram, it is easy to put data either in hub or external and to move it back and forth, and any time I want to do something a bit clever, I do a quick search on Google and up comes some useful C code from somewhere.
I guess I'm a convert to C now, and as such, see less need for such interaction, so no need to try to get it working in XMM for like you say, a binary number of potential users
Looks like there are already several very good solutions to this problem as posted above - kudos to all the authors involved!
Well, I'm not sure how far forward we've gotten. I have runtime code that allows a COG to be loaded from an array of C initialized data. That could just as easily have been data read from an SD card. It all works pretty well and results in an environment that is fairly easy to work with. The C startup code doesn't load any drivers at all. It relies on the C code to load them itself. One advantage on the C3 though is that the driver that handles the cache also handles the SD card so it is already loaded when the C code starts. The C code only has to load serial, keyboard, or TV/VGA drivers as needed.
Unfortunately, I'm pretty much at a dead end with ZOG. I've come to the conclusion that it can't be made to work well with data in hub memory without switching to little-endian mode and the ZPU GCC compiler doesn't really support that yet. It's not clear it will ever support that. :-(