module_driver

Macro module_driver 

Source
macro_rules! module_driver {
    (
        $($i:ident : $t:expr),+,
    ) => { ... };
}
Expand description

Macro for generating a driver module.

This macro automatically generates a driver registration module that creates a static DriverRegister struct containing driver metadata (such as name, probe level, priority, and probe types). The generated static variable is placed in the special linker section .driver.register to be automatically discovered and registered by the driver manager at runtime.

§Parameters

  • $i:ident: Field identifier (e.g., name, level, priority, probe_kinds)
  • $t:expr: Expression for the corresponding field value

§Generated Code

The macro generates a module containing a static DriverRegister that:

  • Uses #[link_section = ".driver.register"] attribute to place it in a special linker section
  • Uses #[no_mangle] and #[used] to prevent compiler optimization
  • Contains all driver registration information

§Example

use rdrive::{
    module_driver,
    driver::*,
    register::FdtInfo,
    probe::OnProbeError,
    PlatformDevice,
};

struct UartDriver {}

impl DriverGeneric for UartDriver {
    fn open(&mut self) -> Result<(), rdrive::KError> { todo!() }
    fn close(&mut self) -> Result<(), rdrive::KError> { todo!() }
}

impl rdif_serial::Interface for UartDriver {
    fn handle_irq(&mut self) { todo!() }
    fn take_tx(&mut self) -> Option<Box<(dyn rdif_serial::io::Write + 'static)>> { todo!() }
    fn take_rx(&mut self) -> Option<Box<(dyn rdif_serial::io::Read + 'static)>> { todo!() }
}

// Define probe function
fn probe_uart(fdt: FdtInfo<'_>, dev: PlatformDevice) -> Result<(), OnProbeError> {
    // Implement specific device probing logic
    dev.register(rdif_serial::Serial::new(UartDriver{}));
    Ok(())
}

// Use macro to generate driver registration module
module_driver! {
    name: "UART Driver",
    level: ProbeLevel::PostKernel,
    priority: ProbePriority::DEFAULT,
    probe_kinds: &[ProbeKind::Fdt {
        compatibles: &["ns16550a", "arm,pl011"],
        // Use `probe_uart` above; this usage is because doctests cannot find the parent module.
        on_probe: |fdt, dev|{
            Ok(())
        },
    }],
}

§Notes

  • This macro can only be used once per driver module
  • The generated module name is automatically derived from the driver name
  • All fields must be properly set, especially the probe_kinds array
  • Probe functions must implement the correct signature and error handling