Skip to main content

Bus

Struct Bus 

Source
pub struct Bus { /* private fields */ }
Expand description

A checked bus: the CPU, the memory map, and every peripheral instance with its register file.

It answers where an address lands and what that register holds. It doesn’t answer what the peripheral does. That’s the model, which is a field of the MCU built on this bus.

Implementations§

Source§

impl Bus

Source

pub fn builder( cpu: Cpu, memory: &'static [Region], peripherals: impl IntoIterator<Item = Peripheral>, ) -> Builder

Starts assembling a bus from its CPU, memory map, and peripheral instances.

Source

pub fn slots(&self) -> &[Slot]

Every slot, in address order. The index is what crate::mcu::Mcu::split dispatches on.

Source

pub fn reset(&mut self)

The part as a system reset leaves it: every register at its reset value and nothing scheduled, driven, or waiting for an answer.

Source

pub fn slot_of(&self, name: &str) -> Option<usize>

The slot index of the instance called name, which an MCU resolves once at construction so that nothing after it looks a peripheral up by string.

Source

pub fn slot(&self, name: &'static str) -> Result<usize, Error>

The slot index of the instance called name, as Bus::slot_of finds it, or Error::UnknownInstance where the bus carries none.

§Errors

If no instance is called name.

Source

pub fn slot_at(&self, address: u64) -> Option<usize>

The slot an address falls in, or None where no instance covers it.

The same search an access decodes with, for a caller that wants to know which instance an address belongs to without making the access.

Source

pub fn cpu(&self) -> Cpu

The CPU.

Source

pub fn memory(&self) -> &[Region]

The memory regions, the description’s and then each one a board added.

Source

pub fn add_region(&mut self, region: Region) -> Result<(), Error>

Adds a region of memory a board fits outside the part, like RAM or flash on its external memory interface. The emulator maps it as it maps the part’s own, an image can be placed in it, and a model’s requested access reaches it.

Fails when the region shares a name or an address with a region, an instance or a window already there, runs past the last address, its erase blocks don’t add up to its size, or it names a programmer the part doesn’t have or is RAM with one.

Source

pub fn add_window(&mut self, window: Window) -> Result<usize, Error>

Adds a window for a board’s chip and returns its slot. The slot comes after every existing slot, so no slot a part already resolved moves. Fails like Bus::add_region, and also when the gate or an interrupt names something the bus doesn’t have.

Source

pub fn keep_added(&mut self, from: &Bus) -> Result<(), Error>

Copies the regions and windows a board added to from onto this bus, with each window in the same slot, and goes on numbering events from where from stood, so an id a chip kept from before is never a new event’s. A part that rebuilds its bus on reset uses this to keep them.

Fails, with nothing copied, unless self is fresh from the same description as from: the same CPU, regions and instances, and nothing added yet. Otherwise a window would land on another slot than the one its chip answers for.

Source

pub fn peripherals(&self) -> impl Iterator<Item = &Peripheral>

Every peripheral instance, by ascending base address.

Source

pub fn peripheral(&self, name: &str) -> Option<&Peripheral>

The instance with this name.

Source

pub fn registers(&self, name: &str) -> Option<&RegisterFile>

The register file of the instance with this name.

Source

pub fn drive( &mut self, at: VirtualNanos, slot: usize, ) -> (&mut RegisterFile, DeviceContext<'_>)

The registers of the instance at slot and a context for its model at at, as an access hands them over, for an input the bus doesn’t carry: a level on a pin, a sample, a word from a chip. A part’s drive_ method is this with its model’s field named beside it. What the model does with the context, an event, an interrupt or a request, settles when the run resumes from the stop the input was handed over at, so the firmware sees it at that same stop.

§Panics

If slot is past the end of Bus::slots.

Source

pub fn slot_mut(&mut self, index: usize) -> &mut Slot

The slot at index, for the MCU that owns its model. A part’s setter that changes what its registers hold with no instant to schedule from, like a supply that sets a status bit, writes through it. One that schedules or raises goes through Bus::drive.

§Panics

If index is past the end of Bus::slots.

Source

pub fn next_event(&self) -> Option<VirtualNanos>

The instant of the earliest pending event, which is when the emulator next needs to stop.

Source

pub fn clock_of(&self, instance: &str) -> Option<Clock>

The clock each instance runs on, by name, for a check that every instance keeping time has one.

Trait Implementations§

Source§

impl Debug for Bus

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Store for Bus

Source§

fn store(&self, to: &mut Writer) -> Result<(), Error>

Writes what a restore needs to put self back as it stands.
Source§

fn load(&mut self, from: &mut Reader) -> Result<(), Error>

Reads what Store::store wrote back into a freshly built self of the same shape.

Auto Trait Implementations§

§

impl Freeze for Bus

§

impl RefUnwindSafe for Bus

§

impl Send for Bus

§

impl Sync for Bus

§

impl Unpin for Bus

§

impl UnsafeUnpin for Bus

§

impl UnwindSafe for Bus

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.