avr-libc-dev
[Top][All Lists]
Advanced

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

Re: [avr-libc-dev] Error when using large memory addresses


From: Paul Schlie
Subject: Re: [avr-libc-dev] Error when using large memory addresses
Date: Tue, 15 Feb 2005 13:27:57 -0500
User-agent: Microsoft-Entourage/11.1.0.040913

However if pgm_read_byte_far(...) were called from within an interrupt
routine, and there were a danger of another pgm_read_byte_far(...) call
being interrupted (although wouldn't be a great way to structure things),
then the interrupt routine would need to save the previous RAMPZ value
somewhere, and then restore it prior to returning.

> From: Paul Schlie <address@hidden>
> 
> Unless I misunderstand (and may), there seems to be nothing to work around; as
> RAMPZ does not affect RAM load/stores on any devices (I'm aware of), and is
> correctly set as required when program memory is accessed; so why would you
> want to add code which does nothing useful?
> 
> 
>> From: gouy yann <address@hidden>
>> Date: Tue, 15 Feb 2005 15:44:34 +0100 (CET)
>> To: Per Arnold Blåsmo <address@hidden>, <address@hidden>
>> Subject: Re: [avr-libc-dev] Error when using lagre memory addresses
>> 
>> hello,
>> 
>> I suspect you will ask to write a bug report for the problem not to be
>> forgiven!
>> 
>> regards.
>> 
>>    Yann
>> 
>>  --- Per Arnold Blåsmo <address@hidden> a écrit :
>>> Hi,
>>> During my work with adapting avg-gcc to a new processor (AT90SC3232CS) I
>>> have discovered a problem regarding addressing that I think is not
>>> working in the generated code.
>>> 
>>> I would like some comments on this from some of you more expert than me
>>> on this :-)
>>> 
>>> Consider the following code:
>>> ----
>>> #include <avr/io.h>
>>> #include <avr/pgmspace.h>
>>> 
>>> #define FROMADDR 0x100000L
>>> #define TOADDR1 (uint8_t *)0x200
>>> #define TOADDR2    (uint8_t *)0x100
>>> 
>>> int main(void)
>>> {
>>>     uint8_t *p_to_addr1= TOADDR1;
>>>     uint8_t *p_to_addr2= TOADDR2;
>>>     uint32_t from_addr = FROMADDR;
>>>     uint8_t size = 255;
>>> 
>>>     while(size--){
>>>         *p_to_addr1++ = pgm_read_byte_far(from_addr++);
>>>     }
>>>     size=255;
>>>     *p_to_addr1 = TOADDR1;
>>>     while(size--){
>>>         *p_to_addr2++ = *p_to_addr1++;
>>>     }
>>> 
>>> }
>>> ----
>>> 
>>> Compile for an ATmega128 it gives the following assembly:
>>> (and yes I know it would not work in real life, but I try to show a
>>> point her :-)
>>> 
>>> ----
>>> int main(void)
>>> {
>>>   62:    cf ef           ldi    r28, 0xFF    ; 255
>>>   64:    dc e0           ldi    r29, 0x0C    ; 12
>>>   66:    de bf           out    0x3e, r29    ; 62
>>>   68:    cd bf           out    0x3d, r28    ; 61
>>>     uint8_t *p_to_addr1= TOADDR1;
>>>   6a:    00 e0           ldi    r16, 0x00    ; 0
>>>   6c:    12 e0           ldi    r17, 0x02    ; 2
>>>     uint8_t *p_to_addr2= TOADDR2;
>>>   6e:    ee 24           eor    r14, r14
>>>   70:    ff 24           eor    r15, r15
>>>   72:    68 94           set
>>>   74:    f0 f8           bld    r15, 0
>>>     uint32_t from_addr = FROMADDR;
>>>   76:    40 e0           ldi    r20, 0x00    ; 0
>>>   78:    50 e0           ldi    r21, 0x00    ; 0
>>>   7a:    60 e1           ldi    r22, 0x10    ; 16
>>>   7c:    70 e0           ldi    r23, 0x00    ; 0
>>>     uint8_t size = 255;
>>> 
>>>     while(size--){
>>>         *p_to_addr1++ = pgm_read_byte_far(from_addr++);
>>>   7e:    ce ef           ldi    r28, 0xFE    ; 254
>>>   80:    db 01           movw    r26, r22
>>>   82:    ca 01           movw    r24, r20
>>>   84:    4f 5f           subi    r20, 0xFF    ; 255
>>>   86:    5f 4f           sbci    r21, 0xFF    ; 255
>>>   88:    6f 4f           sbci    r22, 0xFF    ; 255
>>>   8a:    7f 4f           sbci    r23, 0xFF    ; 255
>>>   8c:    98 01           movw    r18, r16
>>>   8e:    0f 5f           subi    r16, 0xFF    ; 255
>>>   90:    1f 4f           sbci    r17, 0xFF    ; 255
>>>   92:    ab bf           out    0x3b, r26    ; 59   <= 0x3b = RAMPZ set
>>> to 0x10
>>>   94:    fc 01           movw    r30, r24
>>>   96:    87 91           elpm    r24, Z+
>>>   98:    f9 01           movw    r30, r18
>>>   9a:    80 83           st    Z, r24               <= this one should
>>> store to 0x0200 but stores to 0x100200 instead
>>>   9c:    c1 50           subi    r28, 0x01    ; 1
>>>   9e:    80 f7           brcc    .-32         ; 0x80
>>>     }
>>>     size=255;
>>>     *p_to_addr1 = TOADDR1;
>>>   a0:    f8 01           movw    r30, r16
>>>   a2:    10 82           st    Z, r1
>>>     while(size--){
>>>         *p_to_addr2++ = *p_to_addr1++;
>>>   a4:    ce ef           ldi    r28, 0xFE    ; 254
>>>   a6:    f8 01           movw    r30, r16
>>>   a8:    81 91           ld    r24, Z+            <= this one should
>>> load from 0x0200 but loads from 0x100200
>>>   aa:    8f 01           movw    r16, r30
>>>   ac:    f7 01           movw    r30, r14
>>>   ae:    81 93           st    Z+, r24            <= this one should
>>> store in 0x0100 but stores in 0x100100
>>>   b0:    7f 01           movw    r14, r30
>>>   b2:    c1 50           subi    r28, 0x01    ; 1
>>>   b4:    c0 f7           brcc    .-16         ; 0xa6
>>>     }
>>> 
>>> }
>>> 
>>> -----------
>>> 
>>> This code will not work as intended.
>>> 
>>> As you can see I use a 'from address' that is 24 bit put into a long (32
>>> bit).
>>> To read from this address I use 'pgm_read_byte_far'. 'pgm_read_byte_far'
>>> correctly uses
>>> RAMPZ (0x3b) to address the memory location ((RAMPZ:Z) = 0x100000).
>>> 
>>> The problem is that RAMPZ does not get reset after used. That clutters
>>> the use of Z later in the code.
>>> 
>>> My solution to this so far has been to include a line likethis:
>>> 
>>>     __asm__ volatile ("out     %0, 0x0" : : "I" (_SFR_IO_ADDR(RAMPZ)));
>>>     // Hack to reset RAMPZ after it is used
>>> 
>>> Anyone like to comment on this or/and suggest another work-around?
>>> 
>>> Per A.
>>> 
>>> 
>>> _______________________________________________
>>> AVR-libc-dev mailing list
>>> address@hidden
>>> http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
>>>  
>> 
>> 
>> 
>> 
>> 
>> 
>> Découvrez le nouveau Yahoo! Mail : 250 Mo d'espace de stockage pour vos mails
>> ! 
>> Créez votre Yahoo! Mail sur http://fr.mail.yahoo.com/
>> 
>> 
>> _______________________________________________
>> AVR-libc-dev mailing list
>> address@hidden
>> http://lists.nongnu.org/mailman/listinfo/avr-libc-dev






reply via email to

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