Converting Spin/PASM Object
JonnyMac
Posts: 9,195
Like many, I have lots of Propeller objects written in Spin with a PASM driver and work like to learn how to convert this code to C. Is there guidance somewhere that I'm missing? Or... if one of you gurus wants to coach me (we can do that offline) I can write up a tutorial (perhaps even put in into my N&V column) to help others.
For clarification, I'd like to keep my PASM code intact. What I want to learn to do is convert the Spin to C in such a way I can use it in C projects as I use the object in Spin projects today.
For clarification, I'd like to keep my PASM code intact. What I want to learn to do is convert the Spin to C in such a way I can use it in C projects as I use the object in Spin projects today.
Comments
We haven't created a detailed instruction guide on this yet, but it's pretty simple.
I just posted a keyboard example that takes Chip's Keyboard.spin and uses the PASM for the program.
Basically all you have to do in the SimpleIDE is add the .spin file to the project and cognew
the pasm with a special symbol. The symbol name will be binary_<yourspinfilename>_dat_start.
The IDE will compile your .spin file to a .dat file and convert it to a GCC .o (object) file for compile/link.
Look at the keyboard.c keybd_start function for an example of how to start the PASM COG.
These are the steps using the SimpleIDE to add a PASM based project:
- Close all SimpleIDE editor tabs for starting a new project.
- Click New button.
- Create a main demo module with a main program function in the untitled tab.
- Save As SomeDemo.c
- Ensure that SomeDemo.c is the only file in the editor tabs.
- Click on "Set Project" or press F4 - SomeDemo.side appears on the left.
- Right click on SomeDemo.c or SomeCode.c and add your spin program file.
For projects not using SimpleIDE, there is a Makefile in the toggle demos you can use for reference.Of course the toggle/pasm_toggle demo is also in the SimpleIDE demos.
You are welcome to contact me via PM to setup a chat if you need more help.
I'm available off and on today.
Thanks,
--Steve
Jon
This got me wondering: does an automatic Spin-to-C translator exist? I know there is at least one C-to-Spin translator (the one use in generating the fsrw.spin FAT object in the exchange), but I wonder if anybody has created the opposite translator yet?
Still being tested but it's a start.
There are some examples in the propgcc demos folder of C wrappers that have been written to go around some of the classic .spin PASM objects (TV, VGA) and jazzed posted a wrapper for the keyboard object here -> http://forums.parallax.com/showthread.php?138032-Keyboard-driver
My next challenge will be to convert my PASM driver for PCD8544-controlled LCDs -- will post separately for guidance on that.
The code that I wrote followed Steve's model for the keyboard driver. We would usually have just one keyboard attached but I might want to have multiple blinker outputs. This is easy in Spin by defining separate objects using the blinkers.spin code. What structural changes do I need to make to blinker.h and blinker.c to accomplish the same thing?
Your blinker project looks pretty good so far. I'd like to recommend one change though as highlighted below. We need to add "volatile" to PASM cog control structures so that the optimizer does not remove code that interacts with the structure variable.
I'll look at suggestions for the multiple blinker structural changes later this afternoon.
Jon,
The easiest thing to do would be to add an array of structs. That is:
BTW, I see you have your struct type set to volatile, so ignore my previous post.
Maybe i should just go and learn C on the computer and then worry about learning how to apply it to the prop...
Hi sevs. They are a good questions. The blinker.c and blinker_demo.c files are normal c files that are passed to the compiler. The compiler knows that blinker_demo.c is the main program file because it contains the function "int main(void) ....". File blinker.h is just an "interface" file that defines some constants and "function signature" information - a function signature is something like "int getPin(int number);".
SIDE is handling the details of blinker.spin since it is included in the project. It automatically creates a blinker_firmware.o base based on blinker.spin - firmware is another name for PASM. You can have multiple .spin files with PASM in them. The variable name for the start of PASM will be binary_filename_dat_start - with "filename" as in filename.spin .
Hope this helps.
Thanks,
--Steve
I will have a look tomorrow if i cant sleep (nightshift atm). Unfortunately my laptop doesnt quite have enough oomph to run a VM machine.
Will keep reading tonight to try and understand.
PS Is that a screenshot of an up and coming linux version of SIDE?
Yes, it's one version.
We're testing the new features today and tomorrow.
We're building Linux, Mac, and Windows.
Hopefully we can package all of them soon.
Thanks,
--Steve
Is there an instruction guide for this - I think I get the hang of it but not quite.
Where you say "add the .spin file" - how do you add a file? (dumb question I know...)
And I presume the spin file is mostly pasm with the bare minimum of spin to get it to compile - ie something you could feed into the proptool and it would produce a binary?
And I also presume that all variables are being passed in a list with the start at PAR - ie the standard way the mouse and keyboard objects work?
Does the simple IDE have tabs so you can flick back and forth between the C program and the pasm part?
Or as an alternative, is it possible to include the c and pasm as one single text file program like the proptool does with spin and pasm?
It's something that I can/will document and tutorialize if nothing currently exists but it could take a day or two. I'm having issues at my day job (they want me to spend time on THEIR projects!!).
re
How could they?!
OK, Dr. A, here is a quick and dirty set of steps that can hopefully get you going in your usual "over productive" manner. (I mean that in a good and jealous way!! )
The keyboard example which Steve linked to in post #2 of this thread is a great place to start. It's a good example of a PASM driver that has the SPIN PUB functions in the same file and properly passes data back and forth. Once you write the C wrappers (.c and .h files) for a properly written SPIN/PASM driver, you have a 3 file package that can be used by both C and SPIN.
Here are the steps I went through some may be extra, just to get a feel for using SimpleIDE
0) install SimpleIDE and unzip the keyboard.zip files into a folder (you'll need them later)
1) Start up SimpleIDE
2) create a new project - I called mine kbd-test. This created a directory: 'kbd-test', containing a project file: 'kbd-test.side', and a main C template: 'kbd-test.c'
3) add .c and .h files from the keyboard folder to your project - since these files alread exist, you can do it in one of two ways.
If you right click on your main.c file in SimpleIDE, you get a menu with a number of selections.
- "Add File Copy" will add a file to your project's file list *AND* copy it to your project directory,
- "Add File Link" will add the file to your project's file list *BUT* leaves the file where it is.
I chose to add, just to keep the package files together in my new directory.3a) For your SPIN/PASM conversion, you would be writing the .c and .h files to provide the wrapper functions to your PASM code to replace the SPIN PUB methods, so you would most likely start with empty files and create your code. You would then add these to the project in a similar manner.
4) Adding the .SPIN file containing the SPIN/PASM code - WARNING, THERE STILL APPEARS TO BE THE UTF-16/UTF-8 problem with SimpleIDE and Propeller Tool - Last I knew (and what I saw this morning), SimpleIDE can't handle the UTF-16 encoded files that the Propeller Tool uses and creates. No big deal, CUT/PASTE is your friend, here.
***IMPORTANT*** The filename you use is VERY IMPORTANT to linking the PASM and C together. In you .c wrapper file, you will create something looking like this:
the external label will always be binary_filename_dat_start where filename must match EXACTLY to the filename you used for filename.spin
5) At this point, if you've written your .c an .h wrappers and added some test code using those wrapper functions to your main.c program, you should be able to start building and testing.
If you have followed along with the keyboard example, you should be able to build it and load it and see the keyboard demo work.
I hope this is enough to keep you going. If the UTF-8/UTF-16 situation has changed with the recent editor changes, I'm sure Steve will let us know.
Let me know what does and doesn't work so I can make the final tutorial for this correct.
Happy Coding!!
I'm off to Budget land!! :frown:
Haha!! There kind of is now!!
Actually, not a dumb question. This used to be non-intuitive but now with the changes that have bene made and the documentation for SimpleIDE, Steve has created, it's a piece of cake. You DID read the SimpleIDE User's Guide, right??
SimpleIDE uses BSTC to compile the .spin files, so it needs to be at least enough SPIN/PASM for BSTC to process it and create valid output files. In the case of the keyboard example, the entire keyboard.spin file from the Prop Tool library is imported SPIN Pub methods, DAT section containing PASM and anything else in there.
Yes, it makes things work together much more friendly. It should be a global object standard and coding practice.
Yes!!!! It's wonderful and the editor environment is fast and friendly. You can flip form tab to tab and you can even edit the .spin file (except for now, it uses .C highlighting but that's OK, your should see forth .f files when editors think .f means FORTRAN!!)
No, No and NO!! Please keep your c code and SPIN/PASM code separate. You can do some inline assembler with PropGCC (I think) but not what you want/need to do to interface objects. I think the 3 file package (*.spin, *.c and *.h) is really the way to go for portable objects. Include a demo.c and demo.spin and you've got a nice little bundle of code to share.
--Steve
Just here to serve and protect!
So re
So what I might have is a simple Spin program and it contains a file "Main.Spin" and it has some pasm in it and maybe it references an object or two as well. You could call that a "Project"? And you might keep it in a folder, and when you distribute it, zip up all the files into one distribution.
For C, the concept is similar, you have a "Project" but all the pasm part is a separate file.
You could actually take the concept from C and port it back into Spin, and keep all the pasm as separate files. Then the pasm part would be the same file for GCC and for Spin, and indeed for other languages as well.
re passing a list with a par at the beginning
I agree. I guess that brings up the issue of "selling" that concept. It isn't that "thou shalt do it this way", but rather, that this is the only way that makes it possible to use the same pasm code in multiple languages.
Thanks for the writeup. Is there a demo project for this.
Re
Well since you asked, no...
What I have done though is written my own IDE for Catalina and so I've confronted many of these issues along the way. One thing I added (mainly for my own benefit) is a few "New" buttons that created these simple demo projects/files. So you could click "New Pasm" and a super simple pasm-in-c would come up (which passed a value to pasm, added 1 to it, and passed it back). My inline pasm was a bit messy and your way of having it as a separate file is better.
So I need to port the same demo into GCC and split up the code into several small files.
Interesting. Sounds like it is not clear what a "project" is.
Parallax people had a problem understanding project too. They thought the project manager was merely a list of files. Well, it is a list of files, but that's what gets compiled - not the so called "top file". Hemingway could be the "top file" in SimpleIDE and the project manager will compile everything else - if you add Hemingway to the project, things might get interesting though
SimpleIDE project manager also contains project attributes such as compiler type, board type, etc.... It's not just a list of files.
In SimpleIDE a "project" is defined by the "project manager" which happens to include C/C++ files and Spin/PASM files. In the case where the Compiler is C/C++ (the only case for now), Spin/PASM files do not themselves define a project but are just part of a SimpleIDE C/C++ project. You could include other spin files for constants and such if you like, but that's it.
As far as a Spin project containing C files, well it is possible for Spin project to contain COG C files that could be used to generate PASM, but the spin compiler won't do anything with that unless you include it's output in a Spin dat file directive.
Any help?
Thanks,
--Steve
As for a demo of C program using a Gold Standard SPIN/PASM object, the keyboard demo Steve put together is very good. The keyboard object has a good interface, passes values back and forth, the SPIN interface methods make sense and the C wrapper is easy to understand. It is in the thread that is linked to from message #2 of this thread.
Dr. A, I'll take your feedback into consideration for the tutorial.
Steve, it sound like you can lead a Spin coder to projects but you can't make them link! We'll have to intensify the training methods!!
I just read the manual - *now* it all makes sense!
It is a new way of thinking. And better too because you don't need to be copying files between folders. It can all be done within SIDE with links etc. I like it!