Наивный подход и write!
Наивный подход
Скорее всего, вы написали программу, похожую на следующую (examples/naive-send-string.rs):
#![no_main]
#![no_std]
use cortex_m::asm::wfi;
use cortex_m_rt::entry;
use panic_rtt_target as _;
use rtt_target::rtt_init_print;
use microbit::hal::uarte::{self, Baudrate, Parity};
use serial_setup::UartePort;
#[entry]
fn main() -> ! {
rtt_init_print!();
let board = microbit::Board::take().unwrap();
let mut serial = {
let serial = uarte::Uarte::new(
board.UARTE0,
board.uart.into(),
Parity::EXCLUDED,
Baudrate::BAUD115200,
);
UartePort::new(serial)
};
for byte in b"The quick brown fox jumps over the lazy dog.\r\n".iter() {
serial.write(*byte).unwrap();
}
serial.flush().unwrap();
loop {
wfi();
}
}
Это вполне рабочая реализация, но рано или поздно может понадобиться всё то приятное, что есть у print!, например форматирование аргументов и т. д. Если вам интересно, как это сделать, читайте дальше.
write! и core::fmt::Write
Трейт core::fmt::Write позволяет использовать любую структуру, которая его реализует, практически так же, как мы используем print! в мире std. В данном случае структура Uart из HAL nrf реализует core::fmt::Write, поэтому мы можем переписать нашу прошлую программу так (examples/send-string.rs):
#![no_main]
#![no_std]
use core::fmt::Write;
use cortex_m::asm::wfi;
use cortex_m_rt::entry;
use panic_rtt_target as _;
use rtt_target::rtt_init_print;
use microbit::hal::uarte::{self, Baudrate, Parity};
use serial_setup::UartePort;
#[entry]
fn main() -> ! {
rtt_init_print!();
let board = microbit::Board::take().unwrap();
let mut serial = {
let serial = uarte::Uarte::new(
board.UARTE0,
board.uart.into(),
Parity::EXCLUDED,
Baudrate::BAUD115200,
);
UartePort::new(serial)
};
write!(serial, "The quick brown fox jumps over the lazy dog.\r\n").unwrap();
serial.flush().unwrap();
loop {
wfi();
}
}
Если прошить эту программу на micro:bit, вы увидите, что по функциональности она эквивалентна программе на итераторах, которую вы написали.