Shop OBEX P1 Docs P2 Docs Learn Events
Data in the DAT section of published Objects — Parallax Forums

Data in the DAT section of published Objects

parskoparsko Posts: 501
edited 2008-06-04 13:05 in Propeller 1
Hi all.

I'm working on some code that uses Rokiki's lowest level SD routines. In an effort to keep the routine "stock", I'd like to figure out a way to replace a value at the end of it in the "DAT" section. An example, specifically, is his value for:

Clockfreq long 80_000_000 'sets the time for the SD card to wait before timing out after a bad/incorrect read/write

My routine calls his routine, which COGNEW's his assembly driver into a new cog. My understanding is that once a cog is filled with the 512 (496) longs, we cannot change it.

I am guessing that I could somehow figure out where this value is in Main Ram, prior to loading the cog, and change it there. But, if I recall, this task is not so easy, especially once one has modified any code (aka, the absolute value of this in Main Ram will change with any subsequent change in code).

Again, my desire is to use his stock routine, but change a few values to suit my routines needs. I'm happy with only changing them once at the begining, or at compile time, via the use of some CONstants in my own top level routine.

Sorry, I don't have any direct code to share, but the concept should be clear.

Any thoughts?

Thanks,

-Parsko

PS - I'm pretty sure this has been discussed before, but I can't recall when/where, other than that I think it's been a long time since someone brought it up.

