|
@@ -1,22 +1,38 @@
|
|
|
-use super::super::base::device::Device;
|
|
|
use crate::{
|
|
|
- driver::base::{
|
|
|
- char::CharDevice,
|
|
|
- device::{driver::Driver, DeviceState, DeviceType, IdTable, KObject},
|
|
|
- platform::{
|
|
|
- self, platform_device::PlatformDevice, platform_driver::PlatformDriver, CompatibleTable,
|
|
|
+ driver::{
|
|
|
+ base::{
|
|
|
+ char::CharDevice,
|
|
|
+ device::{
|
|
|
+ driver::DriverError, Device, DeviceError, DeviceNumber, DevicePrivateData,
|
|
|
+ DeviceResource, DeviceState, DeviceType, IdTable, KObject, DEVICE_MANAGER,
|
|
|
+ },
|
|
|
+ platform::{
|
|
|
+ platform_device::PlatformDevice, platform_driver::PlatformDriver, CompatibleTable,
|
|
|
+ },
|
|
|
},
|
|
|
+ Driver,
|
|
|
},
|
|
|
filesystem::{
|
|
|
+ devfs::{devfs_register, DevFS, DeviceINode},
|
|
|
sysfs::bus::{bus_device_register, bus_driver_register},
|
|
|
- vfs::IndexNode,
|
|
|
+ vfs::{FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus},
|
|
|
},
|
|
|
include::bindings::bindings::{io_in8, io_out8},
|
|
|
+ kinfo,
|
|
|
libs::spinlock::SpinLock,
|
|
|
syscall::SystemError,
|
|
|
};
|
|
|
-use alloc::sync::Arc;
|
|
|
-use core::{char, intrinsics::offset, str};
|
|
|
+use alloc::{
|
|
|
+ string::{String, ToString},
|
|
|
+ sync::{Arc, Weak},
|
|
|
+ vec::Vec,
|
|
|
+};
|
|
|
+use core::{
|
|
|
+ any::Any,
|
|
|
+ char,
|
|
|
+ intrinsics::offset,
|
|
|
+ str::{self, from_utf8},
|
|
|
+};
|
|
|
|
|
|
const UART_SUCCESS: i32 = 0;
|
|
|
const E_UART_BITS_RATE_ERROR: i32 = 1;
|
|
@@ -100,17 +116,34 @@ struct UartRegister {
|
|
|
// @brief 串口设备结构体
|
|
|
#[derive(Debug)]
|
|
|
pub struct Uart {
|
|
|
- state: DeviceState, // 设备状态
|
|
|
+ private_data: DevicePrivateData, // 设备状态
|
|
|
sys_info: Option<Arc<dyn IndexNode>>,
|
|
|
- driver: Option<Arc<dyn PlatformDriver>>,
|
|
|
+ fs: Weak<DevFS>, // 文件系统
|
|
|
+ port: UartPort,
|
|
|
+ baud_rate: u32,
|
|
|
+ metadata: Metadata,
|
|
|
}
|
|
|
|
|
|
impl Default for Uart {
|
|
|
fn default() -> Self {
|
|
|
+ let mut metadata = Metadata::default();
|
|
|
+ metadata.file_type = FileType::CharDevice;
|
|
|
+ c_uart_init(UartPort::COM1.to_u16(), 115200);
|
|
|
Self {
|
|
|
- state: DeviceState::NotInitialized,
|
|
|
+ private_data: DevicePrivateData::new(
|
|
|
+ IdTable::new(
|
|
|
+ "uart".to_string(),
|
|
|
+ DeviceNumber::new(DeviceNumber::from_major_minor(4, 64)),
|
|
|
+ ),
|
|
|
+ None,
|
|
|
+ CompatibleTable::new(vec!["uart"]),
|
|
|
+ DeviceState::NotInitialized,
|
|
|
+ ),
|
|
|
sys_info: None,
|
|
|
- driver: None,
|
|
|
+ fs: Weak::default(),
|
|
|
+ port: UartPort::COM1,
|
|
|
+ baud_rate: 115200,
|
|
|
+ metadata,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -128,12 +161,8 @@ impl Default for LockedUart {
|
|
|
impl KObject for LockedUart {}
|
|
|
|
|
|
impl PlatformDevice for LockedUart {
|
|
|
- fn compatible_table(&self) -> platform::CompatibleTable {
|
|
|
- platform::CompatibleTable::new(vec!["uart"])
|
|
|
- }
|
|
|
-
|
|
|
fn is_initialized(&self) -> bool {
|
|
|
- let state = self.0.lock().state;
|
|
|
+ let state = self.0.lock().private_data.state();
|
|
|
match state {
|
|
|
DeviceState::Initialized => true,
|
|
|
_ => false,
|
|
@@ -141,18 +170,20 @@ impl PlatformDevice for LockedUart {
|
|
|
}
|
|
|
|
|
|
fn set_state(&self, set_state: DeviceState) {
|
|
|
- let state = &mut self.0.lock().state;
|
|
|
- *state = set_state;
|
|
|
+ self.0.lock().private_data.set_state(set_state);
|
|
|
}
|
|
|
|
|
|
- fn set_driver(&self, driver: Option<Arc<dyn PlatformDriver>>) {
|
|
|
- self.0.lock().driver = driver;
|
|
|
+ fn compatible_table(&self) -> CompatibleTable {
|
|
|
+ return self.0.lock().private_data.compatible_table().clone();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
impl Device for LockedUart {
|
|
|
fn id_table(&self) -> IdTable {
|
|
|
- IdTable::new("uart", 0)
|
|
|
+ return IdTable::new(
|
|
|
+ "uart".to_string(),
|
|
|
+ DeviceNumber::new(DeviceNumber::from_major_minor(4, 64)),
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>) {
|
|
@@ -167,121 +198,222 @@ impl Device for LockedUart {
|
|
|
DeviceType::Serial
|
|
|
}
|
|
|
|
|
|
- fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
|
|
|
+ fn as_any_ref(&self) -> &dyn Any {
|
|
|
self
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// @brief 串口驱动结构体
|
|
|
-#[repr(C)]
|
|
|
-#[derive(Debug)]
|
|
|
-pub struct UartDriver {
|
|
|
- port: UartPort,
|
|
|
- baud_rate: u32,
|
|
|
- sys_info: Option<Arc<dyn IndexNode>>,
|
|
|
-}
|
|
|
+impl CharDevice for LockedUart {
|
|
|
+ fn read(&self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> {
|
|
|
+ let device = self.0.lock();
|
|
|
+ if len > buf.len() {
|
|
|
+ return Err(SystemError::E2BIG);
|
|
|
+ }
|
|
|
+ kinfo!("------len: {:?}", len);
|
|
|
+ for i in 0..len {
|
|
|
+ buf[i] = Self::uart_read_byte(&device.port) as u8;
|
|
|
+ kinfo!("------buf[{:?}] = {:?}", i, buf[i]);
|
|
|
+ }
|
|
|
+ return Ok(len);
|
|
|
+ }
|
|
|
|
|
|
-impl Default for UartDriver {
|
|
|
- fn default() -> Self {
|
|
|
- Self {
|
|
|
- port: UartPort::COM1,
|
|
|
- baud_rate: 115200,
|
|
|
- sys_info: None,
|
|
|
+ fn write(&self, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
|
|
|
+ let device = self.0.lock();
|
|
|
+ if len > buf.len() {
|
|
|
+ return Err(SystemError::E2BIG);
|
|
|
}
|
|
|
+ Self::uart_send(
|
|
|
+ &device.port,
|
|
|
+ from_utf8(&buf[0..len]).map_err(|_| SystemError::EIO)?,
|
|
|
+ );
|
|
|
+
|
|
|
+ return Ok(len);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn sync(&self) -> Result<(), SystemError> {
|
|
|
+ todo!()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// @brief 串口驱动结构体(加锁)
|
|
|
-#[derive(Debug)]
|
|
|
-pub struct LockedUartDriver(SpinLock<UartDriver>);
|
|
|
+// impl TtyDevice for LockedUart {
|
|
|
+// fn ioctl(&self, cmd: String) -> Result<(), DeviceError> {
|
|
|
+// //TODO 补充详细信息
|
|
|
+// Err(DeviceError::UnsupportedOperation)
|
|
|
+// }
|
|
|
+// fn state(&self) -> Result<TtyState, TtyError> {
|
|
|
+// todo!()
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+impl IndexNode for LockedUart {
|
|
|
+ fn read_at(
|
|
|
+ &self,
|
|
|
+ _offset: usize,
|
|
|
+ len: usize,
|
|
|
+ buf: &mut [u8],
|
|
|
+ _data: &mut FilePrivateData,
|
|
|
+ ) -> Result<usize, SystemError> {
|
|
|
+ CharDevice::read(self, len, buf)
|
|
|
+ }
|
|
|
|
|
|
-impl Default for LockedUartDriver {
|
|
|
- fn default() -> Self {
|
|
|
- Self(SpinLock::new(UartDriver::default()))
|
|
|
+ fn write_at(
|
|
|
+ &self,
|
|
|
+ _offset: usize,
|
|
|
+ len: usize,
|
|
|
+ buf: &[u8],
|
|
|
+ _data: &mut FilePrivateData,
|
|
|
+ ) -> Result<usize, SystemError> {
|
|
|
+ CharDevice::write(self, len, buf)
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-impl KObject for LockedUartDriver {}
|
|
|
+ fn poll(&self) -> Result<PollStatus, SystemError> {
|
|
|
+ todo!()
|
|
|
+ }
|
|
|
|
|
|
-impl Driver for LockedUartDriver {
|
|
|
- fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
|
|
|
- self
|
|
|
+ fn fs(&self) -> Arc<dyn FileSystem> {
|
|
|
+ return self
|
|
|
+ .0
|
|
|
+ .lock()
|
|
|
+ .fs
|
|
|
+ .clone()
|
|
|
+ .upgrade()
|
|
|
+ .expect("DevFS is not initialized inside Uart Device");
|
|
|
}
|
|
|
|
|
|
- fn id_table(&self) -> IdTable {
|
|
|
- return IdTable::new("uart_driver", 0);
|
|
|
+ fn as_any_ref(&self) -> &dyn Any {
|
|
|
+ todo!()
|
|
|
}
|
|
|
|
|
|
- fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>) {
|
|
|
- self.0.lock().sys_info = sys_info;
|
|
|
+ fn list(&self) -> Result<Vec<String>, SystemError> {
|
|
|
+ todo!()
|
|
|
}
|
|
|
|
|
|
- fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
|
|
|
- return self.0.lock().sys_info.clone();
|
|
|
+ fn metadata(&self) -> Result<Metadata, SystemError> {
|
|
|
+ return Ok(self.0.lock().metadata.clone());
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-impl CharDevice for LockedUartDriver {
|
|
|
- fn open(&self, _file: Arc<dyn IndexNode>) -> Result<(), crate::syscall::SystemError> {
|
|
|
+ fn open(
|
|
|
+ &self,
|
|
|
+ _data: &mut FilePrivateData,
|
|
|
+ _mode: &crate::filesystem::vfs::file::FileMode,
|
|
|
+ ) -> Result<(), SystemError> {
|
|
|
+ // 若文件系统没有实现此方法,则返回“不支持”
|
|
|
return Ok(());
|
|
|
}
|
|
|
|
|
|
- fn close(&self, _file: Arc<dyn IndexNode>) -> Result<(), crate::syscall::SystemError> {
|
|
|
+ fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
|
|
|
+ // 若文件系统没有实现此方法,则返回“不支持”
|
|
|
return Ok(());
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-impl LockedUartDriver {
|
|
|
- /// @brief 创建串口驱动
|
|
|
- /// @param port 端口号
|
|
|
- /// baud_rate 波特率
|
|
|
- /// sys_info: sys文件系统inode
|
|
|
- /// @return
|
|
|
- #[allow(dead_code)]
|
|
|
- pub fn new(port: UartPort, baud_rate: u32, sys_info: Option<Arc<dyn IndexNode>>) -> Self {
|
|
|
- Self(SpinLock::new(UartDriver::new(port, baud_rate, sys_info)))
|
|
|
+ fn set_metadata(&self, _metadata: &Metadata) -> Result<(), SystemError> {
|
|
|
+ // 若文件系统没有实现此方法,则返回“不支持”
|
|
|
+ return Ok(self.0.lock().metadata = _metadata.clone());
|
|
|
+ }
|
|
|
+ fn create(
|
|
|
+ &self,
|
|
|
+ name: &str,
|
|
|
+ file_type: FileType,
|
|
|
+ mode: u32,
|
|
|
+ ) -> Result<Arc<dyn IndexNode>, SystemError> {
|
|
|
+ // 若文件系统没有实现此方法,则默认调用其create_with_data方法。如果仍未实现,则会得到一个Err(-EOPNOTSUPP_OR_ENOTSUP)的返回值
|
|
|
+ return self.create_with_data(name, file_type, mode, 0);
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-impl PlatformDriver for LockedUartDriver {
|
|
|
- fn probe(
|
|
|
+ fn create_with_data(
|
|
|
&self,
|
|
|
- _device: Arc<dyn PlatformDevice>,
|
|
|
- ) -> Result<(), crate::driver::base::device::driver::DriverError> {
|
|
|
- return Ok(());
|
|
|
+ _name: &str,
|
|
|
+ _file_type: FileType,
|
|
|
+ _mode: u32,
|
|
|
+ _data: usize,
|
|
|
+ ) -> Result<Arc<dyn IndexNode>, SystemError> {
|
|
|
+ // 若文件系统没有实现此方法,则返回“不支持”
|
|
|
+ return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
|
|
|
}
|
|
|
|
|
|
- fn compatible_table(&self) -> platform::CompatibleTable {
|
|
|
- return CompatibleTable::new(vec!["uart"]);
|
|
|
+ fn link(&self, _name: &str, _other: &Arc<dyn IndexNode>) -> Result<(), SystemError> {
|
|
|
+ // 若文件系统没有实现此方法,则返回“不支持”
|
|
|
+ return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn unlink(&self, _name: &str) -> Result<(), SystemError> {
|
|
|
+ // 若文件系统没有实现此方法,则返回“不支持”
|
|
|
+ return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn rmdir(&self, _name: &str) -> Result<(), SystemError> {
|
|
|
+ return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn move_(
|
|
|
+ &self,
|
|
|
+ _old_name: &str,
|
|
|
+ _target: &Arc<dyn IndexNode>,
|
|
|
+ _new_name: &str,
|
|
|
+ ) -> Result<(), SystemError> {
|
|
|
+ // 若文件系统没有实现此方法,则返回“不支持”
|
|
|
+ return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn find(&self, _name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
|
|
|
+ // 若文件系统没有实现此方法,则返回“不支持”
|
|
|
+ return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn get_entry_name(&self, _ino: crate::filesystem::vfs::InodeId) -> Result<String, SystemError> {
|
|
|
+ // 若文件系统没有实现此方法,则返回“不支持”
|
|
|
+ return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn get_entry_name_and_metadata(
|
|
|
+ &self,
|
|
|
+ ino: crate::filesystem::vfs::InodeId,
|
|
|
+ ) -> Result<(String, Metadata), SystemError> {
|
|
|
+ // 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。
|
|
|
+ let name = self.get_entry_name(ino)?;
|
|
|
+ let entry = self.find(&name)?;
|
|
|
+ return Ok((name, entry.metadata()?));
|
|
|
+ }
|
|
|
+
|
|
|
+ fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> {
|
|
|
+ // 若文件系统没有实现此方法,则返回“不支持”
|
|
|
+ return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn mount(
|
|
|
+ &self,
|
|
|
+ _fs: Arc<dyn FileSystem>,
|
|
|
+ ) -> Result<Arc<crate::filesystem::vfs::MountFS>, SystemError> {
|
|
|
+ return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn truncate(&self, _len: usize) -> Result<(), SystemError> {
|
|
|
+ return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn sync(&self) -> Result<(), SystemError> {
|
|
|
+ return Ok(());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl UartDriver {
|
|
|
- /// @brief 创建串口驱动
|
|
|
- /// @param port 端口号
|
|
|
- /// baud_rate 波特率
|
|
|
- /// sys_info: sys文件系统inode
|
|
|
- /// @return 返回串口驱动
|
|
|
- #[allow(dead_code)]
|
|
|
- pub fn new(port: UartPort, baud_rate: u32, sys_info: Option<Arc<dyn IndexNode>>) -> Self {
|
|
|
- Self {
|
|
|
- port,
|
|
|
- baud_rate,
|
|
|
- sys_info,
|
|
|
- }
|
|
|
+impl DeviceINode for LockedUart {
|
|
|
+ fn set_fs(&self, fs: Weak<DevFS>) {
|
|
|
+ self.0.lock().fs = fs;
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
+impl LockedUart {
|
|
|
/// @brief 串口初始化
|
|
|
/// @param uart_port 端口号
|
|
|
/// @param baud_rate 波特率
|
|
|
/// @return 初始化成功,返回0,失败,返回错误信息
|
|
|
#[allow(dead_code)]
|
|
|
- pub fn uart_init(uart_port: &UartPort, baud_rate: u32) -> Result<i32, &'static str> {
|
|
|
+ pub fn uart_init(uart_port: &UartPort, baud_rate: u32) -> Result<(), DeviceError> {
|
|
|
let message: &'static str = "uart init.";
|
|
|
let port = uart_port.to_u16();
|
|
|
// 错误的比特率
|
|
|
if baud_rate > UART_MAX_BITS_RATE || UART_MAX_BITS_RATE % baud_rate != 0 {
|
|
|
- return Err("uart init error.");
|
|
|
+ return Err(DeviceError::InitializeFailed);
|
|
|
}
|
|
|
|
|
|
unsafe {
|
|
@@ -300,15 +432,15 @@ impl UartDriver {
|
|
|
|
|
|
// Check if serial is faulty (i.e: not same byte as sent)
|
|
|
if io_in8(port + 0) != 0xAE {
|
|
|
- return Err("uart faulty");
|
|
|
+ return Err(DeviceError::InitializeFailed);
|
|
|
}
|
|
|
|
|
|
// If serial is not faulty set it in normal operation mode
|
|
|
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
|
|
|
io_out8(port + 4, 0x08);
|
|
|
}
|
|
|
- UartDriver::uart_send(uart_port, message);
|
|
|
- Ok(0)
|
|
|
+ Self::uart_send(uart_port, message);
|
|
|
+ Ok(())
|
|
|
/*
|
|
|
Notice that the initialization code above writes to [PORT + 1]
|
|
|
twice with different values. This is once to write to the Divisor
|
|
@@ -342,13 +474,12 @@ impl UartDriver {
|
|
|
#[allow(dead_code)]
|
|
|
fn uart_send(uart_port: &UartPort, s: &str) {
|
|
|
let port = uart_port.to_u16();
|
|
|
- while UartDriver::is_transmit_empty(port) == false {
|
|
|
- for c in s.bytes() {
|
|
|
- unsafe {
|
|
|
- io_out8(port, c);
|
|
|
- }
|
|
|
+ while Self::is_transmit_empty(port) == false {} //TODO:pause
|
|
|
+ for c in s.bytes() {
|
|
|
+ unsafe {
|
|
|
+ io_out8(port, c);
|
|
|
}
|
|
|
- } //TODO:pause
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// @brief 串口接收一个字节
|
|
@@ -357,8 +488,8 @@ impl UartDriver {
|
|
|
#[allow(dead_code)]
|
|
|
fn uart_read_byte(uart_port: &UartPort) -> char {
|
|
|
let port = uart_port.to_u16();
|
|
|
- while UartDriver::serial_received(port) == false {} //TODO:pause
|
|
|
- unsafe { io_in8(port) as char }
|
|
|
+ while Self::serial_received(port) == false {} //TODO:pause
|
|
|
+ return unsafe { io_in8(port) as char };
|
|
|
}
|
|
|
|
|
|
#[allow(dead_code)]
|
|
@@ -367,12 +498,112 @@ impl UartDriver {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// @brief 串口驱动结构体
|
|
|
+#[repr(C)]
|
|
|
+#[derive(Debug)]
|
|
|
+pub struct UartDriver {
|
|
|
+ id_table: IdTable,
|
|
|
+
|
|
|
+ sys_info: Option<Arc<dyn IndexNode>>,
|
|
|
+}
|
|
|
+
|
|
|
+impl Default for UartDriver {
|
|
|
+ fn default() -> Self {
|
|
|
+ Self {
|
|
|
+ id_table: IdTable::new(
|
|
|
+ "ttyS".to_string(),
|
|
|
+ DeviceNumber::new(DeviceNumber::from_major_minor(4, 64)),
|
|
|
+ ),
|
|
|
+
|
|
|
+ sys_info: None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// @brief 串口驱动结构体(加锁)
|
|
|
+#[derive(Debug)]
|
|
|
+pub struct LockedUartDriver(SpinLock<UartDriver>);
|
|
|
+
|
|
|
+impl Default for LockedUartDriver {
|
|
|
+ fn default() -> Self {
|
|
|
+ Self(SpinLock::new(UartDriver::default()))
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl KObject for LockedUartDriver {}
|
|
|
+
|
|
|
+impl Driver for LockedUartDriver {
|
|
|
+ fn as_any_ref(&self) -> &dyn Any {
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
+ fn id_table(&self) -> IdTable {
|
|
|
+ return IdTable::new("uart_driver".to_string(), DeviceNumber::new(0));
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>) {
|
|
|
+ self.0.lock().sys_info = sys_info;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
|
|
|
+ return self.0.lock().sys_info.clone();
|
|
|
+ }
|
|
|
+
|
|
|
+ fn probe(&self, data: &DevicePrivateData) -> Result<(), DriverError> {
|
|
|
+ let table = data.compatible_table();
|
|
|
+ if table.matches(&CompatibleTable::new(vec!["uart"])) {
|
|
|
+ return Ok(());
|
|
|
+ }
|
|
|
+ return Err(DriverError::ProbeError);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn load(
|
|
|
+ &self,
|
|
|
+ _data: DevicePrivateData,
|
|
|
+ _resource: Option<DeviceResource>,
|
|
|
+ ) -> Result<Arc<dyn Device>, DriverError> {
|
|
|
+ return Err(DriverError::UnsupportedOperation);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl LockedUartDriver {
|
|
|
+ /// @brief 创建串口驱动
|
|
|
+ /// @param sys_info: sys文件系统inode
|
|
|
+ /// @return
|
|
|
+ #[allow(dead_code)]
|
|
|
+ pub fn new(sys_info: Option<Arc<dyn IndexNode>>) -> Self {
|
|
|
+ Self(SpinLock::new(UartDriver::new(sys_info)))
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl PlatformDriver for LockedUartDriver {
|
|
|
+ fn compatible_table(&self) -> CompatibleTable {
|
|
|
+ return CompatibleTable::new(vec!["uart"]);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl UartDriver {
|
|
|
+ /// @brief 创建串口驱动
|
|
|
+ /// @param sys_info: sys文件系统inode
|
|
|
+ /// @return 返回串口驱动
|
|
|
+ #[allow(dead_code)]
|
|
|
+ pub fn new(sys_info: Option<Arc<dyn IndexNode>>) -> Self {
|
|
|
+ Self {
|
|
|
+ id_table: IdTable::new(
|
|
|
+ "ttyS".to_string(),
|
|
|
+ DeviceNumber::new(DeviceNumber::from_major_minor(4, 64)),
|
|
|
+ ),
|
|
|
+ sys_info,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
///@brief 发送数据
|
|
|
///@param port 端口号
|
|
|
///@param c 要发送的数据
|
|
|
#[no_mangle]
|
|
|
pub extern "C" fn c_uart_send(port: u16, c: u8) {
|
|
|
- while UartDriver::is_transmit_empty(port) == false {} //TODO:pause
|
|
|
+ while LockedUart::is_transmit_empty(port) == false {} //TODO:pause
|
|
|
unsafe {
|
|
|
io_out8(port, c);
|
|
|
}
|
|
@@ -383,7 +614,7 @@ pub extern "C" fn c_uart_send(port: u16, c: u8) {
|
|
|
///@return u8 接收到的数据
|
|
|
#[no_mangle]
|
|
|
pub extern "C" fn c_uart_read(port: u16) -> u8 {
|
|
|
- while UartDriver::serial_received(port) == false {} //TODO:pause
|
|
|
+ while LockedUart::serial_received(port) == false {} //TODO:pause
|
|
|
unsafe { io_in8(port) }
|
|
|
}
|
|
|
|
|
@@ -455,13 +686,18 @@ pub extern "C" fn c_uart_init(port: u16, baud_rate: u32) -> i32 {
|
|
|
/// @param none
|
|
|
/// @return 初始化成功,返回(),失败,返回错误码
|
|
|
pub fn uart_init() -> Result<(), SystemError> {
|
|
|
- let device_inode = bus_device_register("platform:0", &UART_DEV.id_table().to_name())
|
|
|
+ // 以后设备管理初始化完善后不应该出现这种代码,应该在 Driver load 一个设备,即返回设备实例之前就完成设备的 init ,不应该用 lazy_init 在设备上
|
|
|
+ let dev = UART_DEV.0.lock();
|
|
|
+ LockedUart::uart_init(&dev.port, dev.baud_rate).map_err(|_| SystemError::ENODEV)?;
|
|
|
+ drop(dev);
|
|
|
+ let device_inode = bus_device_register("platform:0", &UART_DEV.id_table().name())
|
|
|
.expect("uart device register error");
|
|
|
UART_DEV.set_sys_info(Some(device_inode));
|
|
|
- let driver_inode = bus_driver_register("platform:0", &UART_DRV.id_table().to_name())
|
|
|
+ let driver_inode = bus_driver_register("platform:0", &UART_DRV.id_table().name())
|
|
|
.expect("uart driver register error");
|
|
|
UART_DRV.set_sys_info(Some(driver_inode));
|
|
|
- UART_DEV.set_driver(Some(UART_DRV.clone()));
|
|
|
UART_DEV.set_state(DeviceState::Initialized);
|
|
|
+ devfs_register(&UART_DEV.id_table().name(), UART_DEV.clone())?;
|
|
|
+ DEVICE_MANAGER.add_device(UART_DEV.id_table().clone(), UART_DEV.clone());
|
|
|
return Ok(());
|
|
|
}
|