Data in the DAT section of published Objects
parsko
Posts: 501
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.
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
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.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
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
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
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
Thanks again for the ideas guys.
Bedtime...
-Parsko
Then to change it do the following: LONG[noparse][[/noparse]object.getClockFreqPtr] := 64_000_000
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
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...
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.
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
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
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.
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
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