Shop OBEX P1 Docs P2 Docs Learn Events
I really want a complier that can…. — Parallax Forums

I really want a complier that can….

JCeeJCee Posts: 36
edited 2011-10-24 13:14 in Propeller 1
….Read variables across objects


In a sense I want global variables that can be shared across objects running in different cogs without having to pass pointers. I find it cumbersome to pass array pointers with each object and then trying to keep track of all the offsets to get the right variable.

In my project I have a GPS receiver and I wish to parse the NMEA strings, display some info on the screen, and save some info to EEPROM.

The top object launches three new cogs each running different objects. The GPS cog updates all the variables and the other two objects just read the values. I wish there was a way to declare a global variable like Global_GPS_Lat and any other object that needed latitude information could simply use the Global_GPS_Lat variable to read the value at that time.

I realize this would be problematic if two independent objects used the same variable name like Loop_Counter, but this could be avoided by using a simple naming convention. All Global variables must begin with the “Global_” prefix. That way the compiler would know this variable is shared across objects instead of local to one object. Kinda like the way Pub and Pri methods are used, but with variables.

Any chance this concept will get some traction with the 3rd party compiler developers?!!

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-10-23 09:38
    JCee wrote:
    All Global variables must begin with the “Global_” ...
    Ugh.

    It would be better to allow an object to declare which of its variables to export. Then another object could reference them as objref.variable. But you can already do something similar now by writing accessor methods that let you read and write variables in another object without having to know their location.

    -Phil
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-10-23 09:53
    The closest you come to that with the existing compiler is by introducing an empty object which only contains constants. You'd simply have one of this per project.

    GPS_Const.spin

    Unfortunately you have to define one pub function but it can be empty.

    The constants you define are the addresses of the global variables. You simply place these variables at the end of HUB_RAM. Then you use this object in each of your objects that need access to those variables and via the object instance you have access to all these addresses.
    CON
      STR_LONG = $ff00
      STR_LAT     = $ff10
      L_LONG = $ff20
      L_LAT    = $ff24
    PUB empty
    

    With
    OBJ
      gpsConst: "GPS_Const"
    

    any object can now access these variables with:
    gps.readLongitude( gpsConst#STR_LONG )

    Another would maybe convert it to a long:
    long[ gpsConst#L_LONG ]:=convert( gpsConst#STR_LONG )

    And a third one uses the long value for calculations:
    calcSomething( long[ gpsConst#L_LONG ], long[ gpsConst#L_LAT] )

    and so on ...

    The only drawback is that the compiler can't help you when you run out of HUB-RAM. The whole empty space behind the program (including VAR, DAT, PUB, PRI and OBJ) is used as stack for the COG running the main program. So, if this stack grows to much it will overwrite your global variables.
    Maybe it makes sese to have a global variable with the lowest address to hold a magic word. Then you can detect by yourself if the stack grows to much.
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-10-23 09:54
    Your project to me seems not too complicated.
    Developing a new compiler with your wished feature will take 6-12 Months until it runs stable.
    Think of how many things you can code yourself in 6-12 months.

    What PhiPi means is to define some addtional methods like

    PUB SetMyVar1(NewValue)
    MyVar1 := NewValue


    PUB ReadMyVar1 : Value
    result := MyVar1

    Just call these methods from any place you like

    MyModifiedEEPROMObject.SetMyVar1(125)

    MylocalVar5 := MyModifiedEEPROMObject.ReadMyVar1

    etc.

    keep the questions coming
    best regards
    Stefan
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-10-23 10:11
    JCee,

    I can understand your frustration.

    I've been working (off and on) on a GPS logger. I found the GPS object very inefficient with the use of cogs.

    I was able to reduce the number of cogs it used by three but at the expense of moving most of the objects into the top object. I found having a very large top object wasn't as bad as I had expected. Since I copied the CON, VAR, and DAT sections of the objects as well as the methods, I had nice color strips indication when one section of the program ended and another began.

    I had originally planned to move most of the methods back to child objects after working out a way to let them share data but now I'm not sure if it would be worth the time and effort it would take. One big program isn't so bad.

    This is one way of sharing variables across objects, move the child object into the parent. I know, it's not really a solution but it is relatively easy.

    I use the "Summary" view a lot to navigate in large programs.

    Duane
  • jazzedjazzed Posts: 11,803
    edited 2011-10-23 10:39
    JCee wrote: »
    In a sense I want global variables that can be shared across objects running in different cogs without having to pass pointers. I find it cumbersome to pass array pointers with each object and then trying to keep track of all the offsets to get the right variable.
    ...
    Any chance this concept will get some traction with the 3rd party compiler developers?!!

    How about some traction in a Parallax product?

    Propeller-GCC can share variables between COGs via mailbox structs and/or global variables.
  • JCeeJCee Posts: 36
    edited 2011-10-23 10:50
    Thanks for all the quick feedback,

    @MagIO2 I have used objects with just constants before for pin definitions, its helpful to define all the pins in one place and have each object reference the pindef object. But having to manually define the all the variable memory locations would drive me crazy when trying to debug.

    I could deal with using objref.variable, but writing methods just to set or read a variable feels more like a work around for a task as basic as reading a var.

    @Duane I might have to break down and move everything to the top object, I liked the idea of having a simple top object but I guess having both is not an option.
  • JCeeJCee Posts: 36
    edited 2011-10-23 10:53
    @jazzed

    thats exactly what i was looking for, do you have any examples. Where can i find out more about GCC.
  • jazzedjazzed Posts: 11,803
    edited 2011-10-23 11:03
    JCee wrote: »
    @jazzed

    thats exactly what i was looking for, do you have any examples. Where can i find out more about GCC.
    It is still work in progress, but we are near a preview release.
    I'll be presenting Propeller GCC information at Parallax Meetup Group October 27th.
  • Heater.Heater. Posts: 21,230
    edited 2011-10-23 11:28
    Jazzed,
    Propeller-GCC can share variables between COGs via mailbox swork around tructs and/or global variables
    thats exactly what i was looking for...
    Well so can Spin. That's how things generally work around here.
  • jazzedjazzed Posts: 11,803
    edited 2011-10-23 15:01
    Heater. wrote: »
    Propeller-GCC can share variables between COGs via mailbox swork around tructs and/or global variables
    Seems like there is a small copy/paste problem in that "swork around tructs" :) How did work-around get in there? :)
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-10-23 15:44
    In a sense I want global variables that can be shared across objects running in different cogs without having to pass pointers

    Intriguing.

    Just to clarify, there is the concept of an "object" that may not have any pasm code at all and is pure spin. But I don't think you mean that sort as you mention cogs.

    And then there is the type of object that is pure pasm. Thinking through the way you usually do that, in the 'main' program you define a list of variables, one after the other. Then you pass the location of that list to a cog. And then generally, the first thing you do in the cog code is read those values into local cog variables.

    So what you are suggesting is instead of that, define 'Global_myvariable" in the main program, and this is available to a cog.

    In the cog I wonder if this could save some code space as you don't have to read the variables back in at the beginning. Instead, in the Global_myvariable gets added to the 'long' list at the bottom of the cog code with its value added. No, scratch that. With a pointer to its location in hub added. Then you do a rdlong to get the actual value.

    I wonder if that could save some code space. The compiler knows where in hub Global_myvariable is located. So if you happen to add that in some cog code as a long, then the compiler adds in the location for you.

    And then, you don't need the line of code in the 'main' that passes the location of that global variable. And you don't need the line of code at the beginning of the pasm code that reads it back into a local cog long.

    Mabye Spin can do this already - I'm not sure.
  • JCeeJCee Posts: 36
    edited 2011-10-24 12:40
    Yes there maybe some application for defining variables in the main program to be used by a cog running pasm. But I was thinking more along the lines of sharing varibles between two (or more) child spin objects (possibly running in separate cogs). The Global_myvariable would direct the compiler to use the same hub memory location in all other objects .
  • Mike GMike G Posts: 2,702
    edited 2011-10-24 13:14
    I've done this kind of thing before. I'll return a pointer to the starting address of a predefined memory block when the target object is started. Then I pass the pointer to any other objects that needs the variables using object.start(params). The child objects all have constructs that look like this if you're assigning value. Don't forget about memory locking.
      long[params][0] := $00
      long[params][1] := $00
      long[params][2] := $00
      long[params][3] := $00
      long[params][4] := $00
      long[params][5] := $00
    

    Replace the hard coded index with a constant.

    Isn't all HUB memory global anyway?
    http://www.parallaxsemiconductor.com/an003
Sign In or Register to comment.