Argh, structure initialization with PROGMEM (AVR)... - Page 1
Forum section: electronics / general

author: sleemanj
author_rank: Super Contributor
timestamp: October 04, 2014, 11:44:57 am
content: Let's assume code like this in global scope is my intention (make sure you scroll the code, seems the forum puts a height on the code box, and it's non-obvious, which is annoying)...Code:byte MyImagePage000 PROGMEM = {0x0c, 0x94, 0x35, 0x00, 0x0c};byte MyImagePage001 PROGMEM = {0x02, 0xc0, 0x05, 0x90, 0x0d};#define MyImagePage002 NULL#define MyImagePage003 NULLbyte *MyImagePages[] PROGMEM = {MyImagePage000, MyImagePage001, MyImagePage002, MyImagePage003};struct PagedBinData{char *imagename;unsigned int base_address;byte pagesize;unsigned int pagecount;byte *data[];};PagedBinData MyImage = {"slave",0x0000,5,4,MyImagePages};This does not compile, "too many initializers for ‘PagedBinData’"You can see my intention is that1. there are pages of bytes stored in PROGMEM (MyImagePage000 ...)2. some of those pages are empty and are just defined to NULL3. a table of pointers to all the pages (some of which are therefore NULL pointers) is also stored in PROGMEM4. then I want to get that PROGMEM table of pointers into a standard sram structure MyImageHow do I initialize MyImage to get MyImagePages in there like I want?

author: rs20
author_rank: Super Contributor
timestamp: October 04, 2014, 12:53:05 pm
content: Nothing to do with PROGMEM; you need to add "struct". At least, that's one issue.Code:struct PagedBinData MyImage = {"slave",0x0000,5,4,MyImagePages};ORuse typedef so that you don't need to repeat struct all over the place:Code:typedef struct{char *imagename;unsigned int base_address;byte pagesize;unsigned int pagecount;byte *data[];} PagedBinData;

author: sleemanj
author_rank: Super Contributor
timestamp: October 04, 2014, 12:57:45 pm
content: Quote from: rs20 on October 04, 2014, 12:53:05 pmThe second struct (or typedef) is not necessary in C++It's to do with PROGMEM tangentially, because if I didn't have to use PROGMEM, I wouldn't be doing it like this :-)

author: nuno
author_rank: Frequent Contributor
timestamp: October 04, 2014, 12:59:45 pm
content: byte *data[];must be initialized with a list (array) of variables of type byte*, likePagedBinData MyImage = {"slave",0x0000,5,4,{pointer1, pointer2, ...}};because you're declaring the array there, not a pointer to the array, which is what you want. How about...byte **data;};PagedBinData MyImage = {"slave",0x0000,5,4,MyImagePages};You can still index data as an array (make sure you know where it ends).

author: sleemanj
author_rank: Super Contributor
timestamp: October 04, 2014, 01:05:58 pm
content: Quote from: nuno on October 04, 2014, 12:59:45 pmAhhh, perfect, yes that does the trick.Funny, I was sure that I had some reason for using the other notation. I guess it can't have been that important.

author: bingo600
author_rank: Super Contributor
timestamp: October 04, 2014, 06:21:43 pm
content: Be aware that the way you use PROGMEM will get you in trouble , when Arduino switches to a more recent avr-gcc.Not your fault , but PROGMEM is about to be "phased out" / deprecated.Maybe consider to use a typedef or some "#define magic" already now ... "hint" prefix with const char or maybe cinst byte for the ardu. stuff/BingoNice article by Dean Chttp://www.github.com/abcminiuser/avr-tutorials/blob/master/Progmem/Output/Progmem.pdf?raw=true

author: true
author_rank: Frequent Contributor
timestamp: October 04, 2014, 09:36:04 pm
content: Quote from: bingo600 on October 04, 2014, 06:21:43 pmWhere is this discussed / documented?

author: SirNick
author_rank: Frequent Contributor
timestamp: October 05, 2014, 07:16:23 am
content: Yeah, that's news to me too. (Good PDF link though.)

author: westfw
author_rank: Super Contributor
timestamp: October 05, 2014, 07:51:18 am
content: I don't think that PROGMEM itself that became completely deprecated in the new compilers/libc. Just the prog_xxx typedefs (prog_char, etc. Because "attributes may not be attached to a type, only to a variable.")However, there is now support for "named memory spaces" at the compiler level, which can make accessing data in flash EASIER than using the pgmspace.h utilities.https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.htmlAlso note the 24-bit "unified" __memx pointers that can be used to point to either flash or RAM.

author: true
author_rank: Frequent Contributor
timestamp: October 05, 2014, 08:11:51 am
content: Quote from: westfw on October 05, 2014, 07:51:18 amYes, this is what I thought was going on / what I have read, not pgmspace.h going away but rather easier flash access becoming available. Still feels like a hack (and for avr-gcc it sort of is) but it is far easier to work with than pgmspace and will likely have support for a long while.