[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] How to convert Flash Strings from IAR to GCC?
From: |
Theodore A. Roth |
Subject: |
Re: [avr-gcc-list] How to convert Flash Strings from IAR to GCC? |
Date: |
Fri, 24 Oct 2003 16:52:37 -0700 (PDT) |
On Fri, 24 Oct 2003, Bob Paddock wrote:
>
> I'm trying to convert some code from IAR 2.28 to GCC , but I can't get
> the GCC version to read strings from flash, the way that IAR does.
>
> I've read the FAQ on getting string in Flash, and the recent thread on
> "Strings in Flash".
>
> I know I could use pgm_read_byte_near() in the case I show here, but I
> need to stay backwards compatible with IAR, unfortunately, and it appears in
> several different places that one I show here.
>
> How do I get GCC to generate functions that automatically uses LPM the way
> IAR does?
>
>
> This is a snipped of IAR code, and it does the right thing (generates LPM
> instructions):
> void flash_str_out( const char __flash *str )
> {
> uint8_t chr_u8;
> ...
> chr_u8 = *str++;
> ...
> }
>
> This is what IAR generates:
>
> static char const __flash STRING[8] = "1234567";
> _nearfunc void flash_str_out(char const __flash *);
> ...
> \ 00000010 01FC MOVW R31 : R30,R25 : R24
> \ 00000012 9104 LPM R16,Z
> ...
>
>
> This is what GCC generates, which is wrong for reading from Flash (No LPM
> instruction):
>
> 25:strout.c **** void flash_str_out( const prog_char * str )
> 26:strout.c **** {
> 111 .LM1:
> 112 /* prologue: frame size=0 */
> 113 0000 CF93 push r28
> 114 0002 DF93 push r29
> 115 /* prologue end (size=2) */
> 116 0004 EC01 movw r28,r24
> 27:strout.c **** uint8_t chr_u8;
> ...
> 32:strout.c **** chr_u8 = *str++;
> 123 .LM3:
> 124 000a 8991 ld r24,Y+
>
>
>
Doing this:
uint8_t flash_str_out( const char PROGMEM *str )
{
uint8_t chr_u8;
chr_u8 = pgm_read_byte (*str++);
return chr_u8;
}
generated this on my system:
uint8_t flash_str_out( const char PROGMEM *str )
{
ca: fc 01 movw r30, r24
uint8_t chr_u8;
chr_u8 = pgm_read_byte (*str++);
cc: 80 81 ld r24, Z
ce: e8 2f mov r30, r24
d0: ff 27 eor r31, r31
d2: e7 fd sbrc r30, 7
d4: f0 95 com r31
d6: 84 91 lpm r24, Z
return chr_u8;
d8: 99 27 eor r25, r25
}
da: 08 95 ret
If you need compatibility with IAR, then define pgm_read_byte() as a
null macro for IAR:
#ifndef pgm_read_byte
#define pgm_read_byte(a) (a)
#endif
Ted Roth