Shop OBEX P1 Docs P2 Docs Learn Events
Learning C on the Prop — Parallax Forums

Learning C on the Prop

ajwardajward Posts: 1,130
edited 2013-09-27 07:10 in Learn with BlocklyProp
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

Comments

  • Hal AlbachHal Albach Posts: 747
    edited 2013-09-22 17:10
    I know little to nothing about Linux but you may want to read through the post on this (Learn) forum down a little from yours "Simple IDE Linux Question by linuxbikerider. They seem to go into quite some detail re Prop C and Linux. (Some day I'll learn how to link another forum post!)
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2013-09-22 19:09
    Hal Albach wrote: »
    (Some day I'll learn how to link another forum post!)

    Right-click on the thread/subject, select Copy Link Address, right-click Paste in the Reply field.
  • jazzedjazzed Posts: 11,803
    edited 2013-09-22 19:17
    ajward wrote: »
    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

    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.
  • ajwardajward Posts: 1,130
    edited 2013-09-23 00:23
    jazzed wrote: »
    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!!!!!!

    @
  • ajwardajward Posts: 1,130
    edited 2013-09-23 00:30
    Hal Albach wrote: »
    I know little to nothing about Linux but you may want to read through the post on this (Learn) forum down a little from yours "Simple IDE Linux Question by linuxbikerider. They seem to go into quite some detail re Prop C and Linux. (Some day I'll learn how to link another forum post!)

    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!

    @
  • jazzedjazzed Posts: 11,803
    edited 2013-09-23 09:29
    ajward wrote: »
    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!!!!!!

    @

    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.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-09-23 14:39
    jazzed wrote: »
    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.
    Seems like you should be able to run small C++ programs that use cin/cout using the XMMC memory model on the C3. It has much better performance than the XMM-SPLIT model.
  • jazzedjazzed Posts: 11,803
    edited 2013-09-23 15:01
    David Betz wrote: »
    Seems like you should be able to run small C++ programs that use cin/cout using the XMMC memory model on the C3. It has much better performance than the XMM-SPLIT model.

    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. :)
  • David BetzDavid Betz Posts: 14,516
    edited 2013-09-23 15:18
    jazzed wrote: »
    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. :)
    Ugh. I guess the C++ standard library was not designed with microcontrollers in mind. Are you working on a Simple C++ Library?
  • jazzedjazzed Posts: 11,803
    edited 2013-09-23 16:13
    David Betz wrote: »
    Ugh. I guess the C++ standard library was not designed with microcontrollers in mind. Are you working on a Simple C++ Library?

    No thanks :)

    Cody (SRLM) wrote a really nice C++ library though.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-09-23 20:29
    jazzed wrote: »
    No thanks :)

    Cody (SRLM) wrote a really nice C++ library though.
    Of course, as I think you mentioned already, it is perfectly possible to use C++ on the Propeller even in the CMM or LMM memory models as long as you stay away from the bloated C++ standard libraries. My guess is that they don't use those libraries on the Arduino either. They really weren't designed for microcontrollers.
  • SRLMSRLM Posts: 5,045
    edited 2013-09-23 23:08
    jazzed wrote: »
    No thanks :)

    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).
    David Betz wrote: »
    Of course, as I think you mentioned already, it is perfectly possible to use C++ on the Propeller even in the CMM or LMM memory models as long as you stay away from the bloated C++ standard libraries. My guess is that they don't use those libraries on the Arduino either. They really weren't designed for microcontrollers.

    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.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-09-24 09:18
    SRLM wrote: »
    I haven't tried any part of the standard library, templating, or any crazy inheritance stuff yet.
    I don't think templates themselves should cause much of a problem since they're a compile time feature. Of course, if you instantiate zillions of classes from the templates that will be another matter.
  • photomankcphotomankc Posts: 943
    edited 2013-09-27 07:10
    I've been writing C++ for the Propeller for a while now and my observations have been:

    - 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.
Sign In or Register to comment.