Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 <jonasschievink@gmail.com>
  • Loading branch information
bors[bot] and jonas-schievink committed Jan 7, 2021
2 parents 1261653 + 5a43c6e commit 86cd463
Show file tree
Hide file tree
Showing 16 changed files with 9 additions and 8 deletions.
9 changes: 6 additions & 3 deletions asm/inline.rs
Expand Up @@ -52,13 +52,16 @@ pub unsafe fn __cpsie() {

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

Expand Down
Binary file modified bin/thumbv6m-none-eabi-lto.a
Binary file not shown.
Binary file modified bin/thumbv6m-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv7em-none-eabi-lto.a
Binary file not shown.
Binary file modified bin/thumbv7em-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv7em-none-eabihf-lto.a
Binary file not shown.
Binary file modified bin/thumbv7em-none-eabihf.a
Binary file not shown.
Binary file modified bin/thumbv7m-none-eabi-lto.a
Binary file not shown.
Binary file modified bin/thumbv7m-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv8m.base-none-eabi-lto.a
Binary file not shown.
Binary file modified bin/thumbv8m.base-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv8m.main-none-eabi-lto.a
Binary file not shown.
Binary file modified bin/thumbv8m.main-none-eabi.a
Binary file not shown.
Binary file modified bin/thumbv8m.main-none-eabihf-lto.a
Binary file not shown.
Binary file modified bin/thumbv8m.main-none-eabihf.a
Binary file not shown.
8 changes: 3 additions & 5 deletions src/asm.rs
Expand Up @@ -15,7 +15,7 @@ pub fn bkpt() {
call_asm!(__bkpt());
}

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

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

0 comments on commit 86cd463

Please sign in to comment.