Shop OBEX P1 Docs P2 Docs Learn Events
Use of eeprom above 32K — Parallax Forums

Use of eeprom above 32K

4x5n4x5n Posts: 745
edited 2011-10-31 09:09 in Propeller 1
I'm looking into the possibility of utilizing the 64K of eeprom space on my propeller boards by storing among other things pasm routines in the space above 32K and "paging" the routines into hub memory as needed. My question is how do I determine the length and address of a pasm routine is? I've worked out moving the routines into the eeprom from my pc and how to read the eeprom and store it into hub memory. This is the last piece of the puzzle I have to work out. Does anyone know of a source of information on how to do this. I've read posts here about people doing exactly this type of thing.

Comments

  • jazzedjazzed Posts: 11,803
    edited 2011-10-29 23:16
    You can create a normal SPIN/PASM program with the top object containing all the PASM and save it into the upper 32K. The top object's first DAT section can keep a zero terminated table of pointers to the PASM code. You could calculate the size of each PASM section from the table of pointers. Assuming one object and one method, the first DAT section will live at offset $18.

    There are other ways ....
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-10-30 03:01
    Have a look at my blog, part 4.

    I used a slot approach which is of course wasting memory if the PASM does not use the full 2k, but on the other hand it's easy to implement. Each slot is 2kB in size and of course you can easily calculate the start address of each one (2k*n). One slot is reserved for storing name and version information of the rest of the slots. My planning is to store system relevant drivers there, which make the system run and communicate with the user. Other PASM parts can also be stored on SD-card.

    Of course the slots can also be filled with data instead.
  • Mike GreenMike Green Posts: 23,101
    edited 2011-10-30 07:55
    Usually people put a label on the first long of their PASM routine (call it "first") and another label on the last long (call it "last"). When writing the PASM routine to EEPROM, you'd write @first as two bytes, then @last-@first+1 as another two bytes followed by the PASM routine itself. You'd probably have a table in some fixed location in the EEPROM of the various routines with a two byte slot for each routine that contains the EEPROM address of the 4-byte header for the corresponding routine.
  • 4x5n4x5n Posts: 745
    edited 2011-10-30 12:33
    It looks like I don't understand how pasm routines are loaded nearly well enough to pull this off yet. The information I can find seems to indicate that it loads the almost 2k from hub ram into the cog but when I look at the memory mapping of pasm routines I've written in the propeller tool that doesn't seem to be the case. Which means that the loader needs to have a way of knowing how long the pasm program is or there has to be a "marker" at the end of the program.

    I've read the pdf by DeSilva, watched the webinar on assembly and read through the prop manual but there seems to be a lot of information missing. :-( On the other hand I'm having a lot of fun figuring all this out. I'm liking the idea of having a table/array with the address of the pasm routines in the upper 32K of eeprom. In my never humble opinion the nature of how pasm routines are stored in cog ram, etc needs to be included in the processor manual. That's just me though.
  • potatoheadpotatohead Posts: 10,261
    edited 2011-10-30 12:39
    Never mind. I misread the thread.
  • jazzedjazzed Posts: 11,803
    edited 2011-10-30 12:44
    4x5n wrote: »
    It looks like I don't understand how pasm routines are loaded nearly well enough to pull this off yet. The information I can find seems to indicate that it loads the almost 2k from hub ram into the cog but when I look at the memory mapping of pasm routines I've written in the propeller tool that doesn't seem to be the case. Which means that the loader needs to have a way of knowing how long the pasm program is or there has to be a "marker" at the end of the program.

    You really don't need the size for the COG, you only need the PASM size to know how much to load from the EEPROM. The cog will load 496 longs (1984 bytes) regardless of whether the code is useful or not and clear the special registers.

    All you have to do is load the PASM into a good sized buffer and cognew ... assuming you have a free COG.

    potatohead's tutorial is much more comprehensive ....
  • 4x5n4x5n Posts: 745
    edited 2011-10-30 13:22
    If random "stuff" gets loaded after the pasm routine in the cog that am I correct in assuming that I can't just let the pasm routine run out of instructions and end like I could with spin. I do understand that letting a program end by running out of instructions to execute is always bad form in assembly. :-) If I understand you right then all I need to do is worry about the start of of the pasm routine and then don't have to worry about how long it is. (as long as it fits in cog memory of course)

    Where do I find potatohead's tutorial?
  • jazzedjazzed Posts: 11,803
    edited 2011-10-30 13:56
    4x5n wrote: »
    If random "stuff" gets loaded after the pasm routine in the cog that am I correct in assuming that I can't just let the pasm routine run out of instructions and end like I could with spin. I do understand that letting a program end by running out of instructions to execute is always bad form in assembly. :-)
    Yes. It's also bad form in SPIN, but it's less critical because of the way stack the markers will be interpreted after the first PUB.
    4x5n wrote: »
    If I understand you right then all I need to do is worry about the start of of the pasm routine and then don't have to worry about how long it is. (as long as it fits in cog memory of course)
    Yes. Use "fit $1fe" at the end of your PASM to make sure it's in bounds.
    4x5n wrote: »
    Where do I find potatohead's tutorial?

    Looking at potatohead's tutorial again, it doesn't seem much more comprehensive for the experienced assembly programmer. http://forums.parallaxinc.com/forums/attach.aspx?a=28716 that's the best I can do for now. It's in the same place as desliva's. Look at this thread for more goodies: Propeller Tricks n Traps
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-10-30 14:27
    In SPIN it is not bad to have no return because the compiler adds one. If your function is the one which has been started by cognew, the return will jump to a cogstop instruction.

    In PASM you should either have an endless loop or you should do a cogstop! Otherwise really bad things could happen!
  • potatoheadpotatohead Posts: 10,261
    edited 2011-10-30 14:48
    Re: Tutorial

    Yes, right now it's a primer. Very good for somebody who has not done assembly at all, or maybe some, but not PASM. What you find in the DeSilva thread was intended to prep somebody to start on DeSilva's work, and it does that nicely, and as intended.

    I have more material, and will put it here when it's appropriate to do so.
  • 4x5n4x5n Posts: 745
    edited 2011-10-30 15:05
    All I need now is a good way to find the start of the pasm routines. :-) The labels help and I was able able to write a bit of code in the main spin routine to get the address of the labels. Unfortunately everything shifted when I removed that code. (I expected that) I do expect that loading the eprom with pasm routines will be a fairly manual process but would like to automate it as much as possible.
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-10-30 15:34
    Again .. have a look at my blog, it contains code to store PASM in EEPROM (it's called PASMstore). At least you could learn from it.
  • 4x5n4x5n Posts: 745
    edited 2011-10-30 18:26
    Mike Green wrote: »
    Usually people put a label on the first long of their PASM routine (call it "first") and another label on the last long (call it "last"). When writing the PASM routine to EEPROM, you'd write @first as two bytes, then @last-@first+1 as another two bytes followed by the PASM routine itself. You'd probably have a table in some fixed location in the EEPROM of the various routines with a two byte slot for each routine that contains the EEPROM address of the 4-byte header for the corresponding routine.

    I have to admit I never thought about having an object containing with a spin method to load the pasm routines as part of the same object write the pasm routines to eeprom. I'd still like to find a good way to do it off the propeller though. No real good reason though. :-)
  • potatoheadpotatohead Posts: 10,261
    edited 2011-10-30 19:49
    You could always just write a little SPIN to write the PASM to SD card too. Then it's "on the PC" :)
  • jazzedjazzed Posts: 11,803
    edited 2011-10-30 20:04
    potatohead wrote: »
    What you find in the DeSilva thread was intended to prep somebody to start on DeSilva's work, and it does that nicely, and as intended.
    I don't recall seeing any "DeSilva work" beyond his brief tutorial and pointed answers to questions. Got a links?
  • potatoheadpotatohead Posts: 10,261
    edited 2011-10-30 20:09
    No, that's it. The idea at the time was to ramp people up to the tutorial he authored. We both had started similar efforts at the same time. His started off just above where some people wanted to be, so I did a primer for it to close that gap.
  • 4x5n4x5n Posts: 745
    edited 2011-10-30 22:31
    Not sure if this belongs in another thread but it is related to the topic of the thread.

    After a lot of thinking about it I've given up on the idea of determining the space used by pasm programs and building the eerpm image on my computer. I think it would be easier to write a spin "loader" and have it load the pasm routines into the eeprom spaces and have a table in eeprom to keep track of the starting locations and length of the pasm routines as well as the total number stored there. I think of my lack of experience with pasm is starting to come into play though. For example I know that in the DAT block the "variables" come after the pasm routine and the "res" statements come last. The question I have is this: Can I have more then one pasm routine complete with "variables" and "res" section in a single DAT block?

    I'm thinking of something like the following:


    DAT

    org
    prog1
    various lines of code
    label1 long
    ...
    ..
    label8 res
    label9 res
    eprog1

    org
    prog2
    various lines of code
    labela1 long
    ...
    ...
    labela8 res
    labela9 res
    eprog2

    repeat

    Will this work or cause problems? Of course each routine will run at different time and/or cogs I'd rather not have to load one at a time.
  • kuronekokuroneko Posts: 3,623
    edited 2011-10-30 22:48
    4x5n wrote: »
    Can I have more then one pasm routine complete with "variables" and "res" section in a single DAT block?
    Sure. Important bit here is to put a proper org directive in front of each fragment. Also, it's all too easy to refer to a label in a different block (copy+paste, habit etc) which may cause you some head-scratching later (compiler is happy but you may get the wrong offset). So just be careful.
  • pjvpjv Posts: 1,903
    edited 2011-10-31 09:09
    Hi 4x5n;

    I'm working on something similar to what you are describing, and having some success.

    What you are suggesting; loading more than one routine into a cog certainly can be done when loaded all at once. It gets trickier when the loading is to be done not at the same time.

    For example, what I'm attempting is to spawn a cog with some "OS" type program, and while that is then running to load some more programs without affecting the original program. In fact, my goal is to load any (small-ish) number of independent programs and have them operate simutaneously in one cog. Where I'm at now, I can do some of that, but there still are some rough edges that need to be worked out. The Scheduler that orchestrates the independent timing of threads has been solid for over a year now, and the Manager that loads/dissolves and edits driver operating parameters is just getting nicely off the ground.

    When done, this will allow me to operate a half dozen or so "drivers" that are interfaced to Spin, Also Spin triggers the loading and dissolution of any driver at any time, thereby recovering space in the cog. There can be multiple fully independent instances of any drivers, giving convenient operation of multiple Serial Rx/Tx routines at varying baud rates. Also this should allow loading of programs or other data directly from SD cards once the SD driver is complete. At present it takes about 6usec to load the basic SerialTx driver, and about 30 usec to load the full I2C driver; roughly equivalent to a single Spin instruction.

    This seems like a great way to get more out of a cog than the typical single threaded program with its "WAITCNTs" that seems to be the norm today. I have been working on this for a very long time (even had to learn Spin), and hopefully it will not be too much longer for all that to get done so I can market this concept and the "ready to go" drivers to commercial Parallax users for a nominal fee. And perhaps for free to casual non-commercial users.

    So, I think your concept is on the right track, but there are many pitfalls along the way to implement an effective system. I expect it will be a tremendous learning experience for you; I know it has been for me.

    Cheers,

    Peter (pjv)
Sign In or Register to comment.