Shop OBEX P1 Docs P2 Docs Learn Events
Variable exceeds available RAM...already??? — Parallax Forums

Variable exceeds available RAM...already???

basicstampedebasicstampede Posts: 214
edited 2008-09-02 20:23 in General Discussion
This is a listing of my variables.· Not many I thought.· But compiler says "Variable exceeds available RAM"

This is only 20 bytes for RAM.· What is the problem?

counter VAR Word
sec VAR Word
seconds VAR Word
minutes VAR Word
sec_ones VAR Byte
sec_tens VAR Byte
min_ones VAR Byte
min_tens VAR Byte
digit VAR Byte
digitvalue VAR Byte
value VAR Byte
pinstatus VAR Byte
time VAR Byte
oldpin VAR Byte
newpin VAR Byte
result VAR Byte

Comments

  • SteelSteel Posts: 313
    edited 2008-09-02 16:28
    Unfortunately, There are only 20 bytes allocated for variable declaration.

    ....However, apparently Arrays are stored in a different spot, which is MUCH larger...so if you save your variables as arrays instead of bytes and words, you will have much more space. I forget the exact numbers...somebody else can probably chime in on that.
  • BeanBean Posts: 8,129
    edited 2008-09-02 16:30
    Yes, arrays use the remainder of the SX RAM.
    In many cases you can use an array of one element in place of a byte variable. But it requires more code to use the array.

    Also, you BYTEs instead of WORDs anywhere you can.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    "A government big enough to give you everything you want, is big enough to take away everything you·have."·· Thomas Jefferson

    "It is our choices, Harry, that show what we truly are, far more than our abilities."·Dumbledore from Harry Potter

    www.iElectronicDesigns.com

    ·
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2008-09-02 16:36
    I assume you are using an sx28.
    Sx28 only has 19 'normal' bytes.
    Additional bytes are declared as arrays.
    You can declare:
    counter VAR Word
    sec VAR Word
    seconds VAR Word
    minutes VAR Word
    sec_ones VAR Byte
    sec_tens VAR Byte
    min_ones VAR Byte
    min_tens VAR Byte
    digit VAR Byte
    digitvalue VAR Byte
    value VAR Byte
    pinstatus VAR Byte
    time VAR Byte
    oldpin VAR Byte
    newpin VAR Byte
    'result VAR Byte· 'this byte cannot be declared
    Bytes50 var byte(16) 'bank $50
    Bytes70 var byte(16)
    Bytes90 var byte(16)
    BytesA0 var byte(16)
    BytesC0 var byte(16)
    BytesD0 var byte(16)
    BytesF0 var byte(3) 'bank $F0

    regards peter
  • basicstampedebasicstampede Posts: 214
    edited 2008-09-02 16:45
    Thanks for the input everyone.· So I should use array instead.

    Would this be acceptable?

    Bytes50 var byte(16) 'bank $50
    Bytes70 var byte(16)

    Then, I would·use Bytes50(0) to Bytes50(15) and Bytes70(0) to Bytes70(15).

    Is my understanding correct?·

    P.S.· Of course, I guess I need to keep a record of what each of them such as Bytes(4) and Bytes70(12) actually are.· Hmm, but wouldn't this make the program much less readable?·
  • JonnyMacJonnyMac Posts: 9,215
    edited 2008-09-02 17:12
    You can start by making your present variables more efficient. Do you need a word to store seconds and minutes -- in a typical clock/timer application the values that these variables will hold is 0 to 59, so why use a word? Do you really need to keep the 1s and 10s values separately during the entire program run, or just when you're updating some sort of display?

    If you posted your entire listing I'm betting more than a few of us could show you how to shore up your program without a lot of monkey-motion.

    Post Edited (JonnyMac) : 9/2/2008 5:17:51 PM GMT
  • basicstampedebasicstampede Posts: 214
    edited 2008-09-02 17:30
    JohnnyMac, thanks. Actually, for this project, I solved it by using Byte variables. But this experience got me worried about about future projects. So my question above is still of interest to me.
    Should I code this way?

    Bytes50 var byte(16) 'bank $50
    Bytes70 var byte(16)

    Then, I would use Bytes50(0) to Bytes50(15) and Bytes70(0) to Bytes70(15).
    And access each variable for example as Bytes50(3) and Bytes70(12) etc.?
    Is there an easy way to keep track of what Bytes50(4) and Bytes70(11) are for example?

    Thanks.
  • JonnyMacJonnyMac Posts: 9,215
    edited 2008-09-02 17:42
    I wouldn't. I write a LOT of SX/B programs and have almost never run out of variable space. To be honest, though, I've always been stingy with variables so variable management in small micros comes easily. There are times when arrays are a good idea; for example, if you're going to do background serial processes you can stuff all of those variables into an array and let the ISR take care the whole works.

    The lesson, I guess, is to learn to be stingy with your resources. Use bit flags when you can, use bytes instead of words where possible, and unless you need to keep track of a value through the entire run of a program, don't keep it as this just wastes variable space. I always create a group of temporary variables that I use through my programs; these are in the main variable space and yet I never seem to run out of RAM.

    As I've stated before, the SX is a little trickier that the BS2, and as you learn the tricks you'll have a lot more fun.

    Now, I'm not trying to dissuade you from using arrays, I'm simply suggesting that you use them wisely such that your program is still easy to read. For example, you might do this:

    clock           VAR     Byte (4)
     secs           VAR     clock(0)
     mins           VAR     clock(1)
     hours          VAR     clock(2)
     days           VAR     clock(3)
    


    This frees up four bytes from your main RAM space and lets you do things like this:

    PUT clock, 0, 0, 6, 0
    


    ... which will set hours to 6 and everything else to zero.

    One of the SX/B rules that you need to be aware of, however, is that you cannot use an array element as a loop control variable with FOR-NEXT -- this is one of the reasons I caution you not to create a big array and create aliases into it; it would be very easy to try to use one of those [noparse][[/noparse]array] variables in FOR-NEXT, get a compiler warning, and then have a tough time figuring out why.
  • basicstampedebasicstampede Posts: 214
    edited 2008-09-02 18:29
    JohnnyMac, thanks for all you help ans tips.
    I agree that it is good to be stingy with variable RAM. But unlike BS2, SX/B does not allow me to declare a bit, or nib. I think the smallest is Byte.
    So I find that I end up "wasting" more variable RAM than I normally would in BS2.
    Hopefully on next version of SX/B, there is more tools to help us be stingy with RAM.
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2008-09-02 18:33
    You can declare bits like this:
    mybit var bytes50(0).3
    You can even declare 'normal' bits
    digit VAR Bit
    sx/b will group bits into bytes.

    Nibbles are not available in sx/b

    regards peter
  • basicstampedebasicstampede Posts: 214
    edited 2008-09-02 18:45
    Peter, that is fantastic! I learned a few new tricks!!! Thank you!!!
  • basicstampedebasicstampede Posts: 214
    edited 2008-09-02 18:55
    One more quick question:

    Bytes70 var byte(16)

    I guess the above statement declares an array of 17 bytes, them being Bytes70(0) to Bytes70(16). Is this correct? (It appears to be based on my experiment).
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2008-09-02 19:00
    It declares an array of 16 bytes. Note that you do not need to declare
    16 bytes, as Jon demonstrated. But note that you cannot declare arrays
    larger than 16 bytes on the sx28 (eg. span an array across a rambank boundary).
    Key is to declare aliases as Jon did with the time variables and then use those aliases in your code.
    These aliases can be used pretty much as normal variables
    for most sx/b statements.

    regards peter
  • basicstampedebasicstampede Posts: 214
    edited 2008-09-02 19:26
    Peter, but I just tried this and it compiles successfully.

    aa VAR Bit 'good to know I can declare a Bit!!!

    bb VAR Byte(16) 'Declare a string of 17 bytes? bb(0) to bb(16)?
    ee VAR bb(0).5 'Since I can access bb(0) and bb(16), it appears that I've actually created an array of 17 bytes, not 16.
    ff VAR bb(16).7

    meaningful_name VAR bb(3) 'good to know I can do this!

    So if I really only declared 16 bytes with bb VAR Byte(16) statement, then either bb(0) or bb(16) must be erroneous. Which one?
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2008-09-02 19:52
    Unfortunately,
    You have hit a known compiler bug.

    Your declarations compile into
    ··· 67· =0000000D······ aa··········· EQU· 0x0D.0······· ;aa VAR Bit 'good to know I can declare a Bit!!!
    ··· 68·················
    ··· 69·················
    ··· 70· =00000030······ bb··········· EQU· 0x30········· ;bb VAR Byte(16) 'Declare a string of 17 bytes? bb(0) to bb(16)?
    ··· 71·················
    ··· 72· =00000030······ ee··········· EQU· bb+0········· ;ee VAR bb(0).5 'Since I can access bb(0) and bb(16), it appears that I've actually created an array of 17 bytes, not 16.
    ··· 73·················
    ··· 74· =00000040······ ff··········· EQU· bb+16········ ;ff VAR bb(16).7

    which shows that the bit aliases for array variables are not correct.
    It also shows the address for bb(16) is calculated as bb+16 which is $40.
    That address does not exist in the sx28.

    regards peter
  • basicstampedebasicstampede Posts: 214
    edited 2008-09-02 20:00
    OK. Thanks Peter. Then that means I should only use bb(0) to bb(15). Thanks for all your assistance.
  • JonnyMacJonnyMac Posts: 9,215
    edited 2008-09-02 20:23
    You can declare bits but I think it's a wise idea to declare their byte container first, then alias them -- this gives you better control and memory management in my opinion. I use a couple bit flags in the attached demo, but both are aliased into a byte so I have maximum control.

    While it is very easy to get wrapped around the axle in academic discussions about what is or isn't theoretically possible, you'll get to your goals more quickly by writing real code. Yes, along the way you'll run into road blocks an pitfalls, but you'll learn a lot in the process. As my friend PJ Monty says, learning syntax is easy, learning to program takes effort.

    Since I mentioned serial and suggested a clock array I've attached a demo that actually uses them. This framework takes care of buffered transmit and receive as well as maintaining an RTC -- all in the "background." Note that the RTC values are stored as BCD; very much like the DS1302 and similar chips. If you have a PDB you can use the extra serial interface to connect to your PC running HyperTerminal (or something similar). As you can see, the foreground code is able to access the clock variables as if they were in the normal RAM space when it wants to send them to the terminal using the TX_HEX2 subroutine.

    A lot of this code is highly modular and I use it over and over. As your expertise in SX/B develops you'll find yourself doing the same thing. Sure, you make a few tweaks here and there for changing clock or ISR rate, but that's a small price to pay.
Sign In or Register to comment.