Struct hal_x86_64::time::Pit
source · pub struct Pit { /* private fields */ }
Expand description
Intel 8253/8254 Programmable Interval Timer (PIT).
The PIT is a simple timer, with three channels. The most interesting is channel 0, which is capable of firing an interrupt to the 8259 PIC or I/O APIC on ISA interrupt vector 0. Channel 1 was used to time the DRAM refresh rate on ancient IBM PCs and is now generally unused (and may not be implemented in hardware), and channel 2 was connected to the IBM PC speaker and could be used to play sounds.
The PIT has a non-configurable base frequency of 1.193182 MHz, for extremely cool reasons, but a 16-bit divisor can be used to determine what multiple of this base frequency each channel fires at.
Implementations§
source§impl Pit
impl Pit
sourcepub const BASE_FREQUENCY_HZ: usize = 1_193_180usize
pub const BASE_FREQUENCY_HZ: usize = 1_193_180usize
The PIT’s base frequency runs at roughly 1.193182 MHz, for extremely cool reasons.
sourcepub fn sleep_blocking(&mut self, duration: Duration) -> Result<(), PitError>
pub fn sleep_blocking(&mut self, duration: Duration) -> Result<(), PitError>
Sleep (by spinning) for duration
.
This function sets a flag indicating that a sleep is in progress, and
configures the PIT to fire an interrupt on channel 0 in duration
. It then
spins until the flag is cleared by an interrupt handler.
Usage Notes
This is a low-level way of sleeping, and is not recommended for use as a system’s primary method of sleeping for a duration. Instead, a timer wheel or other way of tracking multiple sleepers should be constructed and advanced based on a periodic timer. This function is provided primarily to allow using the PIT to calibrate other timers as part of initialization code, rather than for general purpose use in an operating system.
In particular, using this function is subject to the following considerations:
- An interrupt handler for the PIT interrupt which clears the sleeping flag
must be installed. This is done automatically by the
Controller::init
function in theinterrupt
module. If that interrupt handler is not present, this function will spin forever! - If the PIT is currently in periodic mode, it will be put in oneshot mode when this function is called. This will temporarily disable the existing periodic timer.
- This function returns an error if another CPU core is already sleeping. It should generally be used only prior to the initialization of application processors.
Returns
Ok
(())
afterduration
if a sleep was successfully completed.Err
(
InvalidDuration
)
if the provided duration was too long.
sourcepub fn start_periodic_timer(
&mut self,
interval: Duration
) -> Result<(), PitError>
pub fn start_periodic_timer( &mut self, interval: Duration ) -> Result<(), PitError>
Configures PIT channel 0 in periodic mode, to fire an interrupt every
time the provided interval
elapses.
Returns
Ok
(())
if the timer was successfully configured in periodic mode.Err
(
InvalidDuration
)
if the providedDuration
was too long.
sourcepub fn interrupt_in(
&mut self,
duration: Duration
) -> Result<(), InvalidDuration>
pub fn interrupt_in( &mut self, duration: Duration ) -> Result<(), InvalidDuration>
Configure the PIT to send an IRQ 0 interrupt in duration
.
This configures the PIT in mode 0 (oneshot mode). Once the interrupt has
fired, in order to use the periodic timer, the pit must be put back into
periodic mode by calling Pit::start_periodic_timer
.