5 个不稳定版本
0.2.0 | 2021年7月13日 |
---|---|
0.1.2 | 2021年6月4日 |
0.1.1 | 2020年12月19日 |
0.1.0 | 2020年11月26日 |
0.0.0 | 2020年10月6日 |
#1897 在 硬件支持 中
47KB
706 行
ps2
nightly Rust 通用 PS/2 设备驱动程序。
贡献
欢迎在GitHub上提交错误报告和拉取请求:[https://github.com/lucis-fluxum/ps2-rs](https://github.com/lucis-fluxum/ps2-rs)。
许可证
本crate作为开源软件,根据[https://opensource.org/licenses/MIT](https://opensource.org/licenses/MIT) MIT许可证的条款提供。
除非你明确表示,否则你提交的任何有意包含在`ps2-rs`中的贡献,都应按MIT许可证许可,不附加任何额外的条款或条件。
lib.rs
:
本crate提供了对PS/2控制器和PS/2设备的全面底层访问。它使用带超时的轮询方法来读写IO端口的请求数据。
示例
以下示例实现了OSDev wiki上概述的初始化过程[https://web.archive.org/web/20201112021519/https://wiki.osdev.org/%228042%22_PS/2_Controller#Initialising_the_PS.2F2_Controller](https://web.archive.org/web/20201112021519/https://wiki.osdev.org/%228042%22_PS/2_Controller#Initialising_the_PS.2F2_Controller)。我们通过假设PS/2控制器存在并且当前硬件支持它来跳过步骤1和2。
use ps2::{Controller, error::ControllerError, flags::ControllerConfigFlags};
fn initialize() -> Result<(), ControllerError> {
let mut controller = unsafe { Controller::new() };
// Step 3: Disable devices
controller.disable_keyboard()?;
controller.disable_mouse()?;
// Step 4: Flush data buffer
let _ = controller.read_data();
// Step 5: Set config
let mut config = controller.read_config()?;
// Disable interrupts and scancode translation
config.set(
ControllerConfigFlags::ENABLE_KEYBOARD_INTERRUPT
| ControllerConfigFlags::ENABLE_MOUSE_INTERRUPT
| ControllerConfigFlags::ENABLE_TRANSLATE,
false,
);
controller.write_config(config)?;
// Step 6: Controller self-test
controller.test_controller()?;
// Write config again in case of controller reset
controller.write_config(config)?;
// Step 7: Determine if there are 2 devices
let has_mouse = if config.contains(ControllerConfigFlags::DISABLE_MOUSE) {
controller.enable_mouse()?;
config = controller.read_config()?;
// If mouse is working, this should now be unset
!config.contains(ControllerConfigFlags::DISABLE_MOUSE)
} else {
false
};
// Disable mouse. If there's no mouse, this is ignored
controller.disable_mouse()?;
// Step 8: Interface tests
let keyboard_works = controller.test_keyboard().is_ok();
let mouse_works = has_mouse && controller.test_mouse().is_ok();
// Step 9 - 10: Enable and reset devices
config = controller.read_config()?;
if keyboard_works {
controller.enable_keyboard()?;
config.set(ControllerConfigFlags::DISABLE_KEYBOARD, false);
config.set(ControllerConfigFlags::ENABLE_KEYBOARD_INTERRUPT, true);
controller.keyboard().reset_and_self_test().unwrap();
}
if mouse_works {
controller.enable_mouse()?;
config.set(ControllerConfigFlags::DISABLE_MOUSE, false);
config.set(ControllerConfigFlags::ENABLE_MOUSE_INTERRUPT, true);
controller.mouse().reset_and_self_test().unwrap();
// This will start streaming events from the mouse
controller.mouse().enable_data_reporting().unwrap();
}
// Write last configuration to enable devices and interrupts
controller.write_config(config)?;
Ok(())
}
一旦控制器初始化并设备正常工作,它们将输入放置在IO端口`0x60`的数据缓冲区中。您可以在任何时候使用Controller::read_data
从该缓冲区读取。如果您计划使用基于轮询的方法处理设备输入,请注意,任一设备都可能随时向该缓冲区写入数据,并且据我所知,没有方法可以确定哪些字节来自哪个设备。
处理输入的一个更好的方法是使用中断:为IRQ1(键盘)和IRQ12(鼠标)定义处理程序,然后读取数据。您可以使用Controller::read_data
来读取键盘和鼠标数据,或者您可以使用Mouse::read_data_packet
,这是一个围绕Controller::read_data
的方便包装器,用于鼠标数据包。
进一步阅读
以下是我开发这个库时使用的资源。请注意,一些描述PS/2协议的资源之间存在冲突,因此这个库是我对测试和验证这些资源准确性的最佳努力。如果您发现某些内容缺失或不完全正确,请随时提出问题。
- Adam Chapweske的旧网站,有几篇详细的说明。
- Andries Brouwer的“键盘扫描码”,它涉及的内容远不止扫描码。
- OSDev维基百科上关于PS/2控制器、键盘、鼠标和鼠标输入的页面。
- 这个PDF文件看起来是来自操作系统开发课程。我发现语言非常易于理解,对学习很多相关术语非常有帮助。
- 关于PS/2寄存器和命令的此摘要。有关键盘命令,请参阅此处。
依赖项
~565KB
~11K SLoC