[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-libc-dev] avr-libc 1.0.2 strncpy_P using lpm instead of elpm on
From: |
Dmitry K. |
Subject: |
Re: [avr-libc-dev] avr-libc 1.0.2 strncpy_P using lpm instead of elpm on mega 128 |
Date: |
Fri, 16 Jan 2004 10:20:02 +1000 |
User-agent: |
KMail/1.5 |
15 Jan 2004 10:54 Simon Eatough wrote:
> Hi
> I've noticed a problem with strncpy_P where the wrong version of lpm is
> used. /snip
> 1e646: fb 01 movw r30, r22
> 1e648: dc 01 movw r26, r24
>
> 0001e64a <.strncpy_P_loop>:
> 1e64a: 41 50 subi r20, 0x01 ; 1
> 1e64c: 50 40 sbci r21, 0x00 ; 0
> 1e64e: 48 f0 brcs .+18 ; 0x1e662
> 1e650: 05 90 lpm r0, Z+ <<<<
> should be elpm r0, Z+ on mega
> 128 ? 1e652: 0d 92 st X+, r0
> 1e654: 00 20 and r0, r0
> 1e656: c9 f7 brne .-14 ; 0x1e64a
> 1e658: 01 c0 rjmp .+2 ; 0x1e65c
>
> It looks like macros.inc is expecting __AVR_ENHANCED__ to be defined
> somwhere.
>
I have no operational experience with such crystals.
If I have correctly understood, avr-gcc/libc cannot work with the data
(in program memory) located above of border 64K.
But the program can reach 128K as the pointer to function omits bit 0.
Remains opportunity to work manually, using pgm_read_*_far().
See next example, all pointers are 2 bytes size:
extern void foo (int);
char ram_c;
__attribute__((progmem)) char prog_c = 0;
void size (void)
{
foo(sizeof(&ram_c));
foo(sizeof(&prog_c));
foo(sizeof(&foo));
}
Result (-mmcu=atmega128 -Os) is:
size:
/* prologue: frame size=0 */
/* prologue end (size=0) */
ldi r24,lo8(2)
ldi r25,hi8(2)
call foo
ldi r24,lo8(2)
ldi r25,hi8(2)
call foo
ldi r24,lo8(2)
ldi r25,hi8(2)
call foo
/* epilogue: frame size=0 */
ret
Yours faithfully,
Dmitry.