diff options
author | 2017-05-30 10:23:23 -0500 | |
---|---|---|
committer | 2017-05-30 10:23:23 -0500 | |
commit | 2cdc916e5732821803f8d0c9790458202ca5e219 (patch) | |
tree | 82cb2cb9c2016b0cdb7af6652fdccd8ab23da9bb /src | |
parent | d9278c60fa179b8f54e98c1febbdccb16f7de24d (diff) | |
download | cortex-m-2cdc916e5732821803f8d0c9790458202ca5e219.tar.gz cortex-m-2cdc916e5732821803f8d0c9790458202ca5e219.tar.zst cortex-m-2cdc916e5732821803f8d0c9790458202ca5e219.zip |
add `itm::write_aligned` for writing 4-byte aligned buffers to an ITM port
LLVM can optimize this better and, for example, unroll the loop into a series of
32-bit writes to the ITM port
Diffstat (limited to 'src')
-rw-r--r-- | src/itm.rs | 33 | ||||
-rw-r--r-- | src/lib.rs | 1 |
2 files changed, 34 insertions, 0 deletions
@@ -1,6 +1,9 @@ //! Instrumentation Trace Macrocell use core::{fmt, ptr, slice}; + +use aligned::Aligned; + use peripheral::Stim; fn round_up_to_multiple_of(x: usize, k: usize) -> usize { @@ -64,6 +67,36 @@ pub fn write_all(port: &Stim, buffer: &[u8]) { } } +/// Writes a 4-byte aligned `buffer` to the ITM `port` +pub fn write_aligned(port: &Stim, buffer: &Aligned<u32, [u8]>) { + unsafe { + let len = buffer.len(); + let split = len & !0b11; + write_words( + port, + slice::from_raw_parts(buffer.as_ptr() as *const u32, split >> 2), + ); + + // 3 bytes or less left + let mut left = len & 0b11; + let mut ptr = buffer.as_ptr().offset(split as isize); + + // at least 2 bytes left + if left > 1 { + left -= 2; + while !port.is_fifo_ready() {} + port.write_u16(ptr::read(ptr as *const u16)); + ptr = ptr.offset(2); + } + + // final byte + if left == 1 { + while !port.is_fifo_ready() {} + port.write_u8(*ptr); + } + } +} + /// Writes `fmt::Arguments` to the ITM `port` pub fn write_fmt(port: &Stim, args: fmt::Arguments) { use core::fmt::Write; @@ -16,6 +16,7 @@ #![feature(naked_functions)] #![no_std] +extern crate aligned; pub extern crate cortex_m_semihosting as semihosting; extern crate volatile_register; |