mirror of
https://github.com/google/comprehensive-rust.git
synced 2024-11-26 09:30:52 +02:00
Add example implementing logger.
This commit is contained in:
parent
15518aa177
commit
31c7b283c2
@ -264,7 +264,8 @@
|
||||
- [Multiple registers](bare-metal/aps/better-uart/registers.md)
|
||||
- [Driver](bare-metal/aps/better-uart/driver.md)
|
||||
- [Using it](bare-metal/aps/better-uart/using.md)
|
||||
- [Logging]()
|
||||
- [Logging](bare-metal/aps/logging.md)
|
||||
- [Using it](bare-metal/aps/logging/using.md)
|
||||
- [Other projects](bare-metal/aps/other-projects.md)
|
||||
- [Useful crates]()
|
||||
- [zerocopy]()
|
||||
|
@ -21,3 +21,7 @@ path = "src/main_minimal.rs"
|
||||
[[bin]]
|
||||
name = "improved"
|
||||
path = "src/main_improved.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "logger"
|
||||
path = "src/main_logger.rs"
|
||||
|
@ -21,11 +21,15 @@ minimal.bin: build
|
||||
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/minimal minimal.bin
|
||||
improved.bin: build
|
||||
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/improved improved.bin
|
||||
logger.bin: build
|
||||
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/logger logger.bin
|
||||
|
||||
qemu_minimal: minimal.bin
|
||||
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel minimal.bin -s
|
||||
qemu: improved.bin
|
||||
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel improved.bin -s
|
||||
qemu_logger: logger.bin
|
||||
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel logger.bin -s
|
||||
|
||||
clean:
|
||||
cargo clean
|
||||
|
54
src/bare-metal/aps/examples/src/logger.rs
Normal file
54
src/bare-metal/aps/examples/src/logger.rs
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// ANCHOR: main
|
||||
use crate::pl011::Uart;
|
||||
use core::fmt::Write;
|
||||
use log::{LevelFilter, Log, Metadata, Record, SetLoggerError};
|
||||
use spin::mutex::SpinMutex;
|
||||
|
||||
static LOGGER: Logger = Logger {
|
||||
uart: SpinMutex::new(None),
|
||||
};
|
||||
|
||||
struct Logger {
|
||||
uart: SpinMutex<Option<Uart>>,
|
||||
}
|
||||
|
||||
impl Log for Logger {
|
||||
fn enabled(&self, _metadata: &Metadata) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn log(&self, record: &Record) {
|
||||
writeln!(
|
||||
self.uart.lock().as_mut().unwrap(),
|
||||
"[{}] {}",
|
||||
record.level(),
|
||||
record.args()
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn flush(&self) {}
|
||||
}
|
||||
|
||||
/// Initialises UART logger.
|
||||
pub fn init(uart: Uart, max_level: LevelFilter) -> Result<(), SetLoggerError> {
|
||||
LOGGER.uart.lock().replace(uart);
|
||||
|
||||
log::set_logger(&LOGGER)?;
|
||||
log::set_max_level(max_level);
|
||||
Ok(())
|
||||
}
|
51
src/bare-metal/aps/examples/src/main_logger.rs
Normal file
51
src/bare-metal/aps/examples/src/main_logger.rs
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// ANCHOR: main
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
mod exceptions;
|
||||
mod logger;
|
||||
mod pl011;
|
||||
|
||||
use crate::pl011::Uart;
|
||||
use core::panic::PanicInfo;
|
||||
use log::{error, info, LevelFilter};
|
||||
use psci::system_off;
|
||||
|
||||
/// Base address of the primary PL011 UART.
|
||||
pub const PL011_BASE_ADDRESS: usize = 0x900_0000;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(x0: u64, x1: u64, x2: u64, x3: u64) {
|
||||
// Safe because `PL011_BASE_ADDRESS` is the base address of a PL011 device,
|
||||
// and nothing else accesses that address range.
|
||||
let uart = unsafe { Uart::new(PL011_BASE_ADDRESS as *mut u32) };
|
||||
logger::init(uart, LevelFilter::Trace).unwrap();
|
||||
|
||||
info!("main({:#x}, {:#x}, {:#x}, {:#x})", x0, x1, x2, x3);
|
||||
|
||||
assert_eq!(x1, 42);
|
||||
|
||||
system_off().unwrap();
|
||||
}
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(info: &PanicInfo) -> ! {
|
||||
error!("{}", info);
|
||||
system_off().unwrap();
|
||||
loop {}
|
||||
}
|
||||
// ANCHOR_END: main
|
16
src/bare-metal/aps/logging.md
Normal file
16
src/bare-metal/aps/logging.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Logging
|
||||
|
||||
It would be nice to be able to use the logging macros from the [`log`][1] crate. We can do this by
|
||||
implementing the `Log` trait.
|
||||
|
||||
```rust,editable,compile_fail
|
||||
{{#include examples/src/logger.rs:main}}
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
* The unwrap in `log` is safe because we initialise `LOGGER` before calling `set_logger`.
|
||||
|
||||
</details>
|
||||
|
||||
[1]: https://crates.io/crates/log
|
13
src/bare-metal/aps/logging/using.md
Normal file
13
src/bare-metal/aps/logging/using.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Using it
|
||||
|
||||
We need to initialise the logger before we use it.
|
||||
|
||||
```rust,editable,compile_fail
|
||||
{{#include ../examples/src/main_logger.rs:main}}
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
* Note that our panic handler can now log details of panics.
|
||||
|
||||
</details>
|
Loading…
Reference in New Issue
Block a user