Shop OBEX P1 Docs P2 Docs Learn Events
New in Propeller.... — Parallax Forums

New in Propeller....

jmspaggijmspaggi Posts: 629
edited 2010-04-11 19:49 in Propeller 1
Hi all,

I'm looking at the Propeller because Javelin, best chip ever made, will be discontinued [noparse]:([/noparse]

I already have a "fully loaded Javelin chip" [noparse];)[/noparse] (Bluetooth, LCD, keyboard, 256 KByte extension, SHT11,. DS1302, DS1620x6, Light sensor, etc.) which is doing all I need at home, and I don't think I will re-do everything with a new language.

I'm now looking at the Propeller because it look like there will be an opportunity to run some java code in it! Great.

But why not playing also with PASM since I will have a Propeller? Maybe have one to run my Java code, and another one to run some new Prop projects?

I went through the entire documentation (RTFM) and I now have few questions. Is not the forum the best place for that? [noparse];)[/noparse] So here they are...

1) Is it possible to have only PASM on the propeller? Like, unload the Spin Interpreter? Spin Interpreter is loaded on Cog 0. Can I overwrite it by loading my own code in Cog0? Or is Cog 0 reserved for the Spin Interpreter.

2) On Figure 1-3 page 25, what will happen if cog 1 try to access the hub at hub clock? Can he read/write? Or it's lock by cog0 for another 7 clocks?

3) What memory can a cog use/load? Is it only 512 x 32 bits? How can we access the remaining 32K? Using the hub and RDLONG like methods? Does it mean I need to load piece of code in a cog, run it, when it's over, load the next piece of code from main memory, run it, and so on?

4) Here is an hello world application in Javelin.
public class HelloWorld { 
  public static void main() {
    System.out.println("Hello World"); 
  } 
}



As you can see, it's very simple. Load the application using the IDE, and you will see the result in the console. How can I do the same with the Propeller?

5) What's the Propeller Chip Speed? Default seems to be 5 Mhz, but can go up to 128 Mhz? (Page 20)

6) Does a Propeller simulator exist? I found that on google http://sourceforge.net/projects/gear-emu/ is it working?

7) On page 82 from the documentation v1.1, regarding the memory used by a piece of PASM code, where 496 is coming from?

I know, I'm asking a lot, but it's brand new for me. I have a lot to learn. So thanks for your help.

JM

