fdt_rs/
lib.rs

1//! A flattened device tree (FDT) parser for embedded, low memory, and safety-critical no-std
2//! environments.
3//!
4//! Includes the following features:
5//!
6//! * [Low-level FDT parsing utilities to build your own library](base::parse)
7//! * [Simple utilites based on in-order parsing of the FDT](base)
8//! * [Performant utilities which leverage an index built over the FDT](index)
9//!
10//! ## Features
11//!
12//! This crate can be used without the standard library (`#![no_std]`) by disabling
13//! the default `std` feature. To use `no-std` place the following in your `Cargo.toml`:
14//!
15//! ```toml
16//! [dependencies.fdt-rs]
17//! version = "x"
18//! default-features = false
19//! ```
20//!
21//! ## Examples
22//!
23//!
24#![deny(clippy::all, clippy::cargo)]
25#![allow(clippy::as_conversions)]
26#![cfg_attr(not(feature = "std"), no_std)]
27
28#[cfg(feature = "std")]
29extern crate core;
30extern crate endian_type_rs as endian_type;
31#[macro_use]
32extern crate memoffset;
33#[macro_use]
34extern crate static_assertions;
35extern crate fallible_iterator;
36extern crate unsafe_unwrap;
37
38pub mod base;
39pub mod error;
40pub mod index;
41pub mod prelude;
42pub mod spec;
43
44#[doc(hidden)]
45pub mod common;
46
47pub(crate) mod priv_util;
48
49// When the doctest feature is enabled, add these utility functions.
50#[cfg(all(any(feature = "doctest", doc), feature = "std"))]
51#[doc(hidden)]
52pub mod doctest {
53    pub use crate::base::*;
54    pub use crate::index::*;
55    pub use crate::prelude::*;
56
57    // from https://github.com/rust-lang/cargo/issues/383#issuecomment-720873790
58    macro_rules! external_doc_test {
59        ($x:expr) => {
60            #[doc = $x]
61            extern "C" {}
62        };
63    }
64
65    external_doc_test!(include_str!("../README.md"));
66
67    #[repr(align(4))]
68    struct _Wrapper<T>(T);
69    pub const FDT: &[u8] = &_Wrapper(*include_bytes!("../tests/riscv64-virt.dtb")).0;
70
71    pub fn doctest_index<'i, 'dt: 'i>() -> (DevTreeIndex<'i, 'dt>, Vec<u8>) {
72        // Create the device tree parser
73        let devtree = unsafe { DevTree::new(FDT) }.unwrap();
74
75        // Get the layout required to build an index
76        let layout = DevTreeIndex::get_layout(&devtree).unwrap();
77
78        // Allocate memory for the index.
79        //
80        // This could be performed without a dynamic allocation
81        // if we allocated a static buffer or want to provide a
82        // raw buffer into uninitialized memory.
83        let mut vec = vec![0u8; layout.size() + layout.align()];
84        let (p, s) = (vec.as_mut_ptr(), vec.len());
85        unsafe {
86            let vec_copy = core::slice::from_raw_parts_mut(p, s);
87            (DevTreeIndex::new(devtree, vec_copy).unwrap(), vec)
88        }
89    }
90}