FreeBSD Implementation (ACPI)
Relevant source files
The following files were used as context for generating this wiki page:
The FreeBSD implementation of the battery crate provides access to battery information via the Advanced Configuration and Power Interface (ACPI). It leverages the FreeBSD /dev/acpi device and ioctl calls to retrieve hardware-level data, which is then normalized into the project's unified cross-platform API.
This module is responsible for communicating with the FreeBSD kernel to fetch Battery Information (BIF) and Battery Status (BST). It handles the conversion of OS-specific raw values—which may be reported in either Metric (Watts/Watt-hours) or Imperial (Amperes/Ampere-hours) units—into standard SI units used throughout the library.
Sources: src/platform/freebsd/acpi.rs:188-192, src/platform/freebsd/device.rs:51-78, src/platform/mod.rs:25-29
Core Architecture and Data Flow
The architecture follows a layered approach where raw FFI structures are mapped to internal device representations. The IoCtlDevice implements the common BatteryDevice trait, ensuring consistency with other platforms like Linux or macOS.
System Interaction
The implementation interacts with the FreeBSD kernel by opening /dev/acpi and using specific ioctl commands to query battery units and individual battery statistics.
The diagram shows the flow from the low-level kernel interface through the ACPI data structures to the high-level IoCtlDevice.
Sources: src/platform/freebsd/acpi.rs:188-232, src/platform/freebsd/device.rs:27-49, src/platform/traits.rs:49-65
Key Data Structures
The implementation relies on two primary C-compatible structures defined in the FreeBSD acpiio.h header.
AcpiBif (Battery Information)
This structure contains static information about the battery that does not change frequently, such as design capacity and technology.
| Field | Type | Description |
|---|---|---|
units | u32 | Indicates if capacity/rate is in mW/mWh (0) or mA/mAh (1) |
dcap | u32 | Design capacity |
lfcap | u32 | Last full capacity |
btech | u32 | Battery technology |
dvol | u32 | Design voltage in mV |
model | [u8; 32] | Model identifier string |
serial | [u8; 32] | Serial number string |
type_ | [u8; 32] | Battery chemistry type (e.g., "LION") |
Sources: src/platform/freebsd/acpi.rs:38-53
AcpiBst (Battery Status)
This structure contains dynamic, real-time data regarding the battery's current state.
| Field | Type | Description |
|---|---|---|
state | u32 | Current state (Charging, Discharging, Critical) |
rate | u32 | Present rate of energy flow |
cap | u32 | Remaining capacity |
volt | u32 | Present voltage |
Sources: src/platform/freebsd/acpi.rs:118-123
Logic and Data Normalization
FreeBSD may report values in different units based on the units field in AcpiBif. The IoCtlDevice::refresh method performs the necessary calculations to ensure all data is returned as Energy, Power, or ElectricPotential types.
Unit Conversion Sequence
When the system reports values in Amperes (ACPI_BIF_UNITS_MA), the implementation multiplies these values by the design_voltage to obtain Watt-based measurements.
The sequence illustrates how the device decides whether to scale raw values by the design voltage based on the reported ACPI units.
Sources: src/platform/freebsd/acpi.rs:72-78, src/platform/freebsd/device.rs:55-75
State Mapping
The raw ACPI state bitmask is mapped to the internal State enum. Notable logic includes handling the ACPI_BATT_STAT_INVALID mask and treating ACPI_BATT_STAT_CRITICAL as a discharging state.
pub fn state(&self) -> State {
match self.state {
ACPI_BATT_STAT_FULL => State::Full,
value if value & ACPI_BATT_STAT_DISCHARG != 0 => State::Discharging,
value if value & ACPI_BATT_STAT_CHARGING != 0 => State::Charging,
value if value & ACPI_BATT_STAT_CRITICAL != 0 => State::Discharging,
_ => State::Unknown,
}
}
Sources: src/platform/freebsd/acpi.rs:132-145
IO Control Interface
The interface uses the nix crate to define ioctl calls. Three main operations are supported:
acpiio_batt_get_units: Retrieves the total count of battery units available in the system.acpiio_batt_get_bif: Retrieves static battery information for a specific unit index.acpiio_batt_get_bst: Retrieves dynamic battery status for a specific unit index.
The AcpiDevice struct manages the raw file descriptor for /dev/acpi and ensures it is closed upon being dropped.
Sources: src/platform/freebsd/acpi.rs:163-232, src/lib.rs:30-32
Technology Identification
Battery technology is determined by parsing the type_ string from the AcpiBif structure. This string is matched against known battery chemistries defined in the Technology enum, such as "LION", "NiMH", or "PbAc".
Sources: src/platform/freebsd/acpi.rs:88-97, src/types/technology.rs:25-45
Conclusion
The FreeBSD ACPI implementation provides a robust bridge between the FreeBSD kernel's power management subsystem and the rust-battery library. By abstracting the complexities of ioctl communication and unit normalization, it allows the rest of the library to treat FreeBSD batteries as standard device objects while maintaining high technical accuracy regarding hardware state.