avr-gcc-list
[Top][All Lists]
Advanced

[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


reply via email to

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