Skip to content

Commit 86cd463

Browse files
312: Fix timing of asm-based delay implementation r=adamgreig a=jonas-schievink Should fix rust-embedded#236 I've also moved the cycle adjustment into the assembly implementation, since it seems more appropriate there (and this will be useful if we make `cortex-m-asm` its own crate). Co-authored-by: Jonas Schievink <[email protected]>
2 parents 1261653 + 5a43c6e commit 86cd463

16 files changed

+9
-8
lines changed

asm/inline.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,16 @@ pub unsafe fn __cpsie() {
5252

5353
#[inline(always)]
5454
pub unsafe fn __delay(cyc: u32) {
55-
// Use local labels to avoid R_ARM_THM_JUMP8 relocations which fail on thumbv6m.
55+
// The loop will normally take 3 to 4 CPU cycles per iteration, but superscalar cores
56+
// (eg. Cortex-M7) can potentially do it in 2, so we use that as the lower bound, since delaying
57+
// for more cycles is okay.
58+
let real_cyc = cyc / 2;
5659
asm!(
60+
// Use local labels to avoid R_ARM_THM_JUMP8 relocations which fail on thumbv6m.
5761
"1:",
58-
"nop",
5962
"subs {}, #1",
6063
"bne 1b",
61-
in(reg) cyc
64+
in(reg) real_cyc
6265
);
6366
}
6467

bin/thumbv6m-none-eabi-lto.a

60 Bytes
Binary file not shown.

bin/thumbv6m-none-eabi.a

184 Bytes
Binary file not shown.

bin/thumbv7em-none-eabi-lto.a

72 Bytes
Binary file not shown.

bin/thumbv7em-none-eabi.a

184 Bytes
Binary file not shown.

bin/thumbv7em-none-eabihf-lto.a

108 Bytes
Binary file not shown.

bin/thumbv7em-none-eabihf.a

184 Bytes
Binary file not shown.

bin/thumbv7m-none-eabi-lto.a

64 Bytes
Binary file not shown.

bin/thumbv7m-none-eabi.a

188 Bytes
Binary file not shown.

bin/thumbv8m.base-none-eabi-lto.a

68 Bytes
Binary file not shown.

bin/thumbv8m.base-none-eabi.a

188 Bytes
Binary file not shown.

bin/thumbv8m.main-none-eabi-lto.a

136 Bytes
Binary file not shown.

bin/thumbv8m.main-none-eabi.a

188 Bytes
Binary file not shown.

bin/thumbv8m.main-none-eabihf-lto.a

80 Bytes
Binary file not shown.

bin/thumbv8m.main-none-eabihf.a

192 Bytes
Binary file not shown.

src/asm.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub fn bkpt() {
1515
call_asm!(__bkpt());
1616
}
1717

18-
/// Blocks the program for *at least* `n` instruction cycles
18+
/// Blocks the program for *at least* `cycles` CPU cycles.
1919
///
2020
/// This is implemented in assembly so its execution time is independent of the optimization
2121
/// level, however it is dependent on the specific architecture and core configuration.
@@ -25,10 +25,8 @@ pub fn bkpt() {
2525
/// timer-less initialization of peripherals if and only if accurate timing is not essential. In
2626
/// any other case please use a more accurate method to produce a delay.
2727
#[inline]
28-
pub fn delay(n: u32) {
29-
// NOTE(divide by 4) is easier to compute than `/ 3` because it's just a shift (`>> 2`).
30-
let real_cyc = n / 4 + 1;
31-
call_asm!(__delay(real_cyc: u32));
28+
pub fn delay(cycles: u32) {
29+
call_asm!(__delay(cycles: u32));
3230
}
3331

3432
/// A no-operation. Useful to prevent delay loops from being optimized away.

0 commit comments

Comments
 (0)