根据sysfs完善设备驱动模型 & 添加sysfs官方文档 (#254)

* 根据sysfs完善设备驱动模型

* 添加sysfs官方文档
This commit is contained in:
TingHuang 2023-04-23 22:55:57 +08:00 committed by GitHub
parent f678331a33
commit e0de0fd6a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 583 additions and 152 deletions

View File

@ -11,4 +11,5 @@ todo: 由于文件系统模块重构文档暂时不可用预计在2023年4
overview
vfs/index
sysfs

View File

@ -0,0 +1,109 @@
# SysFS
:::{note}
本文作者:黄厅
Email: <huangting@DragonOS.org>
:::
## 1. SysFS和设备驱动模型
### 1.1. 设备、驱动、总线等彼此之间关系错综复杂
&emsp;&emsp;如果想让内核运行流畅,那就必须为每个模块编码实现这些功能。如此一来,内核将变得非常臃肿、冗余。而设备模型的理念即是将这些代码抽象成各模块共用的框架,这样不但代码简洁了,也可让设备驱动开发者摆脱这本让人头痛但又必不可少的一劫,将有限的精力放于设备差异性的实现。
&emsp;&emsp;设备模型恰是提供了一个模板,一个被证明过的最优的思路和流程,这减少了开发者设计过程中不必要的错误,也给以后的维护扫除了障碍。
### 1.2. sysfs是一个基于内存的文件系统它的作用是将内核信息以文件的方式提供给用户程序使用。
&emsp;&emsp;sysfs可以看成与proc,devfs和devpty同类别的文件系统该文件系统是虚拟的文件系统可以更方便对系统设备进行管理。它可以产生一个包含所有系统硬件层次视图与提供进程和状态信息的proc文件系统十分类似。sysfs把连接在系统上的设备和总线组织成为一个分级的文件它们可以由用户空间存取向用户空间导出内核的数据结构以及它们的属性。
## 2. DragosOS中的设备驱动模型
### 2.1 由设备和驱动构成基本元素
#### 2.1.1. 设备
```rust
/// @brief: 所有设备都应该实现该trait
pub trait Device: Any + Send + Sync + Debug {}
```
&emsp;&emsp;DragonOS采用全局设备管理器管理系统中所有的设备。
```rust
/// @brief Device管理器
#[derive(Debug, Clone)]
pub struct DeviceManager {
devices: BTreeMap<IdTable, Arc<dyn Device>>, // 所有设备
sys_info: Option<Arc<dyn IndexNode>>, // sys information
}
```
#### 2.1.2. 驱动
```rust
/// @brief: 所有驱动驱动都应该实现该trait
pub trait Driver: Any + Send + Sync + Debug {}
```
&emsp;&emsp;同样的,驱动也使用全局的驱动管理器来管理
```rust
/// @brief: 驱动管理器
#[derive(Debug, Clone)]
pub struct DriverManager {
drivers: BTreeMap<IdTable, Arc<dyn Driver>>, // 所有驱动
sys_info: Option<Arc<dyn IndexNode>>, // sys information
}
```
### 2.2. 总线
&emsp;&emsp;总线属于设备的一种类型,同样需要驱动来初始化,同时由于总线的特殊性,使用全局的总线管理器来进行管理。
```rust
/// @brief: 总线驱动trait所有总线驱动都应实现该trait
pub trait BusDriver: Driver {}
/// @brief: 总线设备trait所有总线都应实现该trait
pub trait Bus: Device {}
/// @brief: 总线管理结构体
#[derive(Debug, Clone)]
pub struct BusManager {
buses: BTreeMap<IdTable, Arc<dyn Bus>>, // 总线设备表
bus_drvs: BTreeMap<IdTable, Arc<dyn BusDriver>>, // 总线驱动表
sys_info: Option<Arc<dyn IndexNode>>, // 总线inode
}
```
&emsp;&emsp;可以看到每个管理器中均存在sys_info设备模型通过该成员与sysfs建立联系sys_info指向sysfs中唯一的inode。对于device而言对应sysfs下的devices文件夹其他亦是如此。
## 3. 驱动开发如何进行
&emsp;&emsp;以平台总线platform为例platform总线是一种虚拟总线可以对挂载在其上的设备和驱动进行匹配并驱动设备。该总线是一类设备同时也是一类总线编程时需要创建该设备实例并为设备实例实现Device trait和Bus trait以表明该结构是一类总线设备。同时应该实现总线上的匹配规则不同的总线匹配规则不同该总线采用匹配表方式进行匹配设备和驱动都应该存在一份匹配表表示驱动支持的设备以及设备支持的驱动。
```rust
pub struct CompatibleTable(BTreeSet<&'static str>);
```
&emsp;&emsp;对于bus设备而言需要调用bus_register将bus注册进系统并在sysfs中可视化。
```rust
/// @brief: 总线注册将总线加入全局总线管理器中并根据id table在sys/bus和sys/devices下生成文件夹
/// @parameter bus: Bus设备实体
/// @return: 成功:() 失败:DeviceError
pub fn bus_register<T: Bus>(bus: Arc<T>) -> Result<(), DeviceError> {
BUS_MANAGER.add_bus(bus.get_id_table(), bus.clone());
match sys_bus_register(&bus.get_id_table().to_name()) {
Ok(inode) => {
let _ = sys_bus_init(&inode);
return device_register(bus);
}
Err(_) => Err(DeviceError::RegisterError),
}
}
```
&emsp;&emsp;通过bus_register源码可知该函数不仅在sysfs/bus下生成总线文件夹同时内部调用device_register该函数将总线加入设备管理器中同时在sys/devices下生成设备文件夹。

View File

@ -1,13 +1,26 @@
use super::{driver::Driver, Device, DeviceError, DeviceState, IdTable};
use super::{
device_register, device_unregister,
driver::{driver_register, driver_unregister, Driver, DriverError},
Device, DeviceError, DeviceState, IdTable,
};
use crate::{
filesystem::sysfs::{self, SYS_BUS_INODE},
kdebug,
filesystem::{
sysfs::{
bus::{sys_bus_init, sys_bus_register},
SYS_BUS_INODE,
},
vfs::IndexNode,
},
libs::spinlock::SpinLock,
};
use alloc::{collections::BTreeMap, sync::Arc};
use core::fmt::Debug;
use lazy_static::lazy_static;
lazy_static! {
pub static ref BUS_MANAGER: Arc<LockedBusManager> = Arc::new(LockedBusManager::new());
}
/// @brief: 总线状态
#[derive(Debug, Copy, Clone)]
pub enum BusState {
@ -58,52 +71,31 @@ pub trait BusDriver: Driver {
}
/// @brief: 总线设备trait所有总线都应实现该trait
pub trait Bus: Device {
/// @brief: 注册bus在sysfs中生成相应文件夹
/// @parameter name: 文件夹名
/// @return: 注册成功,返回(),注册失败,返回错误码
fn register_bus(&self, name: &str) -> Result<(), DeviceError> {
match self.register_device(name) {
Ok(_) => {
let bus = sysfs::bus::bus_register(name).unwrap();
kdebug!(
"After register_bus: ls /sys/bus/: {:?}",
SYS_BUS_INODE().list()
);
match sysfs::bus::bus_init(&bus) {
Ok(_) => {
kdebug!("After register_bus: ls /sys/bus/{}: {:?}", name, bus.list());
return Ok(());
}
Err(_) => Err(DeviceError::RegisterError),
}
}
Err(err) => Err(err),
}
}
}
pub trait Bus: Device {}
/// @brief: 总线管理结构体
#[derive(Debug, Clone)]
pub struct BusManager {
buses: BTreeMap<IdTable, Arc<dyn Bus>>, // 总线设备表
bus_drvs: BTreeMap<IdTable, Arc<dyn BusDriver>>, // 总线驱动表
sys_info: Option<Arc<dyn IndexNode>>, // 总线inode
}
/// @brief: 总线管理结构体加锁
pub struct BusManagerLock(SpinLock<BusManager>);
/// @brief: bus管理(锁)
pub struct LockedBusManager(SpinLock<BusManager>);
/// @brief: 总线管理方法集
impl BusManagerLock {
impl LockedBusManager {
/// @brief: 创建总线管理实例
/// @parameter: None
/// @return: 总线管理实例
#[inline]
#[allow(dead_code)]
pub fn new() -> Self {
BusManagerLock(SpinLock::new(BusManager {
LockedBusManager(SpinLock::new(BusManager {
buses: BTreeMap::new(),
bus_drvs: BTreeMap::new(),
sys_info: Some(SYS_BUS_INODE()),
}))
}
@ -124,7 +116,7 @@ impl BusManagerLock {
/// @return: None
#[inline]
#[allow(dead_code)]
pub fn add_bus_driver(&self, id_table: IdTable, bus_drv: Arc<dyn BusDriver>) {
pub fn add_driver(&self, id_table: IdTable, bus_drv: Arc<dyn BusDriver>) {
let mut bus_manager = self.0.lock();
bus_manager.bus_drvs.insert(id_table, bus_drv);
}
@ -164,12 +156,57 @@ impl BusManagerLock {
/// @return: 总线驱动实例
#[inline]
#[allow(dead_code)]
pub fn get_bus_driver(&self, id_table: &IdTable) -> Option<Arc<dyn BusDriver>> {
pub fn get_driver(&self, id_table: &IdTable) -> Option<Arc<dyn BusDriver>> {
let bus_manager = self.0.lock();
return bus_manager.bus_drvs.get(id_table).cloned();
}
/// @brief: 获取总线管理器的sys information
/// @parameter None
/// @return: sys inode
#[inline]
#[allow(dead_code)]
fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
return self.0.lock().sys_info.clone();
}
}
lazy_static! {
pub static ref BUS_MANAGER: Arc<BusManagerLock> = Arc::new(BusManagerLock::new());
/// @brief: 总线注册将总线加入全局总线管理器中并根据id table在sys/bus和sys/devices下生成文件夹
/// @parameter bus: Bus设备实体
/// @return: 成功:() 失败:DeviceError
pub fn bus_register<T: Bus>(bus: Arc<T>) -> Result<(), DeviceError> {
BUS_MANAGER.add_bus(bus.get_id_table(), bus.clone());
match sys_bus_register(&bus.get_id_table().to_name()) {
Ok(inode) => {
let _ = sys_bus_init(&inode);
return device_register(bus);
}
Err(_) => Err(DeviceError::RegisterError),
}
}
/// @brief: 总线注销将总线从全局总线管理器中删除并在sys/bus和sys/devices下删除文件夹
/// @parameter bus: Bus设备实体
/// @return: 成功:() 失败:DeviceError
#[allow(dead_code)]
pub fn bus_unregister<T: Bus>(bus: Arc<T>) -> Result<(), DeviceError> {
BUS_MANAGER.add_bus(bus.get_id_table(), bus.clone());
return device_unregister(bus);
}
/// @brief: 总线驱动注册,将总线驱动加入全局总线管理器中
/// @parameter bus: Bus设备驱动实体
/// @return: 成功:() 失败:DeviceError
pub fn bus_driver_register<T: BusDriver>(bus_driver: Arc<T>) -> Result<(), DriverError> {
BUS_MANAGER.add_driver(bus_driver.get_id_table(), bus_driver.clone());
return driver_register(bus_driver);
}
/// @brief: 总线驱动注销,将总线从全局总线管理器中删除
/// @parameter bus: Bus设备驱动实体
/// @return: 成功:() 失败:DeviceError
#[allow(dead_code)]
pub fn bus_driver_unregister<T: BusDriver>(bus_driver: Arc<T>) -> Result<(), DriverError> {
BUS_MANAGER.add_driver(bus_driver.get_id_table(), bus_driver.clone());
return driver_unregister(bus_driver);
}

View File

@ -1,17 +1,139 @@
use super::IdTable;
use crate::{filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError};
use alloc::{collections::BTreeMap, sync::Arc};
use core::{any::Any, fmt::Debug};
lazy_static! {
pub static ref DRIVER_MANAGER: Arc<LockedDriverManager> = Arc::new(LockedDriverManager::new());
}
/// @brief: Driver error
#[allow(dead_code)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum DriverError {
ProbeError,
RegisterError,
}
/// @brief: 所有设备驱动都应该实现该trait
pub trait Driver: Any + Send + Sync + Debug {
/// @brief: 获取设备驱动标识符
/// @parameter: None
/// @return: 该设备驱动唯一标识符
fn get_id_table(&self) -> IdTable;
impl Into<SystemError> for DriverError {
fn into(self) -> SystemError {
match self {
DriverError::ProbeError => SystemError::EIO,
DriverError::RegisterError => SystemError::EIO,
}
}
}
/// @brief: 所有驱动驱动都应该实现该trait
pub trait Driver: Any + Send + Sync + Debug {
/// @brief: 本函数用于实现动态转换
/// @parameter: None
/// @return: 该驱动驱动唯一标识符
fn as_any_ref(&'static self) -> &'static dyn core::any::Any;
/// @brief: 获取驱动驱动标识符
/// @parameter: None
/// @return: 该驱动驱动唯一标识符
fn get_id_table(&self) -> IdTable;
/// @brief: 设置驱动的sys information
/// @parameter id_table: 驱动标识符,用于唯一标识该驱动
/// @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: 驱动管理器(锁)
#[derive(Debug)]
pub struct LockedDriverManager(SpinLock<DriverManager>);
impl LockedDriverManager {
/// @brief: 创建一个新的驱动管理器(锁)
/// @parameter None
/// @return: LockedDriverManager实体
#[inline]
fn new() -> LockedDriverManager {
LockedDriverManager(SpinLock::new(DriverManager::new()))
}
/// @brief: 添加驱动
/// @parameter id_table: 驱动标识符,用于唯一标识该驱动
/// @parameter drv: 驱动实例
/// @return: None
#[inline]
#[allow(dead_code)]
pub fn add_driver(&self, id_table: IdTable, drv: Arc<dyn Driver>) {
let mut driver_manager = self.0.lock();
driver_manager.drivers.insert(id_table, drv);
}
/// @brief: 卸载驱动
/// @parameter id_table: 驱动标识符,用于唯一标识该驱动
/// @return: None
#[inline]
#[allow(dead_code)]
pub fn remove_driver(&self, id_table: &IdTable) {
let mut driver_manager = self.0.lock();
driver_manager.drivers.remove(id_table);
}
/// @brief: 获取驱动
/// @parameter id_table: 驱动标识符,用于唯一标识该驱动
/// @return: 驱动实例
#[inline]
#[allow(dead_code)]
pub fn get_driver(&self, id_table: &IdTable) -> Option<Arc<dyn Driver>> {
let driver_manager = self.0.lock();
driver_manager.drivers.get(id_table).cloned()
}
/// @brief: 获取驱动管理器的sys information
/// @parameter id_table: 设备标识符,用于唯一标识该驱动
/// @return: 驱动实例
#[inline]
#[allow(dead_code)]
fn get_sys_info(&self) -> Option<Arc<dyn IndexNode>> {
return self.0.lock().sys_info.clone();
}
}
/// @brief: 驱动管理器
#[derive(Debug, Clone)]
pub struct DriverManager {
drivers: BTreeMap<IdTable, Arc<dyn Driver>>, // 所有驱动
sys_info: Option<Arc<dyn IndexNode>>, // sys information
}
impl DriverManager {
/// @brief: 创建一个新的设备管理器
/// @parameter: None
/// @return: DeviceManager实体
#[inline]
fn new() -> DriverManager {
DriverManager {
drivers: BTreeMap::new(),
sys_info: None,
}
}
}
/// @brief: 驱动注册
/// @parameter: name: 驱动名
/// @return: 操作成功,返回(),操作失败,返回错误码
pub fn driver_register<T: Driver>(driver: Arc<T>) -> Result<(), DriverError> {
DRIVER_MANAGER.add_driver(driver.get_id_table(), driver);
return Ok(());
}
/// @brief: 驱动卸载
/// @parameter: name: 驱动名
/// @return: 操作成功,返回(),操作失败,返回错误码
#[allow(dead_code)]
pub fn driver_unregister<T: Driver>(driver: Arc<T>) -> Result<(), DriverError> {
DRIVER_MANAGER.add_driver(driver.get_id_table(), driver);
return Ok(());
}

View File

@ -1,9 +1,25 @@
use crate::filesystem::sysfs::devices::device_register;
use alloc::{collections::BTreeMap, string::String, sync::Arc};
use crate::{
filesystem::{
sysfs::{
devices::{sys_device_register, sys_device_unregister},
SYS_DEVICES_INODE,
},
vfs::IndexNode,
},
libs::spinlock::SpinLock,
syscall::SystemError,
};
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());
}
/// @brief: 设备类型
#[allow(dead_code)]
#[derive(Debug, Eq, PartialEq)]
@ -32,6 +48,13 @@ impl IdTable {
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: 设备当前状态
@ -53,6 +76,19 @@ pub enum DeviceError {
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 {
@ -87,13 +123,111 @@ pub trait Device: Any + Send + Sync + Debug {
/// @return: 该设备唯一标识
fn get_id_table(&self) -> IdTable;
/// @brief: 设备注册
/// @parameter: name: 设备名
/// @return: 操作成功,返回(),操作失败,返回错误码
fn register_device(&self, name: &str) -> Result<(), DeviceError> {
match device_register(name) {
Ok(_) => Ok(()),
Err(_) => Err(DeviceError::RegisterError),
/// @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.get_id_table(), device.clone());
match sys_device_register(&device.get_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.get_id_table(), device.clone());
match sys_device_unregister(&device.get_id_table().to_name()) {
Ok(_) => {
device.set_sys_info(None);
return Ok(());
}
Err(_) => Err(DeviceError::RegisterError),
}
}

View File

@ -1,16 +1,15 @@
use super::device::{
bus::{Bus, BusDriver, BusState, BUS_MANAGER},
bus::{bus_driver_register, bus_register, Bus, BusDriver, BusState},
driver::Driver,
Device, DeviceError, DeviceState, DeviceType, IdTable,
};
use crate::libs::{mutex::Mutex, rwlock::RwLock};
use crate::{filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError};
use alloc::{
collections::{BTreeMap, BTreeSet},
sync::Arc,
vec::Vec,
};
use core::fmt::Debug;
use lazy_static::lazy_static;
use platform_device::PlatformDevice;
use platform_driver::PlatformDriver;
@ -48,24 +47,17 @@ impl CompatibleTable {
}
}
/// @brief: platform总线驱动
#[derive(Debug)]
pub struct PlatformBusDriver {
drivers: RwLock<BTreeMap<IdTable, Arc<dyn PlatformDriver>>>, // 总线上所有驱动
devices: RwLock<BTreeMap<IdTable, Arc<dyn PlatformDevice>>>, // 总线上所有设备
}
pub struct LockedPlatformBusDriver(SpinLock<PlatformBusDriver>);
impl PlatformBusDriver {
/// @brief: 创建一个platform总线驱动该驱动用于匹配plaform总线
impl LockedPlatformBusDriver {
/// @brief: 创建一个platform总线加锁驱动该驱动用于匹配plaform总线
/// @parameter: None
/// @return: platfor总线驱动
#[inline]
#[allow(dead_code)]
pub fn new() -> Self {
Self {
drivers: RwLock::new(BTreeMap::new()),
devices: RwLock::new(BTreeMap::new()),
}
pub fn new() -> LockedPlatformBusDriver {
LockedPlatformBusDriver(SpinLock::new(PlatformBusDriver::new()))
}
/// @brief: 获取该驱动的匹配表
@ -83,7 +75,7 @@ impl PlatformBusDriver {
#[inline]
#[allow(dead_code)]
fn get_device(&self, id_table: &IdTable) -> Option<Arc<dyn PlatformDevice>> {
let device_map = self.devices.read();
let device_map = &self.0.lock().devices;
return device_map.get(id_table).cloned();
}
@ -93,7 +85,7 @@ impl PlatformBusDriver {
#[inline]
#[allow(dead_code)]
fn get_driver(&self, id_table: &IdTable) -> Option<Arc<dyn PlatformDriver>> {
let driver_map = self.drivers.read();
let driver_map = &self.0.lock().drivers;
return driver_map.get(id_table).cloned();
}
@ -101,13 +93,10 @@ impl PlatformBusDriver {
/// @parameter driver: platform类型驱动该驱动需要实现PlatformDriver trait
/// @return: 注册成功返回Ok(()),注册失败返回BusError类型
#[allow(dead_code)]
fn register_platform_driver(
&mut self,
driver: Arc<dyn PlatformDriver>,
) -> Result<(), DeviceError> {
fn register_platform_driver(&self, driver: Arc<dyn PlatformDriver>) -> Result<(), DeviceError> {
let id_table = driver.get_id_table();
let mut drivers = self.drivers.write();
let drivers = &mut self.0.lock().drivers;
// 如果存在同类型的驱动,返回错误
if drivers.contains_key(&id_table) {
return Err(DeviceError::DriverExists);
@ -124,7 +113,7 @@ impl PlatformBusDriver {
#[inline]
fn unregister_platform_driver(&mut self, driver: Arc<dyn PlatformDriver>) {
let id_table = driver.get_id_table();
self.drivers.write().remove(&id_table);
self.0.lock().drivers.remove(&id_table);
}
/// @brief: 注册platform类型设备
@ -137,7 +126,7 @@ impl PlatformBusDriver {
) -> Result<(), DeviceError> {
let id_table = device.get_id_table();
let mut devices = self.devices.write();
let devices = &mut self.0.lock().devices;
if devices.contains_key(&id_table) {
return Err(DeviceError::DeviceExists);
} else {
@ -153,7 +142,7 @@ impl PlatformBusDriver {
#[allow(dead_code)]
fn unregister_platform_device(&mut self, device: Arc<dyn PlatformDevice>) {
let id_table = device.get_id_table();
self.devices.write().remove(&id_table);
self.0.lock().devices.remove(&id_table);
}
/// @brief: 匹配platform类型驱动
@ -162,7 +151,7 @@ impl PlatformBusDriver {
#[allow(dead_code)]
fn driver_match_device(&self, driver: Arc<dyn PlatformDriver>) -> Result<i32, DeviceError> {
let mut num = 0;
let devices = self.devices.read();
let devices = &self.0.lock().devices;
for (_dev_id_table, device) in devices.iter() {
if device
@ -194,8 +183,8 @@ impl PlatformBusDriver {
/// @return: 如果匹配成功返回Ok(())否则返回BusError类型
#[allow(dead_code)]
fn device_match_driver(&self, device: Arc<dyn PlatformDevice>) -> Result<(), DeviceError> {
let drivers = self.drivers.read();
for (_drv_id_table, driver) in &*drivers {
let drivers = &mut self.0.lock().drivers;
for (_drv_id_table, driver) in drivers.into_iter() {
if driver
.get_compatible_table()
.matches(&device.get_compatible_table())
@ -214,17 +203,58 @@ impl PlatformBusDriver {
}
}
/// @brief: platform总线驱动
#[derive(Debug)]
pub struct PlatformBusDriver {
drivers: BTreeMap<IdTable, Arc<dyn PlatformDriver>>, // 总线上所有驱动
devices: BTreeMap<IdTable, Arc<dyn PlatformDevice>>, // 总线上所有设备
sys_info: Option<Arc<dyn IndexNode>>,
}
impl PlatformBusDriver {
/// @brief: 创建一个platform总线驱动该驱动用于匹配plaform总线
/// @parameter: None
/// @return: platfor总线驱动
#[inline]
#[allow(dead_code)]
pub fn new() -> Self {
Self {
drivers: BTreeMap::new(),
devices: BTreeMap::new(),
sys_info: None,
}
}
}
/// @brief: 为PlatformBusDriver实现Driver trait
impl Driver for PlatformBusDriver {
impl Driver for LockedPlatformBusDriver {
#[inline]
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
#[inline]
fn get_id_table(&self) -> IdTable {
IdTable::new("PlatformBusDriver", 0)
}
#[inline]
#[allow(dead_code)]
fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
return self.0.lock().sys_info.clone();
}
#[inline]
#[allow(dead_code)]
fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>) {
self.0.lock().sys_info = sys_info;
}
}
/// @brief: 为PlatformBusDriver实现BusDriver trait
impl BusDriver for PlatformBusDriver {
impl BusDriver for LockedPlatformBusDriver {
fn is_empty(&self) -> bool {
if self.devices.read().is_empty() && self.drivers.read().is_empty() {
if self.0.lock().devices.is_empty() && self.0.lock().drivers.is_empty() {
return true;
} else {
return false;
@ -232,23 +262,15 @@ impl BusDriver for PlatformBusDriver {
}
}
/// @brief: platform总线
#[derive(Debug, Clone)]
pub struct Platform {
state: Arc<Mutex<BusState>>, // 总线状态
driver: Option<Arc<PlatformBusDriver>>, // 总线驱动
}
#[derive(Debug)]
pub struct LockedPlatform(SpinLock<Platform>);
/// @brief: platform方法集
impl Platform {
/// @brief: 创建一个platform总线实例
impl LockedPlatform {
/// @brief: 创建一个加锁的platform总线实例
/// @parameter: None
/// @return: platform总线实例
pub fn new() -> Self {
Self {
state: Arc::new(Mutex::new(BusState::NotInitialized)),
driver: Option::None,
}
pub fn new() -> LockedPlatform {
LockedPlatform(SpinLock::new(Platform::new()))
}
/// @brief: 获取总线的匹配表
@ -266,8 +288,8 @@ impl Platform {
#[inline]
#[allow(dead_code)]
fn is_initialized(&self) -> bool {
let state = self.state.lock();
match *state {
let state = self.0.lock().state;
match state {
BusState::Initialized => true,
_ => false,
}
@ -278,7 +300,7 @@ impl Platform {
/// @return: None
#[inline]
fn set_state(&self, set_state: BusState) {
let mut state = self.state.lock();
let state = &mut self.0.lock().state;
*state = set_state;
}
@ -288,8 +310,8 @@ impl Platform {
#[inline]
#[allow(dead_code)]
fn get_state(&self) -> BusState {
let state = self.state.lock();
return *state;
let state = self.0.lock().state;
return state;
}
/// @brief:
@ -297,66 +319,72 @@ impl Platform {
/// @return: 总线状态
#[inline]
#[allow(dead_code)]
fn set_driver(&mut self, driver: Option<Arc<PlatformBusDriver>>) {
self.driver = driver;
fn set_driver(&self, driver: Option<Arc<LockedPlatformBusDriver>>) {
self.0.lock().driver = driver;
}
}
/// @brief: platform总线
#[derive(Debug, Clone)]
pub struct Platform {
state: BusState, // 总线状态
driver: Option<Arc<LockedPlatformBusDriver>>, // 总线驱动
sys_info: Option<Arc<dyn IndexNode>>, // 总线sys information
}
/// @brief: platform方法集
impl Platform {
/// @brief: 创建一个platform总线实例
/// @parameter: None
/// @return: platform总线实例
pub fn new() -> Self {
Self {
state: BusState::NotInitialized,
driver: Option::None,
sys_info: Option::None,
}
}
}
/// @brief: 为Platform实现Device traitplatform总线也是一种设备属于总线设备类型
impl Device for Platform {
/// @brief: 获取platform设备类型
/// @parameter: None
/// @return: Bus类型
impl Device for LockedPlatform {
#[inline]
#[allow(dead_code)]
fn get_type(&self) -> DeviceType {
return DeviceType::Bus;
}
/// @brief: 获取platform设备标识符
/// @parameter: None
/// @return: platform总线设备标识符
#[inline]
#[allow(dead_code)]
fn get_id_table(&self) -> IdTable {
IdTable::new("platform", 0)
}
#[inline]
fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>) {
self.0.lock().sys_info = sys_info;
}
#[inline]
#[allow(dead_code)]
fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
return self.0.lock().sys_info.clone();
}
}
/// @brief: 为Platform实现Bus traitplatform总线是一种总线设备
impl Bus for Platform {}
lazy_static! {
pub static ref BUS_PLATFORM_DRIVER: Arc<PlatformBusDriver> = Arc::new(PlatformBusDriver::new());
pub static ref BUS_PLATFORM_DEVICE: Arc<Platform> = Arc::new(Platform::new());
}
impl Bus for LockedPlatform {}
/// @brief: 初始化platform总线
/// @parameter: None
/// @return: None
#[allow(dead_code)]
pub fn platform_bus_init() {
BUS_MANAGER.add_bus_driver(
BUS_PLATFORM_DRIVER.get_id_table(),
BUS_PLATFORM_DRIVER.clone(),
);
BUS_MANAGER.add_bus(
BUS_PLATFORM_DEVICE.get_id_table(),
BUS_PLATFORM_DEVICE.clone(),
);
BUS_PLATFORM_DEVICE.set_state(BusState::Initialized);
let _ = BUS_PLATFORM_DEVICE.register_bus("platform");
}
pub fn platform_bus_init() -> Result<(), SystemError> {
let platform_driver: Arc<LockedPlatformBusDriver> = Arc::new(LockedPlatformBusDriver::new());
let platform_device: Arc<LockedPlatform> = Arc::new(LockedPlatform::new());
bus_register(platform_device.clone()).map_err(|e| e.into())?;
platform_device.set_state(BusState::Initialized);
platform_device.set_driver(Some(platform_driver.clone()));
bus_driver_register(platform_driver.clone()).map_err(|e| e.into())?;
#[no_mangle]
extern "C" fn c_platform_bus_init() {
BUS_MANAGER.add_bus_driver(
BUS_PLATFORM_DRIVER.get_id_table(),
BUS_PLATFORM_DRIVER.clone(),
);
BUS_MANAGER.add_bus(
BUS_PLATFORM_DEVICE.get_id_table(),
BUS_PLATFORM_DEVICE.clone(),
);
BUS_PLATFORM_DEVICE.set_state(BusState::Initialized);
return Ok(());
}

View File

@ -7,7 +7,7 @@ use alloc::sync::Arc;
/// @return: 操作成功返回inode操作失败返回错误码
#[inline]
#[allow(dead_code)]
pub fn bus_register(bus_name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
pub fn sys_bus_register(bus_name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
let binding: Arc<dyn IndexNode> = SYS_BUS_INODE();
kdebug!("Before bus_register: ls /sys/bus/: {:?}", binding.list());
binding
@ -21,9 +21,8 @@ pub fn bus_register(bus_name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
/// @brief: 注销bus在sys/bus删除文件夹
/// @parameter bus_name: 总线文件夹名
/// @return: 操作成功,返回(),操作失败,返回错误码
#[inline]
#[allow(dead_code)]
pub fn bus_unregister(bus_name: &str) -> Result<(), SystemError> {
pub fn sys_bus_unregister(bus_name: &str) -> Result<(), SystemError> {
let binding: Arc<dyn IndexNode> = SYS_BUS_INODE();
binding
.as_any_ref()
@ -36,9 +35,7 @@ pub fn bus_unregister(bus_name: &str) -> Result<(), SystemError> {
/// @brief: 在相应总线文件夹下生成devices和drivers文件夹
/// @parameter inode: 总线文件夹inode
/// @return: 操作成功返回devices inode和drivers inode操作失败返回错误码
#[inline]
#[allow(dead_code)]
pub fn bus_init(
pub fn sys_bus_init(
inode: &Arc<dyn IndexNode>,
) -> Result<(Arc<dyn IndexNode>, Arc<dyn IndexNode>), SystemError> {
match inode.as_any_ref().downcast_ref::<LockedSysFSInode>() {

View File

@ -7,7 +7,7 @@ use alloc::sync::Arc;
/// @return: 操作成功返回inode操作失败返回错误码
#[inline]
#[allow(dead_code)]
pub fn class_register(class_name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
pub fn sys_class_register(class_name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
let binding: Arc<dyn IndexNode> = SYS_CLASS_INODE();
binding
.as_any_ref()
@ -22,7 +22,7 @@ pub fn class_register(class_name: &str) -> Result<Arc<dyn IndexNode>, SystemErro
/// @return: 操作成功,返回(),操作失败,返回错误码
#[inline]
#[allow(dead_code)]
pub fn class_unregister(class_name: &str) -> Result<(), SystemError> {
pub fn sys_class_unregister(class_name: &str) -> Result<(), SystemError> {
let binding: Arc<dyn IndexNode> = SYS_CLASS_INODE();
binding
.as_any_ref()
@ -38,7 +38,7 @@ pub fn class_unregister(class_name: &str) -> Result<(), SystemError> {
/// @return: 操作成功返回inode操作失败返回错误码
#[inline]
#[allow(dead_code)]
pub fn device_register(
pub fn class_device_register(
class: Arc<dyn IndexNode>,
device_name: &str,
) -> Result<Arc<dyn IndexNode>, SystemError> {
@ -56,7 +56,10 @@ pub fn device_register(
/// @return: 操作成功,返回(),操作失败,返回错误码
#[inline]
#[allow(dead_code)]
pub fn device_unregister(class: Arc<dyn IndexNode>, device_name: &str) -> Result<(), SystemError> {
pub fn class_device_unregister(
class: Arc<dyn IndexNode>,
device_name: &str,
) -> Result<(), SystemError> {
class
.as_any_ref()
.downcast_ref::<LockedSysFSInode>()

View File

@ -7,7 +7,7 @@ use alloc::sync::Arc;
/// @return: 操作成功返回inode操作失败返回错误码
#[inline]
#[allow(dead_code)]
pub fn device_register(device_name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
pub fn sys_device_register(device_name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
let binding: Arc<dyn IndexNode> = SYS_DEVICES_INODE();
binding
.as_any_ref()
@ -22,7 +22,7 @@ pub fn device_register(device_name: &str) -> Result<Arc<dyn IndexNode>, SystemEr
/// @return: 操作成功,返回(),操作失败,返回错误码
#[inline]
#[allow(dead_code)]
pub fn device_unregister(device_name: &str) -> Result<(), SystemError> {
pub fn sys_device_unregister(device_name: &str) -> Result<(), SystemError> {
let binding: Arc<dyn IndexNode> = SYS_DEVICES_INODE();
binding
.as_any_ref()

View File

@ -137,7 +137,7 @@ impl SysFS {
Err(_) => panic!("SysFS: Failed to create /sys/fs"),
}
// 初始化platform总线
crate::driver::base::platform::platform_bus_init();
crate::driver::base::platform::platform_bus_init().expect("platform bus init failed");
return sysfs;
}
}

View File

@ -94,7 +94,7 @@ impl IndexNode for LockedPipeInode {
let irq_guard = CurrentIrqArch::save_and_disable_irq();
inode.read_wait_queue.sleep_without_schedule();
drop(inode);
drop(irq_guard);
}
sched();