首先看下 PC Host 的 Hello World。
fn main {
println! (Hello World");
}
PC 的运行环境解决了背后的复杂性,要在硬件环境上运行起来就需要把这些复杂性体现出来。[Freestand Rust Binary][] 里面讲解了这些过程,总结起来主要有几个方面。
Rust 的 std libray 需要使用系统的一些线程,锁之类的资源,裸系统上就不能直接使用,因此需要使用一个全局属性。
#![no_std]
Rust 定义了一个在调用 panic! 默认使用的一个处理函数,这里和系统相关,相关处理在 [std panic handler][] 里面,可以通过系统 api 得到调用栈,便于错误分析。我们在不能直接用 std 库,因此需要自己定义这个处理函数。
use core::panic::PanicInfo;
/// This function is called on panic.
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}
[panic_halt][] 为我们处理了这个复杂性,如果发生 panic 就进入循环,代码里面extern 进来就好。
extern crate panic_halt;
程序的执行需要特定的运行环境,才能让高层代码运行起来,对于 Cortex-M 主要包括
cortex_m_rt 提供了这个过程的整体管理,另外提供了一些属性便于上层处理。
println! 是从系统标准输出打印字符,这里当然也不能直接使用。因此需要模拟这个标准输出,通过 [cortex_m_semihosting][] 这个库。
完整的一个 hello world
#![no_main]
#![no_std]
extern crate panic_halt;
use cortex_m_rt::entry;
use cortex_m_semihosting::{debug, hprintln};
#[entry]
fn main() -> ! {
hprintln!("Hello, world!").unwrap();
debug::exit(debug::EXIT_SUCCESS);
loop {}
}