Whats the correct approach here? I tried every combination of const and PROGMEM attributes but always get this error.

For clarification: I could of course use the first mentioned alternative, but i want to create the pointer tables with a preprocessor macro, because there are a lot of them and it would make implementations of new languages easier.

If there really was some reason you needed something at 0x1F00 then you can do:

const uint8_t foo = 5 __attribute__((section(".myvar")));

then pass this to the linker:

-Wl,-section-start=.myvar=0x1F00

and finally:

var = pgm_read_byte((uint8_t *)0x1F00);

But like Alex says, why would you do this? Why not use PROGMEM properly as explained in the original article of this thread? If you do start specifying absolute addresses like 0x1F00 you may conflict with what the linker tries to do automatically - how do you know it wasn't already planning to place code or flash data at that location?

I wish that the customer can easily find some constants before program firmware with isp

But ISP doesn't allow subsections of the flash to be changed/replaced?!? I'd go with Alex's idea of keeping config value in EEPROM which the customer *can* program separately.

Quote:

I saw that the compiler always puts constant from address 0x26 (ATmega8), then fine by me,

It's not the compiler that did that, it's the linker. This is because the linker is given a "linker script" that tells it how to lay things out in flash. That file is ..\AVRToolchain\avr\lib\ldscripts\avr4.x which contains:

This says that anything in a section called .vectors will be placed at the very start of flash - that includes the reset jump and the interrupt vector table - this is then followed by anything in .progmem* sections which means anything where you use PROGMEM which is similar to __attribute__((section(".progmem")). The reset+vectors on a mega8 are clearly 0x26 bytes long.

The PROGMEM attribute in the .h file means nothing to gcc, the symbol is just a hex offset from the start of a particular linker section and the code that refers to it still has to use the method appropriate to the hardware location of that section. Some compilers may do that automatically, but not gcc. For easier maintenance you can define both the attribute and the appropriate programmic references in the .h file and include that in all the c files.

This typedef is now deprecated because the usage of the __progmem__ attribute on a type is not supported in GCC. However, the use of the __progmem__ attribute on a variable declaration is supported, and this is now the recommended usage.

The typedef is only visible if the macro __PROG_TYPES_COMPAT__ has been defined before including (either by a #define directive, or by a -D compiler option.)

No one should EVER edit any library/system header file that belongs to the compiler or the C library. Just consider what happens next week when you upgrade the compiler and everything, including your edits, are replaced.

The fix for your "problem" here is to replace prog_char as you have been told. It was never a valid definition anyway as it applied an attribute (progmem) to a typedef. The correct way is exactly what that text from the user manual I quoted above says. Instead of:

#include
prog_char foo = 'A';

use:

#include
const char PROGMEM foo = 'A';

though this is now 2014 and a much better idea is:

const __flash foo = 'A';

With a __flash variable there's no longer a need to use pgm_read_byte() (or even include pgmspace.h). You can just say:

PORTB = foo;

and the compiler knows that foo was defined in __flash so will do the equivalent of a pgm_read_byte(&foo) anyway when it reads the 'A' character.

For this example, please forget about casts and stylistic questions. What causes me headaches is the question, whether I may do this or not. In my actual code this works. But perhaps I'm just lucky.

So my question is:

- can it happen, that the members within this (or any other) struct have different aligments if they reside in different storage-types??

I mean: is it possible, that intermixed datatypes in structs (8 bit, function(i.e. callback)-pointers, 32 bit values and so on) cause different memory-alignemnts within a struct of the same type, depending on the location where they originate from?

AND: Does this differ between different atmega-processors?

Or can I carelessly copy from

PROGMEM to RAM ||
EEPROM to RAM (with an extra EEPROM-version of course)

I would say it is a fantastic tutorial for the beginners. You are doing a good job. Helps me a lot to understand the basic concepts. I wish you to create much more tutorials on AVR GCC macros with relative examples as in this tutorial. You can also try to go little advance once you establish the basic concepts.

I wouldn't hold your breath. Dean has a real job working on things a bit more advanced than the humble AVR, so i don't think you see much from him.
Note this tutorial is *only* ten years old - there's the _flash attribute now. Time for some reading methinks.

But if you are sticking with PROGMEM then to be honest it doesn't really matter what you pass the pointers around as. In fact you might as well use "void *". The only time it's important what a pointer is pointing to is when you dereference it. So:

But you aren't going to be doing those operations on a pointer to data such as was being shown here. (but, yeah, you'll have too cast it from void * if you want to do arithmetic - but again it doesn't really matter what it points to as long as it's something of the same width).

When I said "it doesn't really matter what it points to" what I meant was RAM, flash, EEPROM or whatever. A "char *" is good for accessing 8bits whether it's in any of those memory spaces.

I attempted to do const char MyArray[2][2][5] PROGMEM = {{"Test",Test"},{"Test",Test"}}; but I now am unable to draw the strings out using (PGM_P)pgm_read_word(&(MyArray[1][1]))

Looks like you have a misconception about that three dimensional char array. There is no indirection involved. No need to read an address from flash first which then points to the text. &(MyArray[1][1]) is already the address of the text.

what I have issue to with this way and not the other is in the deceleration of the array, if I declare an array such "const char MyArray[10][12][15] PROGMEM" does the chip set aside 10*12*15 bytes of program memory for the chars?

what I have issue to with this way and not the other is in the deceleration of the array, if I declare an array such "const char MyArray[10][12][15] PROGMEM" does the chip set aside 10*12*15 bytes of program memory for the chars? if so, unless the bytes are used they are wasted, correct?

Which is the exact reason people don't tend to use fixed width fields in such tables. The usual scheme is to put "char *" pointers in one table that then point to a collection of separately define char strings of varying length elsewhere and it's when you do that the need for double-indirection comes into play where you pgm_read_word() first to get the pointer (char *) to the string you actually want and then you pgm_read_byte() to get to the characters within what the pointer holds the address of.

__flash makes like easier (if not C++) and just today someone made a post that uses something called FSTR() that makes the definition of such string tables easier still (so search "FSTR" ;-)

SO how does one build a table of tables? and "flash" is ram equivalent of a computer? and program memory is the equivalent of a hard-drive, I had a problem with "ram", and am attempting to push my strings into program space(had-drive) (yes/no/maybe)?

@Theone6000: Any attempt to map memory types of an AVR to memory types common on many PCs will fail in one or several aspects.

E.g Jims assertion re flash being the equivalent of a hard disk is true in the sense that both are non-volatile memories, but fails since code is executed directly from flash on an AVR but definitively not direct from a hard disk on a PC. From a code execution perspective the flash is closest to both RAM and a hard disk on a PC. On the other hand you store data non- volatively on a PC hard disk but while you store such in flash on an AVR also the more common cases are certainly EEPROM and possibly some kind of external non-volatile memory like a memory card.

Whatever you claim is equal between an AVR and a PC memory-wise a good case for the opposite can be made.

You just have to face the fact that you're dealing with a different beast here. With a different basic architecture. You'll get used to it soon (-:

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.

No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]