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

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

[avr-libc-dev] [bug #34423] util/crc16.h: with -Os option inline functio


From: Karol Grzybowski
Subject: [avr-libc-dev] [bug #34423] util/crc16.h: with -Os option inline functions are called causing registers value loss
Date: Thu, 29 Sep 2011 10:59:26 +0000
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1

Follow-up Comment #2, bug #34423 (project avr-libc):

Thank you for your post. Yes, you're rigth. It should work, but doesn't and I
wonder why. (The compiler options are as default in AVRStudio 5). Here's wider
description of my problem.

I am writing a simple project with Maxim digital thermometer ds18b20 in Atmel
AVRStudio 5 using AVRlibc. The main goal is to understand how gcc works,
that's why any suggestions are welcome. Uploaded sources are available at
http://students.mimuw.edu.pl/~kg277366/thermometer.zip with default AVRStudio
makefile. The built files are included as well.

The main problem with this project is the fact that the MSB of temperature is
incorrect. GCC uses register r27 with undefined value instead of r14
containing MSB. The part of thermometer.lss file which shows this code
disassembly is attached at the end of ds18b20.h file and below. Runtime tests
confirm wrong value of MSB.

_crc_ibutton_update function comes from AVRlibc util/crc16.h file. According
to my tests, loss of MSB occurs only when my ds_read_temp_crc function is
inlined and AVRlibc _crc_ibutton_update function is called. That's why I guess
GCC has problem with _crc_ibutton_update function. Of course I don't exclude
error in my source code.

I'll be thankful for any ideas explaining this weird compiler behavior. 

static int16_t ds_read_temp_crc()
{
        int16_t temp;
        uint8_t i, data, crc;
        
        if (!ds_reset())
 2e2:   0e 94 82 00     call    0x104   ; 0x104 <ds_reset>
 2e6:   88 23           and     r24, r24
 2e8:   09 f4           brne    .+2             ; 0x2ec <main+0x118>
        {
                return DS_RESET_TEMP;
        }
 2ea:   7b c0           rjmp    .+246           ; 0x3e2 <main+0x20e>
        // skip ROM
        ds_write_byte(0xCC);
 2ec:   8c ec           ldi     r24, 0xCC       ; 204
 2ee:   0e 94 9e 00     call    0x13c   ; 0x13c <ds_write_byte>
        // read scratch pad
        ds_write_byte(0xBE);
 2f2:   8e eb           ldi     r24, 0xBE       ; 190
 2f4:   0e 94 9e 00     call    0x13c   ; 0x13c <ds_write_byte>
        // LSB of temp
        data = ds_read_byte();
        temp = (int16_t)data;
 2f8:   0e 94 c6 00     call    0x18c   ; 0x18c <ds_read_byte>
 2fc:   08 2f           mov     r16, r24 ; LSB stored in r16
 2fe:   80 e0           ldi     r24, 0x00       ; 0
        crc = _crc_ibutton_update(0, data);
 300:   60 2f           mov     r22, r16
 302:   0e 94 41 00     call    0x82    ; 0x82 <_crc_ibutton_update>
 306:   18 2f           mov     r17, r24
        // MSB of temp
        data = ds_read_byte();
        temp |= (int16_t)(data) << 8;
 308:   0e 94 c6 00     call    0x18c   ; 0x18c <ds_read_byte>
 30c:   e8 2e           mov     r14, r24 ; MSB stored in r14
 30e:   81 2f           mov     r24, r17
        crc = _crc_ibutton_update(crc, data);
 310:   6e 2d           mov     r22, r14
 312:   0e 94 41 00     call    0x82    ; 0x82 <_crc_ibutton_update>
 316:   d8 2e           mov     r13, r24
        for (i = 0; i < 7; i++)
        {
                data = ds_read_byte();
                crc = _crc_ibutton_update(crc, data);
        }
 318:   17 e0           ldi     r17, 0x07       ; 7
 31a:   0e 94 c6 00     call    0x18c   ; 0x18c <ds_read_byte>
 31e:   68 2f           mov     r22, r24
 320:   8d 2d           mov     r24, r13
 322:   0e 94 41 00     call    0x82    ; 0x82 <_crc_ibutton_update>
 326:   d8 2e           mov     r13, r24
 328:   11 50           subi    r17, 0x01       ; 1
 32a:   b9 f7           brne    .-18            ; 0x31a <main+0x146>
        if (crc)
        {
                return DS_CRC_ERROR;
        }
 32c:   88 23           and     r24, r24
 32e:   09 f0           breq    .+2             ; 0x332 <main+0x15e>
 330:   5b c0           rjmp    .+182           ; 0x3e8 <main+0x214>
 332:   a0 e0           ldi     r26, 0x00       ; r27:r26 contains: 0x?? 00
 334:   ed 01           movw    r28, r26        ; r29:r28 contains: 0x?? 00
 336:   10 e0           ldi     r17, 0x00       ; r17:r16 contains: 0x00 LSB
        return temp;
338:    0c 2b           or      r16, r28        ; r17:r16 := r17:r16 OR 
r29:r28, where r29 is
undefined instead of MSB
 33a:   1d 2b           or      r17, r29 // temp in r17:r29

 
 33c:   b5 e0           ldi     r27, 0x05       ; 5
 33e:   00 35           cpi     r16, 0x50       ; 80
 340:   1b 07           cpc     r17, r27
 342:   09 f4           brne    .+2             ; 0x346 <main+0x172>
 344:   53 c0           rjmp    .+166           ; 0x3ec <main+0x218>
 346:   e0 e1           ldi     r30, 0x10       ; 16
 348:   00 31           cpi     r16, 0x10       ; 16
 34a:   1e 07           cpc     r17, r30
 34c:   09 f4           brne    .+2             ; 0x350 <main+0x17c>
 34e:   4e c0           rjmp    .+156           ; 0x3ec <main+0x218>
 

    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/bugs/?34423>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.nongnu.org/




reply via email to

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