Shop OBEX P1 Docs P2 Docs Learn Events
VCCv7 code samples & how to - Page 2 — Parallax Forums

VCCv7 code samples & how to

2»

Comments

  • jazzedjazzed Posts: 11,803
    edited 2009-08-27 16:15
    @Agent420, I don't think they will give you a DemoBoard to do this, since it is not an application/library for a specific hardware device they sell. It would be interesting to see your work though.


    I think talking about Spin and C differences is a good idea.

    I spent half a day in the last week fixing a Spin bug with root cause being confusion between "<=" and "=<" (my fingers automatically type <= when I think less than or equal) ... boy that made me mad mad.gif

    Nick's list is a good starting point, so items that Spin actually has in common with C will be first.

    structures?
    * Not formally of course, but the DAT section allows you to define variables like a struct.
    ' spin
    DAT ' account record
    name  byte 0 [noparse][[/noparse]40]
    lastchecknum long 0
    year word 2009
    month byte 0
    dayofweek byte 0
    balance long  0    ' use IEEE floating point for this ... can not be a millionaire at this bank :)
    // C
    typedef struct account {
      char name[noparse][[/noparse]40];
      long lastchecknum;
      short year;
      char month;
      char dayofweek;
      double balance;  ' can be millionaire at this bank, but not FDIC insured amount :)
    } ACCT_st;
    
    


    * You can not define an array of DAT "structures", but you can use pointer math to achieve the same end if the struct is "square."
    * VAR section variables are "sorted by size" by the Spin compiler, so don't try it there.
    unions?
    Includes? (together with #defines #ifdefs etc)
    * Available in bstc and homespun, but not with same c-preprocessor meanings.
    Type-defs?
    Type-checking?
    Type-aware pointers?
    ' spin
    value := long[noparse][[/noparse]ptr+n*4]
    value := word[noparse][[/noparse]ptr+n*2]
    value := byte[noparse][[/noparse]ptr+n]
    // C
    long lptr = { 0, 1, 2, 3 };
    short sptr = { 0, 1, 2, 3 };
    char string = "woot?"
    long lval = lptr[noparse][[/noparse]n]; // or *(lptr+n);
    short sval = sptr[noparse][[/noparse]n];
    char ch = string[noparse][[/noparse]n];
    ch = *(char*)((long)lptr+(long)n*sizeof(lptr)); // kind of tough
    
    


    function-pointers?
    * Not really, but there are ways to fake it.
    casting? (not that this is elegant, but it helps at low-level)
    * See "Type aware pointers"
    sizeof?
    * strsize is the only sizeof like spin method
    Macros?
    Alloc / free? (OK, not a language-element, but a must for even the most simple set of libraries).
    * Various heap managers are possible, and at least one is in the obex ... look for HEAP

    More later ... topics include: arithmetic order of operations, operators, built-in copy/move & set/fill

    If I was Parallax, I would write a book on this topic.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Steve

    Propeller Tools
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-08-27 16:59
    > structures?
    > * Not formally of course, but the DAT section allows you to define variables like a struct.

    No, sorry, that doesn't count. It relies on the sequence of elements. And SPIN mixes and rearranges them as it wants.

    > Type-aware pointers?

    No count here too. SPIN doesn't complain if types don't match. C is (or can be) much more restricting with types (mixing chars and ints and shorts). ICCV7 doesn't shine here very much regarding warnings.

    But if anybody wants to learn C, I strongly recommend:
    The book "C in a nutshell" by P. Prinz & T. Crawford; O'Reilly. Not that much a book to learn with, but a great reference that goes far behind just listing syntax.
    Not that much of a help in µC-dev. in C, but ... "The C Standard library" by P.J. Plauger. If in doubt about any library-usage, this is the reference. But a bit on the hard side to read.
    And something like PC-Lint. Might be a pain to configure, but what this piece of software detects is incredible! Some of the warnings will drive you nuts (in the beginning) but then, you'll be able to write robust code. My PC-Lint is hopelessly outdated (starting with the 5 1/4" floppies smile.gif ).

    If you want to learn C in a primitive environment on the PC (= DOS-box), Mix-C together with their debugger (each $ 19.95) is a good start. The advantage is, you don't get confused by the framework-buzz like Win or .net or whatever. Bare-bones! Not the most up-to-date compier. Includes a self-teaching book. www.mixsoftware.com


    You have to be aware of, that C is compiled and needs much more space than SPIN. So, SPIN still has its place! But beware, when the Prop II rolls out!


    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • jazzedjazzed Posts: 11,803
    edited 2009-08-27 17:11
    Nick Mueller said...
    > structures?
    > * Not formally of course, but the DAT section allows you to define variables like a struct.

    No, sorry, that doesn't count. It relies on the sequence of elements. And SPIN mixes and rearranges them as it wants.
    Nick, you are half right. DAT sections do not rearrange data. VAR sections do as I said. Still, as I qualified, it is not "struct" ....
    Your reading list is very good.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Steve

    Propeller Tools
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-08-27 17:32
    > Nick, you are half right. DAT sections do not rearrange data.

    OK, but then, do they have a name? What SPIN completely lacks of is defining own types (or own structures that do have a name). This are basic tools to make code saver and easier to maintain.
    For example, you can typedef something to be a short and later discover that you need a float. You only have to change the typedef and recompile. OK, a few pitfalls with printf ... smile.gif But can be handled too by a #define.

    typedef int fooType;  // don't forget to change fooPrint too!
    #define fooPrint "%d"
    
    ...
    fooType fooVal = 4711;
    ...
    printf("Value is " fooPrint " units\n", fooVal);
    
    



    You might even check that the #define is adjusted too with an assert (would have to try).

    or something like:
    typedef struct Point { double x, y; } Point_t;
    ...
    Point_t startPoint, endPoint;
    ...
    int MoveFromTo(Point_t start, Point_t end) {
     ...
    
    


    You can't pass wrong parameters to MoveFromTo!

    That's where C shines over SPIN.

    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO

    Post Edited (Nick Mueller) : 8/27/2009 5:38:53 PM GMT
  • jazzedjazzed Posts: 11,803
    edited 2009-08-27 17:50
    I agree with everything you said there Nick. I'm not sure what name is in question though -- variable names are easy, complete structure name is equivalent to the first variable name which is similar to the way struct address space can be referenced in C. The only way to know the sizeof() a DAT structure would be to have a an end label for a calculation.

    C data structures allow much better and simpler control than Spin (down to the packed bit if you like) which is very useful in hardware device drivers and dealing with lists of data. Spin "could" have such language elements, but the interpreter would not fit in a single 512 long Propeller COG.

    Of course Spin has organizational advantages over C, but that's another story.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Steve

    Propeller Tools
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-08-27 18:50
    > Spin "could" have such language elements, but the interpreter would not fit in a single 512 long Propeller COG.

    These are compile-time-features and have no influence on the interpreter.

    And if my comments are boring: wink.gif
    I wanted to show beginners what's the right track. You can translate a SPIN-program to C without much effort. But after that, you'll have to add the candy to make a good C-program out of it. Don't think SPIN, think C!

    Oh, there's another good reading "No Bugs!: Writing Error-free Code in C and C++ (Paperback)", Addison-Wessley; Only second-hand. (There's a similar one by Microsoft-Press. This one's Smile! They made prof of by themselves).

    I didn't invest into books like these for quite some years. So I have to make senior suggestions. smile.gif


    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • jazzedjazzed Posts: 11,803
    edited 2009-08-27 19:17
    You're probably right about compile time impact.

    For me, the right track is to follow what has been done, improve on it, and not get too involved in inconsequential differences. The problem exists in being ignorant of what is important or not.

    Learning to code is like growing up. There will be mentors and institutions that will draw you into certain systems. At some point, you may decide that everything you've been told is a lie, and reevaluate all that input especially from those whom you've judged as being fascist. That is a key stage of discovery because questioning authority allows a creative burst but the foundations received earlier allow some amount of discipline and tools to get the job done. Then, after you've become a consummate professional, you start falling into habits and wanting to help others avoid mistakes. By middle age you want to throw everything out the window. Then grandchildren come along and you say, well it's a living and smile every now and then for seemingly no reason at all [noparse]:)[/noparse]

    @Javalin, I guess some of this has really distracted from your thread. Sorry about that. Back under my rock now [noparse]:)[/noparse]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Steve

    Propeller Tools
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-08-27 19:58
    > By middle age you want to throw everything out the window

    I did that already! I only program for my personal amusement.
    I pick the platform I want, pick the project I want, the language I want and do it they way I think it is perfect. smile.gif

    > @Javalin, I guess some of this has really distracted from your thread. Sorry about that. Back under my rock now [noparse]:)[/noparse]

    I don't think so. Well you can hide wherever you want. smile.gif
    No, I think that talking about structures and safe programming is a must when learning a new language. A programming language is a tool. And I like tools (but now, I prefer those that make hot metal chips or melt metals). And as with every tool, it isn't enough to know where the power switch is, you also have to learn the do-s and dont-s. Of course every experienced lathe-operator will know how to make a tight fit. But he wouldn't have found his own way, when nobody has told him about structures and type-checking (oh, I switched context in the middle of the sentence. smile.gif )

    Just tools!
    Believe it or not, I wanted to start a carreer as an automotive engineer, but during university, I found that compilers are cheaper (compared to a mill), use less space and the only limit is your imagination. And not the fact that regrinding carbides adds costs and a good caliper costs more than a compiler. And you need maybe 10 calipers. And in programming, the supply of material is endless, when making chips, you have to buy stock.


    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • JavalinJavalin Posts: 892
    edited 2009-08-27 20:16
    part two posted... Enjoy - see what mistakes you can pickup!! wink.gif

    James
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-08-27 20:46
    > i=5;
    > if (i = 11) // "=" is an assigment operator - so i is set to 11 here.

    Naa, this assignment (every assignment) also returns what's called an lvalue. So this if-statment is always true (because it is non-zero).

    > for(i=0; i<=7; i++)
    > {
    > i++; // i is incremented again here!

    Never ever do this again!

    > // while mistake 2 - never exists as i doesn't change!!
    > i=1;
    > while (i<=10); // the ; at the end of the while loop - ends the code-loop - so the
    > // { } block never runs!
    >{
    > i+=5;
    >}

    i is changed in fact.
    Edit: Re-reading, I have to admit that I overlooked the semicolon.
    But the opening lcurly and closing rcurly gives a chance for a "neat trick"
    If you need a temporary variable that you don't want to declare at the function's beginning of the body:

    
    int fooBar() {
      int i;
      ...
      {
        int i; // this is a different i! it is "forgotten" outside of this block
        for (i = 0; ...
      }
    
    




    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO

    Post Edited (Nick Mueller) : 8/27/2009 9:30:02 PM GMT
  • WBA ConsultingWBA Consulting Posts: 2,935
    edited 2009-08-27 21:56
    This is interesting. I am actually learning SPIN for the prop while at the same time learning C for Cypress PSoC chips. The biggest difference I have noticed is this forum and the OBEX. There is a PSoC forum, but most people are using PSoC in a commercial environment and don't cater to newbies. My newbie questions go unanswered or get blunt answers. Fortunately, I have a colleague is knows C very well. It would be interesting once I learn SPIN to start converting my programs to C.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Andrew Williams
    WBA Consulting
    WBA-TH1M Sensirion SHT11 Module
  • PavelPavel Posts: 43
    edited 2009-08-27 23:06
    break and continue keywords give you extra control over the looping without modifying the loop indexes or conditionals, or using goto.

    Click here to learn more

    break terminates the loop early, say you are writing to a file and then a write error occurs (disk full for example). You should not continue the write attempts, so you need to get out of the loop right away: break does just that.

        for (iLine = 0; iLine < nLines; iLine++)
        {
            result = fprintf (f, "%d\n", data[noparse][[/noparse]iLine]);
    
            if (result < 0) /* something's wrong */
            {
                break; /* get out of here NOW */
            }
        }
    
    



    continue allows you to skip back to the top of the loop body. This is useful when you have a list of items, some of which needs more processing, some of them not. If the item does not need further processing, you just say continue and the takes you to the next iteration of the loop. For some reason, I don't use continue nearly as often as break. YMMV.

        for (iItem = 0; iItem < nItems; iItem++)
        {
            if (iItem % 2) 
            {
                continue; /* do not process items with odd indexes */
            }
    
            process (iItem); 
        }
    
    



    Regarding the while statements, there's also do {} while (); form, which always executed at least ones as the condition for looping is evaluated at the end. In my coding, I do not use it often, but it can help significantly when the logic is right for it.

    Click here to learn more

        i = 10;
        do 
        {
            i--;
        } while (i > 0);
    
    



    And regarding the branching statements, let's not forget the switch statement. The advantage of switch is that it compiles into a jump table, so there's no actual testing (the code just take a jump to precalculated address - faster). However, to allow for this, the cases must evaluate to constant integer so they are actually evaluated during compile time.

    Click here to learn more

        switch (iCase)
        {
            case 1: 
                func1 ();
                break; 
            case 2:
            case 3:
                func23 ();
                break;
            case 4:
                func4 ();
                break;
            default:
                abort ();
                break;
        }
    
    



    The break statements are necessary to stop the execution at the end of the case (otherwise it will continue through other cases). The default clause is to be executed when the switch argument matches no case and it is a good practice to always include it so you can catch invalid cases (I call abort () in the example which is guaranteed to get my attention, but obviously you can handle it in more graceful way.).

    And one more neat branching tool: the infamous ternary operator. It's kinda like a shorthand for if (condition) {x = something;} else {x = something_else;}.

    Click here to learn more

    
        x = (a == b) ? 1 : 0;
    
    
    



    If a equals b then x will be 1 otherwise it will be 0. Regarding this operator, watch the operator precedence to avoid surprises.

    Post Edited (Pavel) : 8/27/2009 11:21:36 PM GMT
Sign In or Register to comment.