Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 9 of 9

Thread: PROGMEM use on Teensy 3.0

  1. #1
    Junior Member
    Join Date
    Mar 2013
    Posts
    9

    PROGMEM use on Teensy 3.0

    Context: I am working on using the adafruit plasma code for a 16x16 physical array of RGB LEDs using LPD8806 strips. [See https://github.com/adafruit/RGB-matr...s/plasma_16x32 for the original.]

    Here's my more general technical question about using PROGMEM on the Teensy 3.0. I want to store and read from a fairly large array held in PROGMEM: 4096 int16_t elements. When I try to upload my code to the Teensy 3.0, it crashes and the Teensy no longer shows up under the Arduino IDE Tools>Serial Port menu. I can reboot the Teensy and successfully load a different sketch, but this particular sketch consistently causes a crash. I wonder if it has something to do with the amount of data being written to PROGMEM? Or maybe that the Teensy 3.0 is not AVR-based?

    My sketch uses:
    #include <avr/pgmspace.h>
    to make use of the PROGMEM and pgm_read_xxx functions.

    I initialize the array with:
    static int16_t sinetab[4096] PROGMEM = {lots of values here}

    I read from the array with:
    (int16_t)pgm_read_word(sinetab + offset)
    I am using read_word rather than read_byte because my array is storing 16-bit integers.

    I've attached my entire sketch.

    Thanks in advance for any help you might be able to offer.

    Bongo
    Attached Files Attached Files

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,030
    On Teensy 3.0, all you have to do is use "const" in the variable declaration. Or at least that's all you're supposed to do. Everything that's "const" gets put into flash without consuming any RAM.

    PROGMEM, pgm_read_byte() and the other AVR names are defined only so code designed for AVR can compile. But they do absolutely nothing on Teensy 3.0.

    I'd recommend adding const to that huge array. If you're not planning to compile on Teensy 2.0 or other AVR boards, you might as well remove the PROGMEM stuff. Accessing the array normally is much nicer and more readable code that using pgm_read_byte().

  3. #3
    Junior Member
    Join Date
    Mar 2013
    Posts
    9
    Thank you Paul. As always, I appreciate that you take the time to help those of us stumbling along (I took a handful of comp sci and elect engr courses over 30 years ago, and am trying to teach myself how to work with boards like the teensy).

    I will use 'const' as you suggest.

    bongo

  4. #4
    Senior Member
    Join Date
    Nov 2012
    Location
    Boston, MA, USA
    Posts
    1,112
    Quote Originally Posted by PaulStoffregen View Post
    On Teensy 3.0, all you have to do is use "const" in the variable declaration. Or at least that's all you're supposed to do. Everything that's "const" gets put into flash without consuming any RAM.
    Apparently this includes literal constants.

    Code:
    void setup() {
      Serial.begin(1200);
      delay(1000);
      Serial.print(
      "\n"
        "ACT I\n"
        "SCENE I. A desert place.\n"
        "\n"
        "    Thunder and lightning. Enter three Witches \n"
        "\n"
        "First Witch\n"
        "\n"
        "    When shall we three meet again\n"
        "    In thunder, lightning, or in rain?\n"
        "\n"
    
    // and so on for the entire play
    
        "\n"
        "    Flourish. Exeunt\n"
        );
    }
    
    void loop() {
    }
    which compiles and fits into flash on Teensy 3.0

    Code:
    Binary sketch size: 119,956 bytes (of a 131,072 byte maximum)
    Estimated memory use: 3,616 bytes (of a 16,384 byte maximum)
    (As seen here, modified to only print once).
    Attached Files Attached Files

  5. #5
    Senior Member
    Join Date
    Mar 2013
    Posts
    131
    Yes, string literals are formally const char[] but conventionally char [].
    You can confirm that strings are const by considering which of these two lines is correct:
    "thin"[3] = 'k';
    int i = 0; while("thing"[i++]) ;

    It used to be much easier. In the 1980's I wrote a C compiler for the 8-bit processors (Intel 8080 and Motorola 6809). I noticed
    the "readonly" keyword was reserved so I asked Dennis Ritchie if my use of it (storing constants in EPROM) was reasonable. He confirmed
    this and we discussed whether it should be a type declarator or a storage class declarator. The latter is what I implemented and is much
    simpler conceptually and practically and what the use of "const" discussed here is all about. The C++ and C standards committees were ambitious when replacing readonly by const so there are now various subtle situations where you will need to consult books or the spec. for clarifications. C# has readonly and const. Ouch!

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,030
    Now 30-some years later, this has come full-circle with the proposed introduction of named address spaces into the C language. Of course, the compiler used on Arduino for AVR doesn't support this (it's an older version), but eventually we can look forward to proper, well designed compiler support for AVR instead of the ugly hack that is PROGMEM.

  7. #7
    Senior Member
    Join Date
    Mar 2013
    Posts
    131
    Yes, I won't miss PROGMEM. In the early days of C there was a lot of resistance to such architecture-specific features because
    everyone was working so hard to port software and learning how to write portable software. The named address spaces solution seems
    to be somewhat portable and might even work in some time-efficiency scenarios such as locking data in caches.

  8. #8
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,881

    Cool

    Quote Originally Posted by adrianfreed View Post
    The C++ and C standards committees were ambitious when replacing readonly by const so there are now various subtle situations where you will need to consult books or the spec. for clarifications. C# has readonly and const. Ouch!
    The ANSI-C committee (X3J11) did debate whether const/volatile were to be storage classes or type modifiers. The problem with storage modifiers is it falls down in terms of pointers. Consider:

    Code:
    readonly int *p = &q;
    Does this mean you can modify p to point to a different location, but can't modify what p points to (const int * p). Or can you not modify p, but you can modify what it points to (int *const p).


    BTW, I was one of a handful of people that was on the original committee from the first meeting in 1983 until the publication of the ANSI standard in 1989, and then the replacement with the ISO standard in 1990 (ANSI is one of the American standards bodies, ISO is the world wide standards body). I originally represented Data General from 1983 through 1989. I had created most of the C front end for the Data General MV/Eclipse computers, and I switched to finishing the GCC Motorola 88000 port in the last years at DG. From 1990 through 1994, I represented the Open Source Foundation. After OSF and I parted company, I dropped out of the standards business.
    Last edited by MichaelMeissner; 04-15-2013 at 01:55 PM.

  9. #9
    Senior Member
    Join Date
    Mar 2013
    Posts
    131
    Thanks for the update on that history.
    For what it is worth I think const as ANSI-C defined it is much better than a storage class modifier like readonly. Leveraging the distinction in C between
    a declaration and a definition, const is able to provide a way to express a promise to never modify something and also the desire to have data stored somewhere it can't be modified.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •