Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

pulseIn contains invalid assumptions about compilation on newer tool chains #2409

Closed
Labels
Component: CoreRelated to the code for the standard Arduino API Type: Bug Type: RegressionSomething that used to work and now doesn't
Milestone
@ashirley

Description

The pulseIn function in Arduino/hardware/arduino/cores/arduino/wiring_pulse.c assumes that the loop compiles into 21 clock cycles (note the documentation disagrees and assumes 20). This seems to be true with avr-gcc 4.3.2 but not with avr-gcc 4.8.2.

avr-gcc 4.3.2 produces the following for the loop:

 1528: 0f c0 rjmp .+30 ; 0x1548 <pulseIn+0xde> [2 cycles]
; loop starts here
 152a: da 01 movw r26, r20 ; [1 cycle]
 152c: c9 01 movw r24, r18 ; [1 cycle]
 152e: 8e 0d add r24, r14 ; [1 cycle]
 1530: 9f 1d adc r25, r15 ; [1 cycle]
 1532: a0 1f adc r26, r16 ; [1 cycle]
 1534: b1 1f adc r27, r17 ; [1 cycle]
 1536: 8a 15 cp r24, r10 ; [1 cycle]
 1538: 9b 05 cpc r25, r11 ; [1 cycle]
 153a: ac 05 cpc r26, r12 ; [1 cycle]
 153c: bd 05 cpc r27, r13 ; [1 cycle]
 153e: f1 f0 breq .+60 ; 0x157c <pulseIn+0x112> [1 cycle - usually not taken]
 1540: 2f 5f subi r18, 0xFF ; 255 [1 cycle]
 1542: 3f 4f sbci r19, 0xFF ; 255 [1 cycle]
 1544: 4f 4f sbci r20, 0xFF ; 255 [1 cycle]
 1546: 5f 4f sbci r21, 0xFF ; 255 [1 cycle]
 1548: 88 81 ld r24, Y ; [2 cycles]
 154a: 88 21 and r24, r8 ; [1 cycle]
 154c: 89 15 cp r24, r9 ; [1 cycle]
 154e: 69 f3 breq .-38 ; 0x152a <pulseIn+0xc0> [2 cycles as usually taken]

which by my count is 21 cycles long which matches the assumption in the code.

avr-gcc 4.3.2 produces the following for the loop:

 12b4: 68 81 ld r22, Y ; [2 cycles]
 12b6: 60 23 and r22, r16 ; [1 cycle]
 12b8: 61 13 cpse r22, r17 ; [2 cycles - usually skips next instruction]
 12ba: 0a c0 rjmp .+20 ; 0x12d0 <pulseIn+0xd6> [usually skipped]
 12bc: 28 17 cp r18, r24 ; [1 cycle]
 12be: 39 07 cpc r19, r25 ; [1 cycle]
 12c0: 4a 07 cpc r20, r26 ; [1 cycle]
 12c2: 5b 07 cpc r21, r27 ; [1 cycle]
 12c4: a9 f0 breq .+42 ; 0x12f0 <pulseIn+0xf6> [1 cycle - usually not taken]
 12c6: 2f 5f subi r18, 0xFF ; 255 [1 cycle]
 12c8: 3f 4f sbci r19, 0xFF ; 255 [1 cycle]
 12ca: 4f 4f sbci r20, 0xFF ; 255 [1 cycle]
 12cc: 5f 4f sbci r21, 0xFF ; 255 [1 cycle]
 12ce: f2 cf rjmp .-28 ; 0x12b4 <pulseIn+0xba> [2 cycles]

Which by my count is only 16. This would account for pulse readings being around 30% higher than expected (as we are seeing and as is reported at http://forum.arduino.cc/index.php/topic,247507.0.html )

Note that in the process of raising this bug (but after I had done all the investigation!) I found the following thread discussing possible fixes: https://groups.google.com/a/arduino.cc/forum/#!topic/developers/5Po5BuY7UhA

This thread points out that this implementation is also very fragile in the face of interrupts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Component: CoreRelated to the code for the standard Arduino API Type: Bug Type: RegressionSomething that used to work and now doesn't

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      AltStyle によって変換されたページ (->オリジナル) /