mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-04-19 14:52:36 +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)
|
- [Multiple registers](bare-metal/aps/better-uart/registers.md)
|
||||||
- [Driver](bare-metal/aps/better-uart/driver.md)
|
- [Driver](bare-metal/aps/better-uart/driver.md)
|
||||||
- [Using it](bare-metal/aps/better-uart/using.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)
|
- [Other projects](bare-metal/aps/other-projects.md)
|
||||||
- [Useful crates]()
|
- [Useful crates]()
|
||||||
- [zerocopy]()
|
- [zerocopy]()
|
||||||
|
@ -21,3 +21,7 @@ path = "src/main_minimal.rs"
|
|||||||
[[bin]]
|
[[bin]]
|
||||||
name = "improved"
|
name = "improved"
|
||||||
path = "src/main_improved.rs"
|
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
|
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/minimal minimal.bin
|
||||||
improved.bin: build
|
improved.bin: build
|
||||||
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/improved improved.bin
|
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_minimal: minimal.bin
|
||||||
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel minimal.bin -s
|
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel minimal.bin -s
|
||||||
qemu: improved.bin
|
qemu: improved.bin
|
||||||
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel improved.bin -s
|
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:
|
clean:
|
||||||
cargo 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…
x
Reference in New Issue
Block a user