zephyr/device/
flash.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//! Device wrappers for flash controllers, and flash partitions.

// Note that currently, the flash partition shares the controller, so the underlying operations
// are not actually safe.  Need to rethink how to manage this.

use super::{NoStatic, Unique};
use crate::raw;

/// A flash controller
///
/// This is a wrapper around the `struct device` in Zephyr that represents a flash controller.
/// Using the flash controller allows flash operations on the entire device.  See
/// [`FlashPartition`] for a wrapper that limits the operation to a partition as defined in the
/// DT.
#[allow(dead_code)]
pub struct FlashController {
    pub(crate) device: *const raw::device,
}

impl FlashController {
    /// Constructor, intended to be called by devicetree generated code.
    #[allow(dead_code)]
    pub(crate) unsafe fn new(
        unique: &Unique,
        _static: &NoStatic,
        device: *const raw::device,
    ) -> Option<FlashController> {
        if !unique.once() {
            return None;
        }

        Some(FlashController { device })
    }
}

/// A wrapper for flash partitions.  There is no Zephyr struct that corresponds with this
/// information, which is typically used in a more direct underlying manner.
#[allow(dead_code)]
pub struct FlashPartition {
    /// The underlying controller.
    #[allow(dead_code)]
    pub(crate) controller: FlashController,
    #[allow(dead_code)]
    pub(crate) offset: u32,
    #[allow(dead_code)]
    pub(crate) size: u32,
}

impl FlashPartition {
    /// Constructor, intended to be called by devicetree generated code.
    #[allow(dead_code)]
    pub(crate) unsafe fn new(
        unique: &Unique,
        _static: &NoStatic,
        device: *const raw::device,
        offset: u32,
        size: u32,
    ) -> Option<FlashPartition> {
        if !unique.once() {
            return None;
        }

        // The `get_instance` on the flash controller would try to guarantee a unique instance,
        // but in this case, we need one for each device, so just construct it here.
        // TODO: This is not actually safe.
        let controller = FlashController { device };
        Some(FlashPartition {
            controller,
            offset,
            size,
        })
    }
}