Comments

  • KyeKye Posts: 2,200
    edited 2010-04-10 02:30
    1: Each cog can only run PASM code. That said, the spin interpreter is just PASM that is called for you to inititally run your code. So, yes you can overwrite it with something else. Each cog can be dynamically loaded and stopped.

    2: Each cog gets acess to the hub every 7 - 22 clocks. This means that when programing in PASM any hub operations you use will take a variable amount of time to execute waiting for the hub to come arround and service the cog. The hub locks are simply memory elements that can be read and written at the same time. This allows them to be used to prevent two processors from every getting into race conditions when acessing shared memory arrarys.

    3: The 512x32 bits each cog has is what it executes instructions from. So, it can only hold that amount. Don't believe this is a major problem. You should only write code that needs high preformance to run natively on each cog. Otherwise you should you the spin interpreter or something else to execute code from the main memory for you.

    4:
    CON
       
      _clkmode = xtal1 + pll16x                             ' Crystal and PLL settings.
      _xinfreq = 5_000_000                                  ' 5 MHz crystal (5 MHz x 16 = 80 MHz).
     
    OBJ
      pst    : "Parallax Serial Terminal"                   ' Serial communication object
     
    PUB go | value 
                                     
      pst.Start(115200) ' Start the Parallax Serial Terminal cog  
     
      pst.Str(String("Hello World", 13, 10))                          ' Heading
      repeat                                                                        ' Main loop
    

    5: 80Mhz (5Mhz crystal * 16xPLL) - 20 MIPS per core * 8 = 160 MIPS

    6:·Yes, many. Another forum member should post about that stuff.

    7: The last 16 registers are special purpose registers. Like the IN, DIR, and OUT registers.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • jmspaggijmspaggi Posts: 629
    edited 2010-04-10 13:54
    Thanks a lot for your reply. It helps me to understand the propeller better. Now 1, 5 6 and 7 are clear for me.

    I still need few clarification for some of the points above [noparse];)[/noparse]

    2) This one is still not clear for me. I will start another thread just for this one to not overload this one...

    3) Is the spin interpreter natively using multeple cogs when he can? Or if I do a spin application, it will entirely run in one cog unless a use CogNew for some specify parts?

    4) Is there a way go get the PASM code of this example?

    Thanks again,

    JM
  • JRetSapDoogJRetSapDoog Posts: 954
    edited 2010-04-10 22:26
    Hi, JM. I'm basically a newbie, but let me have at your last versions of questions 3 and 4.

    Q3: The SPIN interpreter won't automatically try to optimize or delegate things by running code in more than one cog. It will, as you said, run entirely using one cog (cog 0 by default) unless some part of the code makes a call to CogNew to launch a new cog for other code. The seven remaining cogs will be idle and in a low-power mode. For this simple case, the code, which·would be·all SPIN code, is really all located in hub RAM. But the SPIN interpreter program, which is PASM code, has been automatically loaded into cog 0. It is this SPIN interpreter that continually fetches your SPIN code (which was converted into bytecodes upon compilation, similarly to what is done with Java) an instruction at a time. So, even though cog 0 can only handle 512-16=496 longs of PASM code (the SPIN interpreter in this case), your SPIN code in the hub can occupy as much of the hub memory as you want (the SPIN interpreter itself coming from ROM). With SPIN code, it's important to realize that such SPIN code is never converted en masse to be run by the interpreter; it is fetched piece-by-piece. That is, the SPIN code is not loaded in full into a cog. The Propeller MPU hardware doesn't know how to execute SPIN code without the SPIN interpreter converting it to PASM on the fly for on the fly execution (that is, the SPIN interpreter likely immediately causes the PASM to execute upon conversion from bytecode).

    Consider the example of TV_Text_Demo which uses TV_Text which uses TV. TV_Text_Demo creates one instance of TV_Text, which in turn creates one instance of TV. That's three different files, each one representing a type of object, similar to a class. Only one top-level object is possible (the compiler won't let an object create copies of itself, calling that an "illegal circular reference"), but one object may create (instanciate) multiple instances of another object (or objects). You could, for example, modify TV_Text_Demo to create two instances of TV_Text (which would in turn create two instances of TV) and display independent content on two televisions. At any rate, how do these three objects breakdown in terms of cogs? TV_Text_Demo and TV_Text are all SPIN code, and neither one calls CogNew to launch either a new SPIN interpreter or to run PASM code. So, those are both executed piece-by-piece by the SPIN interpreter resident in cog 0. And what about TV? Well, it's a combination of SPIN code and PASM code, though more PASM than SPIN. And, if you're going to run PASM code, as far as makes sense to me, you've got to load it into a new cog because there's no room for it in the cog with the SPIN interpreter (as it's chocked full to the max with interpreter code), and, you need to give it hardware resources as the cog running the SPIN interpreter pretty much has its hands full (is busy with) running SPIN code, even if just executing a do-nothing repeat (unless the SPIN interpreter recognizes a do-nothing repeat and just shuts down to save power). But back to our one instance of TV (TV.spin), its SPIN portion will also be executed by the single SPIN interpreter in cog 0 just like all the code of TV_Text_Demo and TV_Text, again, because nothing has told the Propeller to fire up a new cog on that SPIN code. By the way, TV's SPIN code consists of just two methods that are called only on demand, neither of which loop, so the SPIN interpreteter quickly executes them when they are called and then goes on with other things. TV_Text has a few loops, but no infinite loops, and so is also called on demand as needed. The top-level TV_Text_Demo, on the other hand, concludes with an infinite loop to cause a count to be displayed on the screen (though it does so with the support of TV_Text and, indirectly, TV via another cog). So, you see, the SPIN interpreter in this case is tasked with continually executing the final infinite loop of TV_Text_Demo and the calls it makes to TV_Text for the count, and it does so as fast as it can. Meanwhile, another cog is busy generating the actual TV signal, as described next.

    The "middle" object in this three-object scenario, TV_Text, not only creates an instance of TV but it also makes a call to TV's start method. And there in TV's start method, my friend (as they say), is the only place among any of these three programs that you will find a CogNew instruction (I checked, although, in a sense, a kind of CogNew instruction is automatically called for us to run the SPIN interpreter that kicks off our "top-level" program). Anyway, this lone CogNew instruction in TV's start method is used to fire up a new cog to run the PASM code that continually handles TV signal generation. A stop method is also available, but probably isn't often called (i.e., once you start a TV display, you probably won't stop it, except for when you stop the entire program). So, to recap, for this instance of the TV object, it's two SPIN methods, start and stop, will be handled by the SPIN interpreter in cog 0 if the TV's parent object, TV_Text, calls them. But as for the speedy PASM code for TV signal generation, that is handled separately by a dedicated cog (cog 1 in this case). The cog for TV signal generation doesn't handle any other code, only the TV signal generation PASM code. Let me conclude this section by just adding that it's possible to also launch a new cog for SPIN code, not just for PASM code. I'm embarrassed to say that I haven't directly done that yet as far as I recall (just for short PASM programs) as I'm still in my Propeller infancy period (yes, and so probably shouldn't be offering guidance...but we learn by attempting to do so). But keep in mind that if you launch a new cog for SPIN code, you're not loading the SPIN code into a cog. What you're doing is firing up another instance of the SPIN interpreter, which will fetch your SPIN code from hub piece-by-piece (in bytecode form) as interpreters are wont (accustomed) to do. You could fire up 8 total instances of the SPIN interpreter if desired. On the flipside, you can shut down all SPIN interpreters, only running PASM code. But, at least in the beginning, you need one SPIN interpreter to get everything rolling, for as the manual says, a Propeller program at least comprises some SPIN code (at least temporarily).

    I've said all this because, upon first dealing with the Propeller, it was at least a bit tricky to figure out how the code for various objects was executed. It took a while to understand that SPIN code could be as large as I wanted it (within the limitaion of hub memory, that is) and that it could be spread across multiple files (objects). Sorry for all the details, but I prefer to err on the side of too much information. Also, I've quite possibly--almost undoubtedly made some mistakes or mis-statements in the above, so perhaps someone will correct me and I'll be further enlightened.

    Q4: If you're looking for PASM code for Kye's version of your Java program, I think that's going to be difficult to come by. As mentioned above, a SPIN program will be converted into byte code. There is a way to inspect the bytecode using some "outside" tool, I believe, but I don't know how to do that. Anyway, I don't think you mean the bytecode. As for the PASM code that represents the SPIN code, that sounds difficult. As mentioned, your SPIN code isn't stored in cog memory and it isn't converted to PASM equivalents all in one fell swoop (though the bytecode version is finalized). It's interpreted (from bytecode) piece-by-piece, and the process of that interpretation for one SPIN statement (though perhaps split into multiple bytecodes) could take dozens of PASM instructions executed by the SPIN interpreter. Yes, some SPIN instructions have very close equivalents in PASM, but a PASM version of the SPIN code never exists in entirity at any one time. Nevertheless, for all I know, there might be some "third-party" tool (or whatever) that could give one a PASM version that would be functionally equivalent to the SPIN code. That would essentially be compiled code, then, wouldn't it. But even if such is available, that's not how it would be run by the SPIN interpreter. The SPIN interpreter will have the "overhead" of translating the bytecode into PASM, which is the reason that it runs basically 40 times slower than native PASM code running in a cog without a SPIN interpreter. Maybe I'm not clear on what you want. About the closest thing to HelloWorld other than what Kye has provided would be to fire up the three programs I mentioned above, TV_Text_Demo, TV_Text and TV, and modify TV_Text_Demo to output just "Hello, World." But that wouldn't be PASM, except for the part of the TV code. You're HelloWorld Java program is a high-level language code program, so it's kind of hard to give a meaningful PASM version of that, even though it eventually boils down to all SPIN code (when it's all said and done, or being done). But for certain SPIN routines, yes, you can give basically equivalent versions in PASM. But your HelloWorld program involves very complicated I/O, so that's probably not going to be a very meaningful/useful equivalent.

    Anyway, hope some of this helps (at least more than it hurts). It's helped my own understanding in thinking through this to offer a response. Good luck. --Jim

    Post Edited (JRetSapDoog) : 4/10/2010 10:36:22 PM GMT

  • localrogerlocalroger Posts: 3,452
    edited 2010-04-10 22:49
    JM, if I may jump in... it helps a bit to think about the philosophy of the Propeller.

    The 8 cogs are very fast, very powerful 32-bit CPUs with extremely limited memory (512 longs each). The memory limitation means that the instruction set can be very rich though; it's kind of hard to explain why unless you're familiar with other assembly languages. Since cogs only have to deal with a 9-bit address space in PASM it's possible to put the instruction opcode, several flags, and source and destination addresses in a single PASM instruction. That kind of economy is impossible in CPUs like the x86 that have to deal with large address spaces.

    Cogs were designed to do certain things you normally need hardware for, in software -- things like serial port UARTs, generating VGA or NTSC video, and so on. Cogs are very fast and with deterministic timing they can do a lot of things that normally take dedicated hardware.

    What cogs aren't designed to do is to run what is usually called the "business logic" of an application.

    So, if you understand cogs as these little limited but very efficient computers, the Hub and Hub RAM is a shared resource and the way business logic gets run is that a cog runs the Spin interpreter, which is itself written in PASM. But the Spin interpreter's job is to read your Spin code, as it's been compiled by the proptool and loaded into Hub RAM, and do the stuff it says to do. Spin bytecode runs a lot slower than PASM but it also saves a lot of space since its codes are smaller and can call for a richer array of actions (like multiply!). And there's 32Kbytes of Hub RAM, a lot more than the 2K each cog has of personal cog RAM. It can take awhile for any particular cog to read Hub RAM though because each cog only has access to the Hub 1/8 of the time. They have to wait their turn.

    So Spin is much slower than PASM because it's drawn from this shared wait-state laden RAM and interpreted, which means a lot of PASM code has to run to figure out what each Spin instruction means to do; most folks figure it's about 50 times slower than PASM. But business logic is what humans interact with and we don't run at 80 MHz, so Spin is fast enough to do a lot of useful stuff, and if you need more speed or separate threads you can run Spin code in more than one cog too, by running more copies of the Spin interpreter. That's why there are two versions of "cognew." One starts a PASM image, but the other starts another Spin interpreter running Spin code (that's the one that needs a stack).

    And this is all very, very different from any other computer I've ever worked with, so just as I did if you have experience with some other platform you kind of have to unmoor yourself from that and let yourself settle into the Prop workspace, which is extremely limiting in some ways but extremely powerful in others, and managing to do things hardly anything else ever available can do in the process.
  • potatoheadpotatohead Posts: 10,261
    edited 2010-04-10 23:32
    I'll second most of that.

    My "spin" on the speed of SPIN is a bit different. Frankly, I think it's rather fast, given it's on chip and interpreted. I clocked it against a 1.7Mhz 6502 and ~1.8 Mhz 6809, and it's in striking range, with the '09 notably faster, but SPIN is on par with the '02.

    Given what PASM does, and how the COGs work together, it's very powerful overall, and the user has a lot of very interesting choices that are not in scope on other MCUs. LMM (where native assembly instructions are fetched by a supervisor kernel running as a PASM program in a COG) adds to that mix, bringing a happy middle ground too.

    Honestly, having those various modes of operation makes the thing as fun as it is capable.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Wiki: Share the coolness!
    8x8 color 80 Column NTSC Text Object
    Safety Tip: Life is as good as YOU think it is!
  • localrogerlocalroger Posts: 3,452
    edited 2010-04-10 23:38
    potatohead, I agree Spin isn't all that slow, it just looks that way when you're comparing it to PASM.
  • jazzedjazzed Posts: 11,803
    edited 2010-04-11 16:30
    jmspaggi said...
    4) Here is an hello world application in Javelin.
    public class HelloWorld { 
      public static void main() {
        System.out.println("Hello World"); 
      } 
    }
    
    


    As you can see, it's very simple. Load the application using the IDE, and you will see the result in the console. How can I do the same with the Propeller?

    5) What's the Propeller Chip Speed? Default seems to be 5 Mhz, but can go up to 128 Mhz? (Page 20)

    6) Does a Propeller simulator exist? I found that on google http://sourceforge.net/projects/gear-emu/ is it working?

    4. The most common hello world example with a serial port would be something like this:

    con                                                              
      _clkmode = xtal1 + pll16x     ' use with a 5MHz crystal
      _xinfreq = 5_000_000
      '_clkmode = xtal1 + pll8x     ' use with a 10MHz crystal
      '_xinfreq = 10_000_000
    obj
    ' FullDuplexSerial is included in every propeller tool release and has flexible parameters
      sx : "FullDuplexSerial"       ' encapsulate the serial port
    pub main
      sx.start(31,30,0,115200)      ' 31 is RX, 30 is TX, 0 is normal mode, 115200 is baud, N18 is port config
      waitcnt(clkfreq+cnt)          ' wait a second for user to start terminal
      sx.str(string("Hello World",$d))' since chars and strings both use "", the string symbol differentiates them
      repeat                        ' stop processor
    
    


    A 2 line code change makes the same output on TV/VGA for simple text drivers.

    5. The Propeller per cog speed can be 80MHz with a 5MHz or 10Mhz crystal and 12MHz without a crystal RCFAST mode (RCSLOW mode is also available). Others over-clock the Propeller: typical over-clock speeds are 96MHz and 100MHz. All of these speeds are the speeds that the cogs run PASM. Most PASM instructions take 4 clock cycles, so each cog can run at 20MIPS (at 80MHz cog clock rate) so with all 8 cogs combined Propeller can run at 160 MIPS (or higher with over-clocking). Spin performs like a glacier compared to PASM, but is smaller and one entire interpreter fits in one cog with a few longs to spare (lots spaghetti there, but a useful example for learning some tricks). You can have 8 Spin interpreters running at the same time if you're careful.

    6. The GEAR simulator is for PASM only; I never understood it enough to bother. A good simulator for Propeller like in AVR Studio would be most welcome. PASM is very different from any other modern assembly language, but it is fun to learn/use.

    Note that while Spin has an object structure, it does not offer inheritance and polymorphism. Still, Spin code reuse is very handy.

    EDIT: Fixed syntax error in hello world example.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    May the road rise to meet you; may the sun shine on your back.
    May you create something useful, even if it's just a hack.

    Post Edited (jazzed) : 4/11/2010 5:26:51 PM GMT
  • potatoheadpotatohead Posts: 10,261
    edited 2010-04-11 16:48
    Gear will do SPIN. I use it, from time to time, to test out something when I don't have a Prop handy. It will actually render video displays most of the time. For learning about the prop, doing pin I/O, understanding what happens in PASM, and for running SPIN programs, it's a pretty great tool. It's not all that fast, but fast enough to learn on.

    It can run the graphics_demo, rendering a frame of video every minute or so. Breakpoints have been added, making it useful for troubleshooting as well.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Wiki: Share the coolness!
    8x8 color 80 Column NTSC Text Object
    Safety Tip: Life is as good as YOU think it is!
  • jazzedjazzed Posts: 11,803
    edited 2010-04-11 17:04
    If you know SPIN byte codes, then you can understand what gear is doing with them [noparse]:)[/noparse] Otherwise, it is meaningless for SPIN.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    May the road rise to meet you; may the sun shine on your back.
    May you create something useful, even if it's just a hack.
  • potatoheadpotatohead Posts: 10,261
    edited 2010-04-11 17:25
    Well ok. We will have to agree to disagree.

    It really isn't all that hard to associate some variables to known memory locations and watch the output to see what is going on. Secondly, seeing SPIN in terms of the byte codes is useful to know what really happens when a given SPIN statement is compiled. I found GEAR quite useful in that regard.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Wiki: Share the coolness!
    8x8 color 80 Column NTSC Text Object
    Safety Tip: Life is as good as YOU think it is!
  • jazzedjazzed Posts: 11,803
    edited 2010-04-11 17:30
    potatohead said...
    Well ok. We will have to agree to disagree.

    It really isn't all that hard to associate some variables to known memory locations and watch the output to see what is going on. Secondly, seeing SPIN in terms of the byte codes is useful to know what really happens when a given SPIN statement is compiled. I found GEAR quite useful in that regard.
    Used in combination with Brad's BSTC list files (or homespun list files), one may find some workable utility in it.
    Still, it is an opportunity for improvement much like finding ways for advancing past punch-card programming [noparse]:)[/noparse]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    May the road rise to meet you; may the sun shine on your back.
    May you create something useful, even if it's just a hack.
  • potatoheadpotatohead Posts: 10,261
    edited 2010-04-11 19:13
    I much prefer to focus on what a tool can do, instead of what it cannot.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Wiki: Share the coolness!
    8x8 color 80 Column NTSC Text Object
    Safety Tip: Life is as good as YOU think it is!
  • jazzedjazzed Posts: 11,803
    edited 2010-04-11 19:34
    potatohead said...
    I much prefer to focus on what a tool can do, instead of what it cannot.
    Well, at least a new user may now know what not to expect.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    May the road rise to meet you; may the sun shine on your back.
    May you create something useful, even if it's just a hack.
  • potatoheadpotatohead Posts: 10,261
    edited 2010-04-11 19:49
    ...and of course, what to expect [noparse]:)[/noparse]

    Being a new user, they may well find ways of working that are quite different from those who are experienced and come with different expectations. That's the point of it on my posts. There isn't one size fits all on tools.

    Cheers.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Wiki: Share the coolness!
    8x8 color 80 Column NTSC Text Object
    Safety Tip: Life is as good as YOU think it is!
Sign In or Register to comment.