[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Constants in flash

From: Bas Laarhoven
Subject: Re: [avr-gcc-list] Constants in flash
Date: Sun, 23 Oct 2005 22:57:38 +0200
User-agent: Mozilla Thunderbird 1.0.6 (Windows/20050716)

Torsten Landschoff wrote:

Hi *,
In writing a boot loader for the ATmega128 I run into the following
problem: I have a function taking some kind of "format string" to describe the intended behaviour. I declare those as being in program memory. Because of that they end up in the highest 8kB of program memory. But I want to access them from program code. Problem is: When I take the
address I only get the lower 16 bits:

   #include <avr/pgmspace.h>
   void    f(void)
            static const char format[] PROGMEM = "silly example";
            uint32_t address = (uint32_t) format;
            char first = pgm_read_byte_far(address);

Hi Torsten,

You've been bitten by two different problems at once:
First of all, the sign extend you did notice.
This can easily be avoided by adding an (unsigned) cast before the (uint32_t) cast,
resulting in "(uint32_t) (unsigned) format".

Second and worse: The pointer contains only the lowest 16-bits of a byte address. This is a compiler limitation and I haven't yet found a way to pass the 17th address bit to the application (even though the symbol in the object file contains all 17 bits).
If you have some extra information you may be able to infer the
value of the 17th bit (e.g. with code in the bootloader) and offset the address variable.

Hope this helps,


This ironically generates working code, which looks like this:

  6:simple.c      ****         uint32_t address = (uint32_t) format;
 91                    .LM2:
 92 0014 80E0                  ldi r24,lo8(format.0)
 93 0016 90E0                  ldi r25,hi8(format.0)
 94 0018 AA27                  clr r26
 95 001a 97FD                  sbrc r25,7
 96 001c A095                  com r26
 97 001e BA2F                  mov r27,r26
[register shuffling omitted]
117                    /* #APP */
118 0040 ABBF                  out 59, r26
119 0042 FC01                  movw r30, r24
120 0044 8791                  elpm r24, Z+
122                    /* #NOAPP */

For some reason the compiler thinks the address is signed which leads to working code (as long as the format is in the upper or lower 32kByte of Flash).
So it seems that in my case I don't have a problem. On the other hand I wonder
how I could infer the flash location of a so declared constant. Any hints?
BTW: Replacing the cast in the assignment to address with (uint16_t) leads
to non-working code in my case.



AVR-GCC-list mailing list

reply via email to

[Prev in Thread] Current Thread [Next in Thread]