Shop OBEX P1 Docs P2 Docs Learn Events
A proposal to develop a standard for communicating with cogs from any language! — Parallax Forums

A proposal to develop a standard for communicating with cogs from any language!

RossHRossH Posts: 5,512
edited 2012-05-31 21:06 in Propeller 1
All,

Over in the thread about new drivers for C/C++, the discussion has moved to the idea of developing a standard interface to allow high level languages like Spin, C, Forth or BASIC (whether interpreted or LMM-based) to interact with code running in cogs. This could be driver code or library code (such as the various floating point librarys).

I think this is a good idea, and is something that has been missing from the Propeller for far too long, leading everyone (including me) to come up with their own solution.

Catalina uses the concept of a registry, which is 8 longs in a fixed high Hub RAM location which allows you to specify what programs are loaded in each cog, and point to a communication block which the cog will monitor and use to accept commands (including configuration commands, or requests to perform a function) and return results. Synchronization and handshaking are built in, but multi-cog access must be added over the top.

Catalina calls cog programs plugins, and the Catalina Registry/plugin mechanism is described in the attached document. This is just to kick off discussions - I'm not proposing this as the final solution. It does work quite well, but may not be ideal for all types of drivers/programs. If anyone has any ideas about a better solution, please post them here and we'll see if we can come up with a new scheme that everyone can use.

Ross.
«13456710

