Skip to main content

proka_kernel/drivers/char/
serial.rs

1extern crate alloc;
2
3use super::super::{CharDevice, Device, DeviceError, DeviceInner, DeviceType, SharedDeviceOps};
4use alloc::format;
5use alloc::string::{String, ToString};
6use alloc::sync::Arc;
7use spin::RwLock;
8use uart_16550::SerialPort;
9
10pub struct SerialDevice {
11    port_address: u16,
12    name: String,
13    serial_port: RwLock<SerialPort>,
14}
15
16impl SerialDevice {
17    pub fn new(port_address: u16) -> Self {
18        let mut serial_port = unsafe { SerialPort::new(port_address) };
19        serial_port.init();
20        Self {
21            port_address,
22            name: format!("serial-{}", port_address),
23            serial_port: RwLock::new(serial_port),
24        }
25    }
26
27    /// 创建一个串口字符设备实例,并封装为通用的 `Device` 结构。
28    /// 用户需要手动指定 major/minor 号。
29    pub fn create_device(major: u16, minor: u16, port_address: u16) -> Device {
30        let serial = Arc::new(SerialDevice::new(port_address));
31        Device::new(
32            serial.name().to_string(),
33            major,
34            minor,
35            DeviceInner::Char(serial),
36        )
37    }
38
39    /// 创建一个串口字符设备实例,并让 `DeviceManager` 自动分配 major/minor 号。
40    pub fn create_device_auto_assign(port_address: u16) -> Device {
41        let serial = Arc::new(SerialDevice::new(port_address));
42        Device::new_auto_assign(serial.name().to_string(), DeviceInner::Char(serial))
43    }
44}
45
46impl SharedDeviceOps for SerialDevice {
47    fn name(&self) -> &str {
48        &self.name
49    }
50
51    fn device_type(&self) -> DeviceType {
52        DeviceType::Char
53    }
54
55    fn open(&self) -> Result<(), DeviceError> {
56        Ok(())
57    }
58
59    fn close(&self) -> Result<(), DeviceError> {
60        Ok(())
61    }
62
63    fn ioctl(&self, cmd: u64, _arg: u64) -> Result<u64, DeviceError> {
64        match cmd {
65            1 => Ok(self.port_address as u64),
66            _ => Err(DeviceError::NotSupported),
67        }
68    }
69}
70
71impl CharDevice for SerialDevice {
72    fn read(&self, _buf: &mut [u8]) -> Result<usize, DeviceError> {
73        Err(DeviceError::NotSupported)
74    }
75
76    fn write(&self, buf: &[u8]) -> Result<usize, DeviceError> {
77        let mut serial_port = self.serial_port.write();
78        for byte in buf {
79            serial_port.send(*byte);
80        }
81        Ok(buf.len())
82    }
83}