Comments

  • Ken PetersonKen Peterson Posts: 806
    edited 2008-06-02 17:03
    You can access Clockfreq in the DAT section as if it were a long in the VAR section. However, you need to change the value before launching the cog if you intend this value to be copied into cog memory. Once it is in the cog, it can only be changed by the cog, or by accessing it by name in hub memory and re-starting the cog.

    If the value you want to change is buried in an object written by someone else, you would need to add an accessor function to their object to change the value because it would be inaccessible otherwise.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • allanlane5allanlane5 Posts: 3,815
    edited 2008-06-02 17:04
    @Clockfreq will be the 16-bit address of the Clockfreq variable in Main Memory.
  • Ken PetersonKen Peterson Posts: 806
    edited 2008-06-02 17:08
    @allanlane5: it is not necessary to use a pointer to change the value of a location in the DAT section. This can be done in spin:

    pub changeClkfreq(newValue) 
    
      Clockfreq := newValue
    
    
    DAT
       Clockfreq   long   80_000_000
    
    
    

    Clockfreq cannot be accessed outside of the object it is in unless access is provided with a function such as the one above.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Post Edited (Ken Peterson) : 6/2/2008 5:32:48 PM GMT
  • hippyhippy Posts: 1,981
    edited 2008-06-02 18:37
    Or just add a "rdlong clockfreq,#0" as the first line of the PASM code.
  • parskoparsko Posts: 501
    edited 2008-06-02 19:16
    Hippy,

    My goal is to use Tom's stock routine. As I am using it now, I've modified it to work with my code, NON-stock. This makes it less condusive (sp?) for others should I when I decide to publish.

    Ken,

    What if there were multiple objects with the same "Clockfreq" variable in the DAT section? Would your example change them all? I will have to try that at some point. I didn't realize it was possible. Are you sure there isn't another piece of info that I need to get it to point to Clockfreq correctly?

    I've attached the specific SD assy driver for clarity of the variable I'm changing. It's line #287...

    Thanks for the replies, guys!

    -Parsko
  • AribaAriba Posts: 2,685
    edited 2008-06-02 23:14
    Parsko

    Look at the Start method of the sdspiqasm object. This method does exactly the same as you want to do for the do,di,clk and cs DAT-variables. Just add: clockfreq := clkfreq in this start method, but I think you have also to change freq and hifreq.

    You can only access this DAT variables inside the same object. So if you have multiple objects with such a clockfreq variable, all access their own. ( an exeption is to have multiple instances of the same object, then the DAT section exists only 1 time for all instances).

    But because the clockfreq is only used for a timeout in sdspiqasm, I think it's not necessary to change it, if your real clockfreq not differs much to 80MHz (for example 96MHz or 64 MHz). If you still wanna do it, then make your own sdspi object, and pack it to all the others when you publish it.

    Andy
  • parskoparsko Posts: 501
    edited 2008-06-03 04:02
    Ken, I think you're right. I just played around with it for about a half an hour, and I couldn't get it right. I'll think more about this another time...

    Thanks again for the ideas guys.

    Bedtime...

    -Parsko
  • Ken PetersonKen Peterson Posts: 806
    edited 2008-06-03 13:35
    Another thing you can do is provide an access function that will pass out the address of a variable.

    
    PUB getClockFreqPtr
        return @Clockfreq
    
    DAT
        Clockfreq   long   80_000_000
    
    
    



    Then to change it do the following: LONG[noparse][[/noparse]object.getClockFreqPtr] := 64_000_000

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • parskoparsko Posts: 501
    edited 2008-06-03 14:36
    Wait, what?!?!

    Does that suggest modifying the others (Rokiki's SD routine's) code?

    I had come to a conclusion that I can simply add one public object within his code that will do everything I'd want, and be easy to spot, should one want to reverse engineer it. Save it as something unique, as I have done so far.

    Even though it seems clear that it can't happen, I still think (stubbornly) that it can. Like I said, it will likely involve changing the value in Main Ram prior to loading the cog. Now, I just need to figure out a dynamic way to change this value without digging through code after every compile.

    I'm still a bit confused about your code, specifically where (which objects) the three different lines of code reside. Care to elaborate?

    -Luke

    PS - I knew I should have last night, and I'm kicking myself in the tush for not, uploaded the sample I had...
  • allanlane5allanlane5 Posts: 3,815
    edited 2008-06-03 18:19
    Now, *I* thought the ONLY way to pass such parameters to the Propeller Assembly code was through the "PAR" register. Which you set in the COGNEW call which copies the assembly to a COG.

    Then, in the assembly, you can use the contents of the PAR register to access information in "Main Memory". I wasn't aware you could embed SPIN VAR values in Assembly code. Even if you did, you'd want to embed @Clockfreq -- because "Clockfreq" would get you 80 Meg -- and there IS no location 80 Meg. @Clockfreq would get you the 32 bit location in Main Memory which CONTAINED "Clockfreq" -- which I thought is what you wanted to manipulate.
  • parskoparsko Posts: 501
    edited 2008-06-03 20:17
    Allan,

    You're on the same wavelength as me, I think. Yes, Clockfreq, located in a separate object from my Main object, is the value I would like to manipulate. I would like to manipulate this value once, to set it to something else, say 80_000_000/250, THEN start the separate object into a new cog.

    Yes, you are absolutely correct that the only way to send data to an Assembly object running in it's own cog is to use the PAR register, and/or with a pointer inside the Assembly cog.

    But, I'm trying to change a value without changing the routine itself. Meaning, I want the Assembly Cog's routine (in this case, sdspiqasm.spin) to be the same, prior to compile time, as it would be as if you just downloaded it from the Object Exchange. Not that it matters, but the "IP" would be maintained. It's akin to using Chips OEM TV_text driver, but changing the value (for instance, from NTSC to PAL) without changing the original code to some new "saved as" file on one's local hard-drive.

    There is a location in Main Ram where this value (clockfreq) is located. We should be able to rewrite this value, if we knew where it was. Finding it once isn't particularly difficult. But, if you are changing code regularly, then you'd have to find it over and over again, because it's location will change every time new code is written (and the values absolute location changes).

    It's not so much of an embedding of SPIN VAR values in Assembly code, I'm just trying to rewrite the value of clockfreq, post compile, with a little subroutine in the Main Startup sequence, then load. Also, the original value will always be maintained in the EEPROM.

    -parsko
  • Ken PetersonKen Peterson Posts: 806
    edited 2008-06-03 21:09
    @parsko: What you are dealing with is a concept called "data encapsulation". When someone writes an object with a variable in it, the namespace containing that variable only applies to code within that object. There is no way to access it unless whoever created the object provides explicit access to it through a PUB function (see my examples above for two ways of providing such access). This prevents users of your objects from mucking around with the inner workings of them.

    In both cases, my example code would have to be added to the object which contains the variable you want to change. You apparently have two options: Either get Rokiki to release a new revision of the SD object with the added function, or maintain your own "tainted" copy.

    A side note:

    Using PAR is not the only way to get data to a cog. Whenever you launch a cog with PASM code, it copies 496 longs from the DAT section in HUB memory to the cog memory, including all variables in the DAT section within that space. Before you launch the cog, you can access those variables in SPIN by name to set up parameters (like pointers) for the cog. After you launch the cog, the PASM code only works with the local copy of those variables and can no longer see any changes made to hub copy of those variables.

    What I usually do is set up variables in VAR, create pointers to those variables in DAT, then launch the cog - taking the pointers into cog memory along with the code. Then the PASM code in the cog can access the variables in hub memory via the pointers.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Post Edited (Ken Peterson) : 6/3/2008 9:14:58 PM GMT
  • parskoparsko Posts: 501
    edited 2008-06-04 03:05
    Ken Peterson said...
    What I usually do is set up variables in VAR, create pointers to those variables in DAT, then launch the cog - taking the pointers into cog memory along with the code. Then the PASM code in the cog can access the variables in hub memory via the pointers.
    Clever. Never thought about doing that. I think that might come in handy sometime!

    Otherwise, very clear. I believe you. I have no intentions of asking Tom to release new code. I'll keep my own tainted version, but likely add my own PUB routine at the top for clarity. In general, I've kept his code OEM, other than a few bits.
    Ken said...
    Before you launch the cog, you can access those variables in SPIN by name to set up parameters (like pointers) for the cog. After you launch the cog, the PASM code only works with the local copy of those variables and can no longer see any changes made to hub copy of those variables.
    Where I have been confused (and stubborn about) is that I keep thinking that access to the variables in a DAT section are accessible by all public routines compiled. What you have made clear is that this access is ONLY explicit to the object with which it resides. Access to variable in a DAT section are NOT accessible by all public routines compiled.

    Again, thanks to both you and Allen for your thoughts.

    -parsko
  • Ken PetersonKen Peterson Posts: 806
    edited 2008-06-04 13:05
    As is probably evident, you CAN access the variable if you know the address. The problem is accessing it by name (whereby you obtain that address). I am not aware of any means to do that outside of an object. If someone has discovered a hack that lets one do this, it would be nice if they run across this thread.

    One thing that's different between DAT and VAR is that variables in DAT exist only once in a program.· All instances of an object share the same values in the DAT section.· However, each instance of an object has its own VAR section.· I have a copy of the TV object that I modified to put all of the variables in the DAT section so I can share the same display among several objects in a program.· I would only need to call the start function once.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Post Edited (Ken Peterson) : 6/4/2008 1:14:45 PM GMT
Sign In or Register to comment.