Electronics > Microcontrollers

AVR C: which pgm_read_* function to use for enum types in PROGMEM?

(1/3) > >>

HwAoRrDk:
This is probably just as much of a C question than a microcontroller one, but it concerns some code I'm writing for an Atmel AVR, so I figure here is as good a place as any to ask. :)

Say I have an enum defined like so:


--- Code: ---typedef enum {
FOO, BAR /* etc... */
} my_enum_t;

--- End code ---

And then somewhere in my code I want to have an array of this enum type, like so:


--- Code: ---my_enum_t blah[] = { FOO, BAR, BAR, FOO /* etc... */ };

--- End code ---

But this array is of non-trivial length, and I don't want it taking up valuable RAM, so I could choose to keep it in program space using the PROGMEM attribute. Then I can access its elements using one of the pgm_read_* functions. But which one? I don't know for sure what the byte size is of my enum type. I think I read somewhere that AVR GCC uses 16-bit int for enums by default, so I suppose I could use pgm_read_word(). But, what if I want to use the 'short-enums' compiler flag? Depending on my enum values, the enum type's size could then be any integer size! (The docs say "the enum type will be equivalent to the smallest integer type which has enough room".)

Is there a way to find out what size of int has been used for an enum (or all enums)? Of course, I know about sizeof(), but I feel hard-coding a mapping between enum size in bytes and pgm_read_* functions is a bit... yucky. I'm hoping that's not my only choice. Something defined at compile-time would be nice.

sleemanj:
memcpy_P ?

HwAoRrDk:
memcpy_P? But isn't that for... oh, wait, I think I see what you're getting at.

So I'd do something like this?


--- Code: ---my_enum_t elem;
memcpy_P(&elem, &blah[n], sizeof(my_enum_t));

--- End code ---

sleemanj:

--- Quote from: HwAoRrDk on December 01, 2016, 02:26:31 am ---
--- Code: ---my_enum_t elem;
memcpy_P(&elem, &blah[n], sizeof(my_enum_t));

--- End code ---

--- End quote ---

Yes pretty sure that should work.

HwAoRrDk:
That doesn't seem to work. :( I just end up with a random garbage value in elem that's not a valid member of the enumeration.

Oh, but I did find out that 'short-enums' is actually enabled by default with Atmel Studio 7, so sizeof(my_enum_t) in my case is actually 1 byte, and I would have been wrong to blindly go ahead and use pgm_read_word().

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version