Comments

  • RossHRossH Posts: 5,512
    edited 2011-12-02 18:13
    reserved for updates.
  • jazzedjazzed Posts: 11,803
    edited 2011-12-02 18:25
    You expect that your registry and mailbox methods would be required?
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-12-02 18:35
    Well I'm going to don my flameproof suit and wade right in. Having translated many spin/pasm objects to a split C and pasm object, I don't think you have a standard such as "8 longs". Every object seems different. Some only need one long. Some, like TV drivers, might require almost all the hub to be reserved as a buffer.

    I think the best solution is Chip's solution. You pass n longs, which have to be in the same order and which may include variables and arrays. These are the only variables that can be shared between the cog and the higher level language, but you can have as many or as few as you want.
  • RossHRossH Posts: 5,512
    edited 2011-12-02 18:36
    jazzed wrote: »
    You expect that your registry and mailbox methods would be required?

    What?

    Ross.
  • RossHRossH Posts: 5,512
    edited 2011-12-02 18:43
    Dr_Acula wrote: »
    Well I'm going to don my flameproof suit and wade right in. Having translated many spin/pasm objects to a split C and pasm object, I don't think you have a standard such as "8 longs". Every object seems different. Some only need one long. Some, like TV drivers, might require almost all the hub to be reserved as a buffer.
    Perhaps I didn't explain it well enough - the 8 longs are for 8 cogs - one long per cog. This long contains the type of program loaded (upper 8 bits) and a pointer to the actual communication block used to communicate with the cog (lower 24 bits).
    Dr_Acula wrote: »
    I think the best solution is Chip's solution. You pass n longs, which have to be in the same order and which may include variables and arrays. These are the only variables that can be shared between the cog and the higher level language, but you can have as many or as few as you want.
    Chip's solution is very low level - it generally needs to have stuff build on top of it to be useful, which is why some drivers have chosen to use different techniques. It also provides no means for programs to identify what program is loaded in what cog. A slightly higher-level solution would provide this (and other capabilities) at very little additional cost.

    Ross.
  • jazzedjazzed Posts: 11,803
    edited 2011-12-02 18:44
    RossH wrote: »
    What?

    Ross.
    So what part of your .pdf should I be reading? Your registry and mailbox solutions are referenced on many pages.
  • RossHRossH Posts: 5,512
    edited 2011-12-02 18:52
    jazzed wrote: »
    So what part of your .pdf should I be reading? Your registry and mailbox solutions are referenced on many pages.

    Start with the registry stuff on page 6 - the rest of the document describes how a typical plugin would be written to use it.

    Ross.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-12-02 18:53
    As an inveterate PASM programmer and Spin proponent, I can't, for the life of me, understand why Spin/PASM objects cannot be used in situ by C programs without translation. After all, Spin byte-code programs are nothing more than data for just another PASM program (i.e. interpreter). And if GCC can't accommodate such a PASM program/data structure, I have to wonder what the he!! good it is. It seems that Parallax is poised to reinvent their entire treasury of legacy Spin/PASM code, and to what end? Has the C cartel completely taken over the hearts and minds of Parallax, demanding that everything C be exclusively C? What am I missing here?

    I could have posted this in the other thread, but I really don't want to antagonize Chris, since he's one of the Good Guys. :)

    -Phil
  • jazzedjazzed Posts: 11,803
    edited 2011-12-02 18:57
    As an inveterate PASM programmer and Spin proponent, I can't, for the life of me, understand why Spin/PASM objects cannot be used in situ by C programs without translation. After all, Spin byte-code programs are nothing more than data for just another PASM program (i.e. interpreter). And if GCC can't accommodate such a PASM program/data structure, I have to wonder what the he!! good it is. It seems that Parallax is poised to reinvent their entire treasury of legacy Spin/PASM code, and to what end? Has the C cartel completely taken over the hearts and minds of Parallax, demanding that everything C be exclusively C? What am I missing here?

    -Phil
    GCC accommodates PASM. I asked Parallax if they want it to support SPIN. The answer was no.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-12-02 19:03
    jazzed wrote:
    I asked Parallax if they want it to support SPIN. The answer was no.
    That's very disappointing and can only lead to additional expense, redundant effort, and a forking of the Propeller object library. It makes no sense whatsoever.

    -Phil
  • RossHRossH Posts: 5,512
    edited 2011-12-02 19:09
    As an inveterate PASM programmer and Spin proponent, I can't, for the life of me, understand why Spin/PASM objects cannot be used in situ by C programs without translation. After all, Spin byte-code programs are nothing more than data for just another PASM program (i.e. interpreter). And if GCC can't accommodate such a PASM program/data structure, I have to wonder what the he!! good it is. It seems that Parallax is poised to reinvent their entire treasury of legacy Spin/PASM code, and to what end? Has the C cartel completely taken over the hearts and minds of Parallax, demanding that everything C be exclusively C? What am I missing here?

    -Phil

    Hi Phil - Spin/PASM programs can be used "in situ" by other languages provided the other language makes special (and somewhat complex) provisions for the Spin program data areas and stack space (I believe Catalina and Zog can both do this, but this is precisely the bit that Heater describes as "yucky!"). Spin was never designed with interoperability in mind, and so (for example) Spin programs cannot use C stack space and vice-versa. Spin also has no mechanism for sharing symbol information with other languages, which makes things very difficult!

    But this thread is not really about general purpose intregation of Spin with other programs, it is specifically about integrating cog programs (generally written in PASM) with other languages. However, in the world of Spin it is often the case that some functionality is implemented in Spin - but that's because the program was originally expected to be used only from Spin. In many cases that Spin code can simply be "stripped off" and replaced with equivalent C code. This is the approach I first took with Catalina, but even so there was still a demand to be able to use Spin programs unmodified - so now I support that as well. But it is still difficult to interact with such programs, which is what this thread is really about - if there was a common mechanism to interact that was independent of the language used, it would make life easier for everyone.

    Ross.
  • RossHRossH Posts: 5,512
    edited 2011-12-02 19:13
    jazzed wrote: »
    GCC accommodates PASM. I asked Parallax if they want it to support SPIN. The answer was no.

    Slightly off-topic, but does Parallax intend to support Spin on the Prop 2 at all? Originally they said they did, but my feeling is they may have changed their minds.

    Ross.
  • jazzedjazzed Posts: 11,803
    edited 2011-12-02 19:14
    RossH wrote: »
    Start with the registry stuff on page 6 - the rest of the document describes how a typical plugin would be written to use it.

    Ross.
    What you have is not unreasonable. At least you're specifying a pointer to the mailbox data structure. That's really as far as a standard needs to go except for requiring the driver to publish it's usage. Did you have anything else in mind?
  • jazzedjazzed Posts: 11,803
    edited 2011-12-02 19:20
    RossH wrote: »
    Slightly off-topic, but does Parallax intend to support Spin on the Prop 2 at all? Originally they said they did, but my feeling is they may have changed their minds.

    Ross.
    I'm not sure why this question comes up. At root Propeller is a SPIN/PASM "Chip." I've never heard of any intention to not support SPIN/PASM on Propeller 2.

    Parallax wants to ensure that anyone from K-12 to University curricula/programs, hobbyists, and large scale commercial enterprises can use their products.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-12-02 19:38
    jazzed wrote:
    I've never heard of any intention to not support SPIN/PASM on Propeller 2.
    We haven't heard much about it. Any idea where that supporting effort is coming from?

    -Phil
  • jazzedjazzed Posts: 11,803
    edited 2011-12-02 19:43
    We haven't heard much about it. Any idea where that supporting effort is coming from?

    -Phil
    Yes, but I won't give a name since it may produce unnecessary stress on an already over-worked person.
  • RossHRossH Posts: 5,512
    edited 2011-12-02 19:45
    jazzed wrote: »
    What you have is not unreasonable. At least you're specifying a pointer to the mailbox data structure. That's really as far as a standard needs to go except for requiring the driver to publish it's usage. Did you have anything else in mind?

    I'm open to suggestions, but I find that most things can be built on top of this simple structure fairly easily. Adding a few "conventions", like the one you mention - i.e. publishing a list of standard driver types - is also required. Perhaps specifying a standard "initialization" command would be useful? Also "fixing" the location of the registry in Hub RAM - e.g. always use the last 8 longs?.

    Another thing missing at this level is synchronization across multiple cogs - I currently add that over the top (e.g. by using a lock around specific driver accesses - but perhaps there is a simpler mechanism we could use? One problem is knowing which lock to use, so one idea I have had since I developed this in the first place is to use a few of the extra registry bits to specify which lock is allocated to which cog - we don't need all 24 bits as address (even on the Prop 2 hub addresses will only need 18 bits) - so we could use 3 of the spare bits to specify that a specific lock has been allocated to this cog - I didn't want to just assume that lock 3 (for example) would always be allocated for use with cog 3. But perhaps this would add too much complexity?

    Ross.
  • RossHRossH Posts: 5,512
    edited 2011-12-02 19:49
    jazzed wrote: »
    I'm not sure why this question comes up. At root Propeller is a SPIN/PASM "Chip."
    The Prop 1 is indeed a Spin/PASM chip, since it has the Spin interpreter "built in". But my understanding is that the Prop 2 will not, so it is now no different from any other multi-core chip in that respect. Also, we have heard a little (but not really much technical detail) about how PASM will be modified for the Prop 2, but absolutely nothing about how Spin will be modified - and yet Spin is what most people will use first, and it will also need a makeover!

    Ross.
  • jazzedjazzed Posts: 11,803
    edited 2011-12-02 20:12
    RossH wrote: »
    I'm open to suggestions, but I find that most things can be built on top of this simple structure fairly easily. Adding a few "conventions", like the one you mention - i.e. publishing a list of standard driver types - is also required. Perhaps specifying a standard "initialization" command would be useful? Also "fixing" the location of the registry in Hub RAM - e.g. always use the last 8 longs?.

    Another thing missing at this level is synchronization across multiple cogs - I currently add that over the top (e.g. by using a lock around specific driver accesses - but perhaps there is a simpler mechanism we could use? One problem is knowing which lock to use, so one idea I have had since I developed this in the first place is to use a few of the extra registry bits to specify which lock is allocated to which cog - we don't need all 24 bits as address (even on the Prop 2 hub addresses will only need 18 bits) - so we could use 3 of the spare bits to specify that a specific lock has been allocated to this cog - I didn't want to just assume that lock 3 (for example) would always be allocated for use with cog 3. But perhaps this would add too much complexity?

    Ross.

    Having a driver "publish it's usage" means the API is well defined. In C we have header files where we can define structs for I/O.
    I suppose classifying a driver is not a bad idea, but to me that's just another part of the API. I wouldn't want to be restricted by some intermediary.

    Locks can be passed in the mailbox struct. Is it a requirement? Maybe, but again that should be defined in the API.

    I will never agree to fixing the start address of an 8 long registry or any mailbox. That is an implementation detail.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-12-02 20:14
    jazzed wrote:
    We haven't heard much about it. Any idea where that supporting effort is coming from?

    -Phil
    Yes, but I won't give a name since it may produce unnecessary stress on an already over-worked person.
    The over-worked part is certainly a cause for concern. While I would never want to add to another's stress level, this news makes me wonder whether the Spin2 effort needs a review. The worst possible scenario for my enthusiasm for the Prop2 would be that it be launched with a C compiler and nothing else to support it. That would be the road to oblivion for the Prop 2, IMO.

    -Phil
  • jazzedjazzed Posts: 11,803
    edited 2011-12-02 20:19
    The over-worked part is certainly a cause for concern.
    Name one person at Parallax that is not over-worked !
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-12-02 20:28
    jazzed wrote:
    Name one person at Parallax that is not over-worked !
    Point taken. Not to make light of it, but perhaps a cause for even bigger concern? :)

    -Phil
  • RossHRossH Posts: 5,512
    edited 2011-12-02 21:30
    jazzed wrote: »
    Having a driver "publish it's usage" means the API is well defined. In C we have header files where we can define structs for I/O.
    The difficult bit is figuring out how do this in a language independent way, which does not involve so much complexity, or consume so many resources (or time!) that people simply don't do it.
    jazzed wrote: »
    I suppose classifying a driver is not a bad idea, but to me that's just another part of the API. I wouldn't want to be restricted by some intermediary.
    What intermediary do you mean?
    jazzed wrote: »
    Locks can be passed in the mailbox struct. Is it a requirement? Maybe, but again that should be defined in the API.
    Same argument as above - if you make the "basic" set of operations that every driver must implement too big or too complex, people simply won't use them. In this case, it would cost nothing to reserve three bits in the registry long of each cog, but this would allow an applications to store the number of the lock that should be used to coordinate access to the cog (we would have to reserve a value - e.g. zero - to mean no lock has been allocated, or else we would need 4 bits).
    jazzed wrote: »
    I will never agree to fixing the start address of an 8 long registry or any mailbox. That is an implementation detail.
    I agree, which is why I don't do it - the Catalina registry can be anywhere in memory, and I have in fact moved it several times as I found more things I had to store in hub RAM.. However, this does cause problems since there is currently no way to pass the address of the registry between programs compiled and linked separately. At the moment, all Catalina programs are linked together to generate the final binary, so this is not a problem. The same would be true of GCC.

    Perhaps someone can think of a clever mechanism for passing such fixed information between separately compiled processes?

    Ross.
  • RavenkallenRavenkallen Posts: 1,057
    edited 2011-12-02 22:07
    I was also wondering about any details relating to the SPIN language for the Propeller 2. There have not seemed to be any talk about this at all. It is still the primary language that i use for my applications(Even though i am trying to learn some PASM). Should this question be posed on a separate thread?
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-12-02 22:19
    Catalina uses the concept of a registry, which is 8 longs in a fixed high Hub RAM location which allows you to specify what programs are loaded in each cog, and point to a communication block which the cog will monitor and use to accept commands

    I've been thinking about this some more. I think we are in more agreement than I initially thought.

    My big ask in any communications protocol is that all the communication longs are grouped together. I don't really care what those longs are or whether they are arrays or longs or even how many there are. I just feel that if they are grouped together then it makes code a lot more portable between languages, and it also greatly decreases the risk of code overwriting variables and introducing strange bugs, and it means that the cog pasm code can be compiled at another time (you can even distribute precompiled cog binaries on an SD card eg mouse.cog, keyboard.cog, display.cog).

    Now what you are saying (I think) is that you have a registry that points to each of these blocks.

    For Catalina, use it as it is. For backwards compatability with existing obex code, I think that could be changed fairly easily. Define your registry in spin as an 8 long array. Then instead of passing the location of a block with PAR, pass the location of the registry.

    Hmm - and the cog number?

    One problem - what if your obex code fills the cog with only one or two longs free? (not uncommon!). You are going to need an extra long or two for the code that reads the registry location, adds the cognumber and then extracts the pointer to the data block.

    So just to check, in the cog code, you extract par which instead of pointing to the comms data block, it points to the registry which then points to the comms data block. And for the higher level code, you some code to work out where the comms data block is, and then incorporate this into the long that goes in the registry (with lock bits and other things?).
  • RossHRossH Posts: 5,512
    edited 2011-12-02 22:22
    I was also wondering about any details relating to the SPIN language for the Propeller 2. There have not seemed to be any talk about this at all. It is still the primary language that i use for my applications(Even though i am trying to learn some PASM). Should this question be posed on a separate thread?

    Yes, I'm certainly interested - but I'd encourage you to raise this in a separate thread. Even though I prefer C, Spin offers the easiest and best way for most users to take advantage of the unique capabilities of the Propeller - i.e. the ability to use multiple cores as "soft" periperals, or to do parallel processing. Without Spin, the Propeller is no match for the cheaper and/or faster alternatives.

    Ross.
  • potatoheadpotatohead Posts: 10,261
    edited 2011-12-02 22:23
    Spin is going to be Chip's domain. Back when we discussed it, he decided to extend SPIN for the Prop II. I suspect we will hear a lot more about SPIN when Prop II is solidified enough to warrant getting SPIN done.

    What would sync primitives look like?
  • RossHRossH Posts: 5,512
    edited 2011-12-02 22:37
    Dr_Acula wrote: »
    Now what you are saying (I think) is that you have a registry that points to each of these blocks.
    Correct. It is up to you to define the block to suit your own needs - although (as I describe in the attached document) a block of 2 consecutive longs is so universally useful that I have never found a need for anything else, so I allocate one automatically (this saves every cog the need to do so themselves). The block size and usage is determined by the type of plugin you tell the registry you are - this tells others how to use your block.
    Dr_Acula wrote: »
    For Catalina, use it as it is. For backwards compatability with existing obex code, I think that could be changed fairly easily. Define your registry in spin as an 8 long array. Then instead of passing the location of a block with PAR, pass the location of the registry.
    I'd certainly like to see that - it would make my life so much easer!
    Dr_Acula wrote: »
    Hmm - and the cog number?
    In Catalina you don't need the cog number - you search the registry for the cog containing the plugin type you want. Once you have found it, you can then access it by cog number (for speed) - but I generally don't bother doing that. It's fully supported by the kernel, though (invoking a plugin is built into the kernel, so the user effort it is a simple PASM jmp #SYSP instruction).
    Dr_Acula wrote: »
    One problem - what if your obex code fills the cog with only one or two longs free? (not uncommon!). You are going to need an extra long or two for the code that reads the registry location, adds the cognumber and then extracts the pointer to the data block.
    Yes, this is a problem - sometimes there is not enough code space left in a cog to do the necessary registration etc, so I do part of it from C (or Spin) when I start the cog. This is one reason it is necessary to keep the overhad of using the mechanism as small as possible.
    Dr_Acula wrote: »
    So just to check, in the cog code, you extract par which instead of pointing to the comms data block, it points to the registry which then points to the comms data block. And for the higher level code, you some code to work out where the comms data block is, and then incorporate this into the long that goes in the registry (with lock bits and other things?).
    Yes, that's a fair summary. In the higher level code you can call a function to return you the registry address, or another to search the registry to find the plugin you need and just return you a pointer to the comms block. Interacting with the comms block is usually done via a set of C functions written specifically for that plugin - these functions know how to correctly interpret and interact with that type of comms block.

    Ross.
  • RossHRossH Posts: 5,512
    edited 2011-12-02 22:41
    potatohead wrote: »
    Spin is going to be Chip's domain. Back when we discussed it, he decided to extend SPIN for the Prop II. I suspect we will hear a lot more about SPIN when Prop II is solidified enough to warrant getting SPIN done.
    Good to know.
    potatohead wrote: »
    What would sync primitives look like?
    The one I use is the simplest possible - a hub lock. I just use the lock as a semaphore (which is really all a lock is) - i.e. you have to get a successful "lock" before you access the comms block for the plugin. You unlock it when you are finished to indicate someone else can use it.

    Ross.
  • jazzedjazzed Posts: 11,803
    edited 2011-12-02 22:56
    RossH wrote: »
    However, this does cause problems since there is currently no way to pass the address of the registry between programs compiled and linked separately. At the moment, all Catalina programs are linked together to generate the final binary, so this is not a problem. The same would be true of GCC.
    I would not be against having a single 16 bit word point to the address of a registry. Thing is it is not really necessary to do this at all unless you want to reload programs. While I can see advantages in some situations like an O/S, not everyone wants to do that.
Sign In or Register to comment.