mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-10 16:26:48 +00:00
* 按照rust规范修改两个函数名称 * 修改一些函数句柄以符合rust规范 * 添加字符设备相关 * 添加字符设备相关文件 * 添加字符设备驱动框架代码 * 将串口注册 * 规范代码
293 lines
8.0 KiB
Rust
293 lines
8.0 KiB
Rust
use crate::{
|
|
filesystem::{
|
|
sysfs::{
|
|
devices::{sys_device_register, sys_device_unregister},
|
|
SYS_DEVICES_INODE,
|
|
},
|
|
vfs::IndexNode,
|
|
},
|
|
libs::spinlock::SpinLock,
|
|
syscall::SystemError,
|
|
};
|
|
use alloc::{collections::BTreeMap, string::String, sync::Arc};
|
|
use core::{any::Any, fmt::Debug};
|
|
|
|
pub mod bus;
|
|
pub mod driver;
|
|
|
|
lazy_static! {
|
|
pub static ref DEVICE_MANAGER: Arc<LockedDeviceManager> = Arc::new(LockedDeviceManager::new());
|
|
}
|
|
|
|
pub trait KObject: Any + Send + Sync + Debug {}
|
|
|
|
/// @brief: 设备号实例
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
|
|
pub struct DeviceNumber(usize);
|
|
|
|
impl Default for DeviceNumber {
|
|
fn default() -> Self {
|
|
DeviceNumber(0)
|
|
}
|
|
}
|
|
|
|
impl From<usize> for DeviceNumber {
|
|
fn from(dev_t: usize) -> Self {
|
|
DeviceNumber(dev_t)
|
|
}
|
|
}
|
|
|
|
impl Into<usize> for DeviceNumber {
|
|
fn into(self) -> usize {
|
|
self.0
|
|
}
|
|
}
|
|
|
|
impl DeviceNumber {
|
|
/// @brief: 设备号创建
|
|
/// @parameter: dev_t: 设备号
|
|
/// @return: 设备号实例
|
|
pub fn new(dev_t: usize) -> DeviceNumber {
|
|
Self(dev_t)
|
|
}
|
|
|
|
/// @brief: 获取主设备号
|
|
/// @parameter: none
|
|
/// @return: 主设备号
|
|
pub fn major(&self) -> usize {
|
|
(self.0 >> 20) & 0xfff
|
|
}
|
|
|
|
/// @brief: 获取次设备号
|
|
/// @parameter: none
|
|
/// @return: 次设备号
|
|
pub fn minor(&self) -> usize {
|
|
self.0 & 0xfffff
|
|
}
|
|
}
|
|
|
|
/// @brief: 根据主次设备号创建设备号实例
|
|
/// @parameter: major: 主设备号
|
|
/// minor: 次设备号
|
|
/// @return: 设备号实例
|
|
pub fn mkdev(major: usize, minor: usize) -> DeviceNumber {
|
|
DeviceNumber(((major & 0xfff) << 20) | (minor & 0xfffff))
|
|
}
|
|
|
|
/// @brief: 设备类型
|
|
#[allow(dead_code)]
|
|
#[derive(Debug, Eq, PartialEq)]
|
|
pub enum DeviceType {
|
|
Bus,
|
|
Net,
|
|
Gpu,
|
|
Input,
|
|
Block,
|
|
Rtc,
|
|
Serial,
|
|
Intc,
|
|
PlatformDev,
|
|
}
|
|
|
|
/// @brief: 设备标识符类型
|
|
#[derive(Debug, Clone, Hash, PartialOrd, PartialEq, Ord, Eq)]
|
|
pub struct IdTable(&'static str, u32);
|
|
|
|
/// @brief: 设备标识符操作方法集
|
|
impl IdTable {
|
|
/// @brief: 创建一个新的设备标识符
|
|
/// @parameter name: 设备名
|
|
/// @parameter id: 设备id
|
|
/// @return: 设备标识符
|
|
pub fn new(name: &'static str, id: u32) -> IdTable {
|
|
Self(name, id)
|
|
}
|
|
|
|
/// @brief: 将设备标识符转换成name
|
|
/// @parameter None
|
|
/// @return: 设备名
|
|
pub fn to_name(&self) -> String {
|
|
return format!("{}:{}", self.0, self.1);
|
|
}
|
|
}
|
|
|
|
/// @brief: 设备当前状态
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub enum DeviceState {
|
|
NotInitialized = 0,
|
|
Initialized = 1,
|
|
UnDefined = 2,
|
|
}
|
|
|
|
/// @brief: 设备错误类型
|
|
#[derive(Debug, Copy, Clone)]
|
|
pub enum DeviceError {
|
|
DriverExists, // 设备已存在
|
|
DeviceExists, // 驱动已存在
|
|
InitializeFailed, // 初始化错误
|
|
NoDeviceForDriver, // 没有合适的设备匹配驱动
|
|
NoDriverForDevice, // 没有合适的驱动匹配设备
|
|
RegisterError, // 注册失败
|
|
}
|
|
|
|
impl Into<SystemError> for DeviceError {
|
|
fn into(self) -> SystemError {
|
|
match self {
|
|
DeviceError::DriverExists => SystemError::EEXIST,
|
|
DeviceError::DeviceExists => SystemError::EEXIST,
|
|
DeviceError::InitializeFailed => SystemError::EIO,
|
|
DeviceError::NoDeviceForDriver => SystemError::ENODEV,
|
|
DeviceError::NoDriverForDevice => SystemError::ENODEV,
|
|
DeviceError::RegisterError => SystemError::EIO,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// @brief: 将u32类型转换为设备状态类型
|
|
impl From<u32> for DeviceState {
|
|
fn from(state: u32) -> Self {
|
|
match state {
|
|
0 => DeviceState::NotInitialized,
|
|
1 => DeviceState::Initialized,
|
|
_ => todo!(),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// @brief: 将设备状态转换为u32类型
|
|
impl From<DeviceState> for u32 {
|
|
fn from(state: DeviceState) -> Self {
|
|
match state {
|
|
DeviceState::NotInitialized => 0,
|
|
DeviceState::Initialized => 1,
|
|
DeviceState::UnDefined => 2,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// @brief: 所有设备都应该实现该trait
|
|
pub trait Device: KObject {
|
|
/// @brief: 本函数用于实现动态转换
|
|
/// @parameter: None
|
|
/// @return: any
|
|
fn as_any_ref(&'static self) -> &'static dyn core::any::Any;
|
|
|
|
/// @brief: 获取设备类型
|
|
/// @parameter: None
|
|
/// @return: 实现该trait的设备所属类型
|
|
fn dev_type(&self) -> DeviceType;
|
|
|
|
/// @brief: 获取设备标识
|
|
/// @parameter: None
|
|
/// @return: 该设备唯一标识
|
|
fn id_table(&self) -> IdTable;
|
|
|
|
/// @brief: 设置sysfs info
|
|
/// @parameter: None
|
|
/// @return: 该设备唯一标识
|
|
fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>);
|
|
|
|
/// @brief: 获取设备的sys information
|
|
/// @parameter id_table: 设备标识符,用于唯一标识该设备
|
|
/// @return: 设备实例
|
|
fn sys_info(&self) -> Option<Arc<dyn IndexNode>>;
|
|
}
|
|
|
|
/// @brief Device管理器(锁)
|
|
#[derive(Debug)]
|
|
pub struct LockedDeviceManager(SpinLock<DeviceManager>);
|
|
|
|
impl LockedDeviceManager {
|
|
fn new() -> LockedDeviceManager {
|
|
LockedDeviceManager(SpinLock::new(DeviceManager::new()))
|
|
}
|
|
|
|
/// @brief: 添加设备
|
|
/// @parameter id_table: 总线标识符,用于唯一标识该总线
|
|
/// @parameter dev: 设备实例
|
|
/// @return: None
|
|
#[inline]
|
|
#[allow(dead_code)]
|
|
pub fn add_device(&self, id_table: IdTable, dev: Arc<dyn Device>) {
|
|
let mut device_manager = self.0.lock();
|
|
device_manager.devices.insert(id_table, dev);
|
|
}
|
|
|
|
/// @brief: 卸载设备
|
|
/// @parameter id_table: 总线标识符,用于唯一标识该设备
|
|
/// @return: None
|
|
#[inline]
|
|
#[allow(dead_code)]
|
|
pub fn remove_device(&self, id_table: &IdTable) {
|
|
let mut device_manager = self.0.lock();
|
|
device_manager.devices.remove(id_table);
|
|
}
|
|
|
|
/// @brief: 获取设备
|
|
/// @parameter id_table: 设备标识符,用于唯一标识该设备
|
|
/// @return: 设备实例
|
|
#[inline]
|
|
#[allow(dead_code)]
|
|
pub fn get_device(&self, id_table: &IdTable) -> Option<Arc<dyn Device>> {
|
|
let device_manager = self.0.lock();
|
|
device_manager.devices.get(id_table).cloned()
|
|
}
|
|
|
|
/// @brief: 获取设备管理器的sys information
|
|
/// @parameter id_table: 设备标识符,用于唯一标识该设备
|
|
/// @return: 设备实例
|
|
#[inline]
|
|
#[allow(dead_code)]
|
|
fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
|
|
return self.0.lock().sys_info.clone();
|
|
}
|
|
}
|
|
|
|
/// @brief Device管理器
|
|
#[derive(Debug, Clone)]
|
|
pub struct DeviceManager {
|
|
devices: BTreeMap<IdTable, Arc<dyn Device>>, // 所有设备
|
|
sys_info: Option<Arc<dyn IndexNode>>, // sys information
|
|
}
|
|
|
|
impl DeviceManager {
|
|
/// @brief: 创建一个新的设备管理器
|
|
/// @parameter: None
|
|
/// @return: DeviceManager实体
|
|
#[inline]
|
|
fn new() -> DeviceManager {
|
|
DeviceManager {
|
|
devices: BTreeMap::new(),
|
|
sys_info: Some(SYS_DEVICES_INODE()),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// @brief: 设备注册
|
|
/// @parameter: name: 设备名
|
|
/// @return: 操作成功,返回(),操作失败,返回错误码
|
|
pub fn device_register<T: Device>(device: Arc<T>) -> Result<(), DeviceError> {
|
|
DEVICE_MANAGER.add_device(device.id_table(), device.clone());
|
|
match sys_device_register(&device.id_table().to_name()) {
|
|
Ok(sys_info) => {
|
|
device.set_sys_info(Some(sys_info));
|
|
return Ok(());
|
|
}
|
|
Err(_) => Err(DeviceError::RegisterError),
|
|
}
|
|
}
|
|
|
|
/// @brief: 设备卸载
|
|
/// @parameter: name: 设备名
|
|
/// @return: 操作成功,返回(),操作失败,返回错误码
|
|
pub fn device_unregister<T: Device>(device: Arc<T>) -> Result<(), DeviceError> {
|
|
DEVICE_MANAGER.add_device(device.id_table(), device.clone());
|
|
match sys_device_unregister(&device.id_table().to_name()) {
|
|
Ok(_) => {
|
|
device.set_sys_info(None);
|
|
return Ok(());
|
|
}
|
|
Err(_) => Err(DeviceError::RegisterError),
|
|
}
|
|
}
|