kernel/device/char/
mod.rs

1use core::any::Any;
2
3use super::Device;
4
5extern crate alloc;
6
7/// Character device interface
8/// 
9/// This trait defines the interface for character devices.
10/// It provides methods for querying device information and handling character I/O operations.
11/// Uses internal mutability for thread-safe shared access.
12pub trait CharDevice: Device {
13    /// Read a single byte from the device
14    /// 
15    /// For blocking devices (like TTY), this method will block until data is available.
16    /// For non-blocking devices, this returns None if no data is available.
17    /// 
18    /// # Returns
19    /// 
20    /// The byte read from the device, or None if no data is available
21    fn read_byte(&self) -> Option<u8>;
22    
23    /// Write a single byte to the device
24    /// 
25    /// # Arguments
26    /// 
27    /// * `byte` - The byte to write to the device
28    /// 
29    /// # Returns
30    /// 
31    /// Result indicating success or failure
32    fn write_byte(&self, byte: u8) -> Result<(), &'static str>;
33    
34    /// Read multiple bytes from the device
35    /// 
36    /// # Arguments
37    /// 
38    /// * `buffer` - The buffer to read data into
39    /// 
40    /// # Returns
41    /// 
42    /// The number of bytes actually read
43    fn read(&self, buffer: &mut [u8]) -> usize {
44        let mut bytes_read = 0;
45        for i in 0..buffer.len() {
46            if let Some(byte) = self.read_byte() {
47                buffer[i] = byte;
48                bytes_read += 1;
49            } else {
50                break;
51            }
52        }
53        bytes_read
54    }
55    
56    /// Write multiple bytes to the device
57    /// 
58    /// # Arguments
59    /// 
60    /// * `buffer` - The buffer containing data to write
61    /// 
62    /// # Returns
63    /// 
64    /// Result containing the number of bytes written or an error
65    fn write(&self, buffer: &[u8]) -> Result<usize, &'static str> {
66        let mut bytes_written = 0;
67        for &byte in buffer {
68            self.write_byte(byte)?;
69            bytes_written += 1;
70        }
71        Ok(bytes_written)
72    }
73    
74    /// Check if the device is ready for reading
75    fn can_read(&self) -> bool;
76    
77    /// Check if the device is ready for writing
78    fn can_write(&self) -> bool;
79}
80
81/// A generic implementation of a character device
82pub struct GenericCharDevice {
83    device_name: &'static str,
84    read_fn: fn() -> Option<u8>,
85    write_fn: fn(u8) -> Result<(), &'static str>,
86    can_read_fn: fn() -> bool,
87    can_write_fn: fn() -> bool,
88}
89
90impl GenericCharDevice {
91    pub fn new(
92        device_name: &'static str, 
93        read_fn: fn() -> Option<u8>,
94        write_fn: fn(u8) -> Result<(), &'static str>,
95        can_read_fn: fn() -> bool,
96        can_write_fn: fn() -> bool,
97    ) -> Self {
98        Self { 
99            device_name, 
100            read_fn, 
101            write_fn,
102            can_read_fn,
103            can_write_fn,
104        }
105    }
106}
107
108impl Device for GenericCharDevice {
109    fn device_type(&self) -> super::DeviceType {
110        super::DeviceType::Char
111    }
112
113    fn name(&self) -> &'static str {
114        self.device_name
115    }
116
117    fn as_any(&self) -> &dyn Any {
118        self
119    }
120    
121    fn as_any_mut(&mut self) -> &mut dyn Any {
122        self
123    }
124    
125    fn as_char_device(&self) -> Option<&dyn CharDevice> {
126        Some(self)
127    }
128}
129
130impl CharDevice for GenericCharDevice {
131    fn read_byte(&self) -> Option<u8> {
132        (self.read_fn)()
133    }
134
135    fn write_byte(&self, byte: u8) -> Result<(), &'static str> {
136        (self.write_fn)(byte)
137    }
138
139    fn can_read(&self) -> bool {
140        (self.can_read_fn)()
141    }
142
143    fn can_write(&self) -> bool {
144        (self.can_write_fn)()
145    }
146}
147
148#[cfg(test)]
149mod tests;
150
151#[cfg(test)]
152pub mod mockchar;
153
154pub mod tty;