Learning C on the Prop
ajward
Posts: 1,130
I'm just getting into C on the Prop and have gone through some of the example programs. Tried to compile some source code I wrote for G++ on my Linux box and it compiles okay, but it doesn't run... or at least doesn't run the way I intended (no output to the terminal).
Not asking for a diagnostic... not yet anyhow. Just wondering what "gotchas" to look out for when porting code?
Thanks for any wisdom!
Amanda Ward
Not asking for a diagnostic... not yet anyhow. Just wondering what "gotchas" to look out for when porting code?
Thanks for any wisdom!
Amanda Ward
Comments
Right-click on the thread/subject, select Copy Link Address, right-click Paste in the Reply field.
Hi Amanda.
The biggest potential gotcha with C++ can be code size. That being said, there are examples around of Propeller running Arduino C++ code (ya, that's what it is). Martin_H has ported lots of Arduino code (video).
Generally speaking, any std:: namespace library calls should be avoided (I.E. cin and cout). It's also best to avoid using new. Any class can be declared as a local object and shared as a global if necessary.
Also, using printf with float/double presents some interesting issues. 1) the math library must be linked, and 2) printf (and/or scanf) will suck all available memory. To get around that issue we have created microcontroller sized functions like print (which is similar to printf), scan (similar to scanf), and other items like putLine, putDec, putBin, etc... The print function starts at around 6KB, but never grows beyond that ... and you don't need to link the math library just to print PI for example.
Ah-ha... namespace library calls, the code was rife with them. 'Tis a simple text based, 5 function calculator... maybe 50 lines of code, but with cin's and cout's all over the place. Actually, I would have been somewhat surprised if it had worked, but I had to try... I'm like that! ;-)
Many thanks!!!!!!
@
Hi Hal!
Not running on the Linux box just yet. SimpleIDE runs on my iMac and I have a couple of netbooks for those times when you have to have Winderz.
Thanks for your reply!
@
Glad that helps.
Typically a std namespace propeller-gcc program size will start at about 500KB.
The Tiny library was created to make things like that fit, but there are gotchas with it.
I've run such code on a C3 with XMM-SPLIT memory model. I don't recommend it though.
A C++ Javascript interpreter mentioned by Heater will run on C3, but it is very slow.
Not enough RAM available ... I've tried. Maybe a smaller cache would help.
I'm trying to suggest solutions that have an icicle's chance in Phoenix for survival.
No thanks
Cody (SRLM) wrote a really nice C++ library though.
Thanks! I'm still waiting to release it (one of the contributors had doubts, and we're still working that out).
My non-scientific experiments with C++ shows that the typical overhead of "classifying" a set of functions and variables is somewhere between 4 and 100 bytes. "C with classes" isn't an issue, it's "C++ with 15 years of additional features" where problems start to arise. I tried to get exceptions working but every trick I tried was too big on a 10 line program. I haven't tried any part of the standard library, templating, or any crazy inheritance stuff yet.
- Don't use heap (new/delete) at all. The moment that goes into your code the size explodes all over. I have read some techniques to overload those with much smaller versions but in general you may be barking up the wrong tree with lots of dynamic objects anyway.
- As mentioned, don't use the std:: library, don't try to use the STL library either. Those containers and serialization items are neat for PC apps but your not stuffing that into 32KB.
- I like sensible default constructors that create an object that while it may not be ready to operate, it will not do anything harmful if used prematurely until the point it's been fully initialized by a method. I often create methods for objects expected to live in arrays that allow separate initialization so the arrays can be created on the stack without needing the horrible initializer syntax of C++.
- Try hiding copy constructors in the private or protected side of the class. This forces you to prevent automatic copies being created where they shouldn't be.
- Use references as much as possible and sensible to avoid duplicating objects that you do want to allow copies of in some cases.
- I declare most objects on the global scope if they are intended to live the whole application time anyway. Pass references to those global objects to other objects that need to work with them.
- No pure virtual methods. That seems to cause code size explosion as well. I do make some class trees but I live with the fact that it would be technically possible to instantiate a class that is not intended to be, just got to be careful. I use the convention ISomeClass for those classes. The "I" denotes "Interface" so it's clear that it's not a working class.
- Starting new cogs from within an object member function needs a bit of thought. I often create a global function or set of them that does whatever parallel work is needed for the object in that objects ".cpp" file. That global function is called from a member using cogstart(). I pass the needed object instance variables as a pointer to a structure for the cogstart() function's "par" parameter. I don't think right now you can pass a method to cogstart() that belongs to an object instance because cogstart() is C code and can't deal with the notion of 'this->'. I think it was suggested that a static object method might work but I have never tried that.
You can start to do more of the no-no items above if you go to XMMC model, but that has serious implications for your use of the other cogs and slows you down so evaluate that carefully. Right now I find CMM is required for must any sizable application anyway so speed may not be as much of a factor using flash enabled Propeller boards.
You'll have to get used to breaking a few pillars of the OOP faith to work in the tiny little memory space of LMM/CMM with C++. I think those blasphemies are worth it to make up for some of the things missing in SPIN's objects like passing object references to other functions and objects and creating compiler-enforced interfaces to those objects. I often make my programs very hybrid. There is a lot of procedural code that is not wrapped in objects, but things that translate well to that concept get object-ized. Sensors, devices, containers of things, records, ect.
I'll be real interested to see what SRLM comes up with. I have ported a couple of things over from Arduino-land for use in the propeller like "String" and a couple other utility type things but simpletools has eliminated a great-deal of that need for me these days. I just need someone to make an SPI library to handle the various SPI modes and I'd be golden.
Hope that helps! I'm a poor programmer but I manage a few neat tricks with the Propeller. And I appreciate being able to work in C/C++ on them rather than SPIN even if it limits my program size a bit more.