mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 08:06:32 +00:00
注册串口设备,创建字符设备框架(#290)
* 按照rust规范修改两个函数名称 * 修改一些函数句柄以符合rust规范 * 添加字符设备相关 * 添加字符设备相关文件 * 添加字符设备驱动框架代码 * 将串口注册 * 规范代码
This commit is contained in:
285
kernel/src/driver/base/char/mod.rs
Normal file
285
kernel/src/driver/base/char/mod.rs
Normal file
@ -0,0 +1,285 @@
|
||||
use super::{
|
||||
device::{mkdev, DeviceNumber, KObject},
|
||||
map::{kobj_map, kobj_unmap, LockedKObjMap},
|
||||
};
|
||||
use crate::{filesystem::vfs::IndexNode, kerror, libs::spinlock::SpinLock, syscall::SystemError};
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use core::cmp::Ordering;
|
||||
|
||||
const CHARDEV_MAJOR_HASH_SIZE: usize = 255;
|
||||
const CHARDEV_MAJOR_MAX: usize = 512;
|
||||
const MINOR_BITS: usize = 20;
|
||||
const MINOR_MASK: usize = 1 << MINOR_BITS - 1;
|
||||
/* Marks the bottom of the first segment of free char majors */
|
||||
const CHARDEV_MAJOR_DYN_END: usize = 234;
|
||||
/* Marks the top and bottom of the second segment of free char majors */
|
||||
const CHARDEV_MAJOR_DYN_EXT_START: usize = 511;
|
||||
const CHARDEV_MAJOR_DYN_EXT_END: usize = 384;
|
||||
|
||||
lazy_static! {
|
||||
// 全局字符设备号管理实例
|
||||
pub static ref CHARDEVS: Arc<LockedChrDevs> = Arc::new(LockedChrDevs::default());
|
||||
|
||||
// 全局字符设备管理实例
|
||||
pub static ref CDEVMAP: Arc<LockedKObjMap> = Arc::new(LockedKObjMap::default());
|
||||
}
|
||||
|
||||
pub trait CharDevice: KObject {
|
||||
/// @brief: 打开设备
|
||||
/// @parameter: file: devfs inode
|
||||
/// @return: 打开成功,返回OK(()),失败,返回错误代码
|
||||
fn open(&self, file: Arc<dyn IndexNode>) -> Result<(), SystemError>;
|
||||
|
||||
/// @brief: 关闭设备
|
||||
/// @parameter: file: devfs inode
|
||||
/// @return: 关闭成功,返回OK(()),失败,返回错误代码
|
||||
fn close(&self, file: Arc<dyn IndexNode>) -> Result<(), SystemError>;
|
||||
}
|
||||
|
||||
// 管理字符设备号的map(加锁)
|
||||
pub struct LockedChrDevs(SpinLock<ChrDevs>);
|
||||
|
||||
impl Default for LockedChrDevs {
|
||||
fn default() -> Self {
|
||||
LockedChrDevs(SpinLock::new(ChrDevs::default()))
|
||||
}
|
||||
}
|
||||
|
||||
// 管理字符设备号的map
|
||||
#[derive(Debug)]
|
||||
struct ChrDevs(Vec<Vec<CharDeviceStruct>>);
|
||||
|
||||
impl Default for ChrDevs {
|
||||
fn default() -> Self {
|
||||
ChrDevs(vec![Vec::new(); CHARDEV_MAJOR_HASH_SIZE])
|
||||
}
|
||||
}
|
||||
|
||||
// 字符设备在系统中的实例,devfs通过该结构与实际字符设备进行联系
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CharDeviceStruct {
|
||||
dev_t: DeviceNumber, //起始设备号
|
||||
minorct: usize, // 次设备号数量
|
||||
name: &'static str, //字符设备名
|
||||
}
|
||||
|
||||
impl CharDeviceStruct {
|
||||
/// @brief: 创建实例
|
||||
/// @parameter: dev_t: 设备号
|
||||
/// minorct: 次设备号数量
|
||||
/// name: 字符设备名
|
||||
/// char: 字符设备实例
|
||||
/// @return: 实例
|
||||
///
|
||||
#[allow(dead_code)]
|
||||
pub fn new(dev_t: DeviceNumber, minorct: usize, name: &'static str) -> Self {
|
||||
Self {
|
||||
dev_t,
|
||||
minorct,
|
||||
name,
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief: 获取起始次设备号
|
||||
/// @parameter: None
|
||||
/// @return: 起始设备号
|
||||
///
|
||||
#[allow(dead_code)]
|
||||
pub fn device_number(&self) -> DeviceNumber {
|
||||
self.dev_t
|
||||
}
|
||||
|
||||
/// @brief: 获取起始次设备号
|
||||
/// @parameter: None
|
||||
/// @return: 起始设备号
|
||||
///
|
||||
#[allow(dead_code)]
|
||||
pub fn base_minor(&self) -> usize {
|
||||
self.dev_t.minor()
|
||||
}
|
||||
|
||||
/// @brief: 获取次设备号数量
|
||||
/// @parameter: None
|
||||
/// @return: 次设备号数量
|
||||
#[allow(dead_code)]
|
||||
pub fn minorct(&self) -> usize {
|
||||
self.minorct
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 字符设备框架函数集
|
||||
pub struct CharDevOps;
|
||||
|
||||
impl CharDevOps {
|
||||
/// @brief: 主设备号转下标
|
||||
/// @parameter: major: 主设备号
|
||||
/// @return: 返回下标
|
||||
#[allow(dead_code)]
|
||||
fn major_to_index(major: usize) -> usize {
|
||||
return major % CHARDEV_MAJOR_HASH_SIZE;
|
||||
}
|
||||
|
||||
/// @brief: 动态获取主设备号
|
||||
/// @parameter: None
|
||||
/// @return: 如果成功,返回主设备号,否则,返回错误码
|
||||
#[allow(dead_code)]
|
||||
fn find_dynamic_major() -> Result<usize, SystemError> {
|
||||
let chardevs = CHARDEVS.0.lock();
|
||||
// 寻找主设备号为234~255的设备
|
||||
for index in (CHARDEV_MAJOR_DYN_END..CHARDEV_MAJOR_HASH_SIZE).rev() {
|
||||
if let Some(item) = chardevs.0.get(index) {
|
||||
if item.is_empty() {
|
||||
return Ok(index); // 返回可用的主设备号
|
||||
}
|
||||
}
|
||||
}
|
||||
// 寻找主设备号在384~511的设备
|
||||
for index in (CHARDEV_MAJOR_DYN_EXT_END + 1..CHARDEV_MAJOR_DYN_EXT_START + 1).rev() {
|
||||
if let Some(chardevss) = chardevs.0.get(Self::major_to_index(index)) {
|
||||
let mut flag = true;
|
||||
for item in chardevss {
|
||||
if item.device_number().major() == index {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if flag {
|
||||
// 如果数组中不存在主设备号等于index的设备
|
||||
return Ok(index); // 返回可用的主设备号
|
||||
}
|
||||
}
|
||||
}
|
||||
return Err(SystemError::EBUSY);
|
||||
}
|
||||
|
||||
/// @brief: 注册设备号,该函数需要指定主设备号
|
||||
/// @parameter: from: 主设备号
|
||||
/// count: 次设备号数量
|
||||
/// name: 字符设备名
|
||||
/// @return: 如果注册成功,返回设备号,否则,返回错误码
|
||||
#[allow(dead_code)]
|
||||
pub fn register_chardev_region(
|
||||
from: DeviceNumber,
|
||||
count: usize,
|
||||
name: &'static str,
|
||||
) -> Result<DeviceNumber, SystemError> {
|
||||
Self::__register_chardev_region(from, count, name)
|
||||
}
|
||||
|
||||
/// @brief: 注册设备号,该函数自动分配主设备号
|
||||
/// @parameter: baseminor: 主设备号
|
||||
/// count: 次设备号数量
|
||||
/// name: 字符设备名
|
||||
/// @return: 如果注册成功,返回,否则,返回false
|
||||
#[allow(dead_code)]
|
||||
pub fn alloc_chardev_region(
|
||||
baseminor: usize,
|
||||
count: usize,
|
||||
name: &'static str,
|
||||
) -> Result<DeviceNumber, SystemError> {
|
||||
Self::__register_chardev_region(mkdev(0, baseminor), count, name)
|
||||
}
|
||||
|
||||
/// @brief: 注册设备号
|
||||
/// @parameter: device_number: 设备号,主设备号如果为0,则动态分配
|
||||
/// minorct: 次设备号数量
|
||||
/// name: 字符设备名
|
||||
/// @return: 如果注册成功,返回设备号,否则,返回错误码
|
||||
fn __register_chardev_region(
|
||||
device_number: DeviceNumber,
|
||||
minorct: usize,
|
||||
name: &'static str,
|
||||
) -> Result<DeviceNumber, SystemError> {
|
||||
let mut major = device_number.major();
|
||||
let baseminor = device_number.minor();
|
||||
if major >= CHARDEV_MAJOR_MAX {
|
||||
kerror!(
|
||||
"CHARDEV {} major requested {} is greater than the maximum {}\n",
|
||||
name,
|
||||
major,
|
||||
CHARDEV_MAJOR_MAX - 1
|
||||
);
|
||||
}
|
||||
if minorct > MINOR_MASK + 1 - baseminor {
|
||||
kerror!("CHARDEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
|
||||
name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK);
|
||||
}
|
||||
let chardev = CharDeviceStruct::new(mkdev(major, baseminor), minorct, name);
|
||||
if major == 0 {
|
||||
// 如果主设备号为0,则自动分配主设备号
|
||||
major = Self::find_dynamic_major().expect("Find synamic major error.\n");
|
||||
}
|
||||
if let Some(items) = CHARDEVS.0.lock().0.get_mut(Self::major_to_index(major)) {
|
||||
let mut insert_index: usize = 0;
|
||||
for (index, item) in items.iter().enumerate() {
|
||||
insert_index = index;
|
||||
match item.device_number().major().cmp(&major) {
|
||||
Ordering::Less => continue,
|
||||
Ordering::Greater => {
|
||||
break; // 大于则向后插入
|
||||
}
|
||||
Ordering::Equal => {
|
||||
if item.device_number().minor() + item.minorct() <= baseminor {
|
||||
continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
|
||||
}
|
||||
if item.base_minor() >= baseminor + minorct {
|
||||
break; // 在此处插入
|
||||
}
|
||||
return Err(SystemError::EBUSY); // 存在重合的次设备号
|
||||
}
|
||||
}
|
||||
}
|
||||
items.insert(insert_index, chardev);
|
||||
}
|
||||
return Ok(mkdev(major, baseminor));
|
||||
}
|
||||
|
||||
/// @brief: 注销设备号
|
||||
/// @parameter: major: 主设备号,如果为0,动态分配
|
||||
/// baseminor: 起始次设备号
|
||||
/// minorct: 次设备号数量
|
||||
/// @return: 如果注销成功,返回(),否则,返回错误码
|
||||
fn __unregister_chardev_region(
|
||||
device_number: DeviceNumber,
|
||||
minorct: usize,
|
||||
) -> Result<(), SystemError> {
|
||||
if let Some(items) = CHARDEVS
|
||||
.0
|
||||
.lock()
|
||||
.0
|
||||
.get_mut(Self::major_to_index(device_number.major()))
|
||||
{
|
||||
for (index, item) in items.iter().enumerate() {
|
||||
if item.device_number() == device_number && item.minorct() == minorct {
|
||||
// 设备号和数量都相等
|
||||
items.remove(index);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
return Err(SystemError::EBUSY);
|
||||
}
|
||||
|
||||
/// @brief: 字符设备注册
|
||||
/// @parameter: cdev: 字符设备实例
|
||||
/// dev_t: 字符设备号
|
||||
/// range: 次设备号范围
|
||||
/// @return: none
|
||||
#[allow(dead_code)]
|
||||
pub fn cdev_add(cdev: Arc<dyn CharDevice>, dev_t: DeviceNumber, range: usize) {
|
||||
if Into::<usize>::into(dev_t) == 0 {
|
||||
kerror!("Device number can't be 0!\n");
|
||||
}
|
||||
kobj_map(CDEVMAP.clone(), dev_t, range, cdev);
|
||||
}
|
||||
|
||||
/// @brief: 字符设备注销
|
||||
/// @parameter: dev_t: 字符设备号
|
||||
/// range: 次设备号范围
|
||||
/// @return: none
|
||||
#[allow(dead_code)]
|
||||
pub fn cdev_del(dev_t: DeviceNumber, range: usize) {
|
||||
kobj_unmap(CDEVMAP.clone(), dev_t, range);
|
||||
}
|
||||
}
|
@ -175,8 +175,8 @@ impl LockedBusManager {
|
||||
/// @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()) {
|
||||
BUS_MANAGER.add_bus(bus.id_table(), bus.clone());
|
||||
match sys_bus_register(&bus.id_table().to_name()) {
|
||||
Ok(inode) => {
|
||||
let _ = sys_bus_init(&inode);
|
||||
return device_register(bus);
|
||||
@ -190,7 +190,7 @@ pub fn bus_register<T: Bus>(bus: Arc<T>) -> Result<(), DeviceError> {
|
||||
/// @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());
|
||||
BUS_MANAGER.add_bus(bus.id_table(), bus.clone());
|
||||
return device_unregister(bus);
|
||||
}
|
||||
|
||||
@ -198,7 +198,7 @@ pub fn bus_unregister<T: Bus>(bus: Arc<T>) -> Result<(), DeviceError> {
|
||||
/// @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());
|
||||
BUS_MANAGER.add_driver(bus_driver.id_table(), bus_driver.clone());
|
||||
return driver_register(bus_driver);
|
||||
}
|
||||
|
||||
@ -207,6 +207,6 @@ pub fn bus_driver_register<T: BusDriver>(bus_driver: Arc<T>) -> Result<(), Drive
|
||||
/// @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());
|
||||
BUS_MANAGER.add_driver(bus_driver.id_table(), bus_driver.clone());
|
||||
return driver_unregister(bus_driver);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::IdTable;
|
||||
use super::{IdTable, KObject};
|
||||
use crate::{filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError};
|
||||
use alloc::{collections::BTreeMap, sync::Arc};
|
||||
use core::{any::Any, fmt::Debug};
|
||||
use core::fmt::Debug;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref DRIVER_MANAGER: Arc<LockedDriverManager> = Arc::new(LockedDriverManager::new());
|
||||
@ -25,16 +25,16 @@ impl Into<SystemError> for DriverError {
|
||||
}
|
||||
|
||||
/// @brief: 所有驱动驱动都应该实现该trait
|
||||
pub trait Driver: Any + Send + Sync + Debug {
|
||||
pub trait Driver: KObject {
|
||||
/// @brief: 本函数用于实现动态转换
|
||||
/// @parameter: None
|
||||
/// @return: 该驱动驱动唯一标识符
|
||||
/// @return: any
|
||||
fn as_any_ref(&'static self) -> &'static dyn core::any::Any;
|
||||
|
||||
/// @brief: 获取驱动驱动标识符
|
||||
/// @parameter: None
|
||||
/// @return: 该驱动驱动唯一标识符
|
||||
fn get_id_table(&self) -> IdTable;
|
||||
fn id_table(&self) -> IdTable;
|
||||
|
||||
/// @brief: 设置驱动的sys information
|
||||
/// @parameter id_table: 驱动标识符,用于唯一标识该驱动
|
||||
@ -125,7 +125,7 @@ impl DriverManager {
|
||||
/// @parameter: name: 驱动名
|
||||
/// @return: 操作成功,返回(),操作失败,返回错误码
|
||||
pub fn driver_register<T: Driver>(driver: Arc<T>) -> Result<(), DriverError> {
|
||||
DRIVER_MANAGER.add_driver(driver.get_id_table(), driver);
|
||||
DRIVER_MANAGER.add_driver(driver.id_table(), driver);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@ -134,6 +134,6 @@ pub fn driver_register<T: Driver>(driver: Arc<T>) -> Result<(), DriverError> {
|
||||
/// @return: 操作成功,返回(),操作失败,返回错误码
|
||||
#[allow(dead_code)]
|
||||
pub fn driver_unregister<T: Driver>(driver: Arc<T>) -> Result<(), DriverError> {
|
||||
DRIVER_MANAGER.add_driver(driver.get_id_table(), driver);
|
||||
DRIVER_MANAGER.add_driver(driver.id_table(), driver);
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
use alloc::{collections::BTreeMap, string::String, sync::Arc};
|
||||
|
||||
use crate::{
|
||||
filesystem::{
|
||||
sysfs::{
|
||||
@ -11,6 +9,7 @@ use crate::{
|
||||
libs::spinlock::SpinLock,
|
||||
syscall::SystemError,
|
||||
};
|
||||
use alloc::{collections::BTreeMap, string::String, sync::Arc};
|
||||
use core::{any::Any, fmt::Debug};
|
||||
|
||||
pub mod bus;
|
||||
@ -20,6 +19,61 @@ 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)]
|
||||
@ -112,16 +166,21 @@ impl From<DeviceState> for u32 {
|
||||
}
|
||||
|
||||
/// @brief: 所有设备都应该实现该trait
|
||||
pub trait Device: Any + Send + Sync + Debug {
|
||||
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 get_type(&self) -> DeviceType;
|
||||
fn dev_type(&self) -> DeviceType;
|
||||
|
||||
/// @brief: 获取设备标识
|
||||
/// @parameter: None
|
||||
/// @return: 该设备唯一标识
|
||||
fn get_id_table(&self) -> IdTable;
|
||||
fn id_table(&self) -> IdTable;
|
||||
|
||||
/// @brief: 设置sysfs info
|
||||
/// @parameter: None
|
||||
@ -208,8 +267,8 @@ impl DeviceManager {
|
||||
/// @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()) {
|
||||
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(());
|
||||
@ -222,8 +281,8 @@ pub fn device_register<T: Device>(device: Arc<T>) -> Result<(), DeviceError> {
|
||||
/// @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()) {
|
||||
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(());
|
||||
|
98
kernel/src/driver/base/map/mod.rs
Normal file
98
kernel/src/driver/base/map/mod.rs
Normal file
@ -0,0 +1,98 @@
|
||||
use super::device::{mkdev, DeviceNumber, KObject};
|
||||
use crate::libs::spinlock::SpinLock;
|
||||
use alloc::{collections::BTreeMap, sync::Arc, vec::Vec};
|
||||
|
||||
const KOBJMAP_HASH_SIZE: usize = 255;
|
||||
|
||||
/// @brief: 字符设备与块设备管理结构体
|
||||
#[derive(Debug, Clone)]
|
||||
struct Probe(Arc<dyn KObject>);
|
||||
|
||||
impl Probe {
|
||||
/// @brief: 新建probe实例
|
||||
/// @parameter: data: probe实例
|
||||
/// @return: probe实例
|
||||
pub fn new(data: Arc<dyn KObject>) -> Self {
|
||||
Self(data)
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief: 字符设备和块设备管理实例(锁)
|
||||
#[derive(Debug)]
|
||||
pub struct LockedKObjMap(SpinLock<KObjMap>);
|
||||
|
||||
impl Default for LockedKObjMap {
|
||||
fn default() -> Self {
|
||||
Self(SpinLock::new(KObjMap::default()))
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief: 字符设备和块设备管理实例
|
||||
#[derive(Debug, Clone)]
|
||||
struct KObjMap(Vec<BTreeMap<DeviceNumber, Probe>>);
|
||||
|
||||
impl Default for KObjMap {
|
||||
fn default() -> Self {
|
||||
Self(vec![BTreeMap::new(); KOBJMAP_HASH_SIZE])
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief: obj设备注册
|
||||
/// @parameter: domain: 管理实例
|
||||
/// dev_t: 设备号
|
||||
/// range: 次设备号范围
|
||||
/// data: 设备实例
|
||||
/// @return: none
|
||||
pub fn kobj_map(
|
||||
domain: Arc<LockedKObjMap>,
|
||||
dev_t: DeviceNumber,
|
||||
range: usize,
|
||||
data: Arc<dyn KObject>,
|
||||
) {
|
||||
if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) {
|
||||
for i in 0..range {
|
||||
map.insert(
|
||||
mkdev(dev_t.major(), dev_t.minor() + i),
|
||||
Probe::new(data.clone()),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief: obj设备注销
|
||||
/// @parameter: domain: 管理实例
|
||||
/// dev_t: 设备号
|
||||
/// range: 次设备号范围
|
||||
/// @return: none
|
||||
pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize) {
|
||||
if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) {
|
||||
for i in 0..range {
|
||||
let rm_dev_t = &DeviceNumber::new(Into::<usize>::into(dev_t) + i);
|
||||
match map.get(rm_dev_t) {
|
||||
Some(_) => {
|
||||
map.remove(rm_dev_t);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief: 设备查找
|
||||
/// @parameter: domain: 管理实例
|
||||
/// dev_t: 设备号
|
||||
/// @return: 查找成功,返回设备实例,否则返回None
|
||||
#[allow(dead_code)]
|
||||
pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>> {
|
||||
if let Some(map) = domain.0.lock().0.get(dev_t.major() % 255) {
|
||||
match map.get(&dev_t) {
|
||||
Some(value) => {
|
||||
return Some(value.0.clone());
|
||||
}
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
@ -1,2 +1,4 @@
|
||||
pub mod char;
|
||||
pub mod device;
|
||||
pub mod map;
|
||||
pub mod platform;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::device::{
|
||||
bus::{bus_driver_register, bus_register, Bus, BusDriver, BusState},
|
||||
driver::Driver,
|
||||
Device, DeviceError, DeviceState, DeviceType, IdTable,
|
||||
Device, DeviceError, DeviceState, DeviceType, IdTable, KObject,
|
||||
};
|
||||
use crate::{filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError};
|
||||
use alloc::{
|
||||
@ -94,7 +94,7 @@ impl LockedPlatformBusDriver {
|
||||
/// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型
|
||||
#[allow(dead_code)]
|
||||
fn register_platform_driver(&self, driver: Arc<dyn PlatformDriver>) -> Result<(), DeviceError> {
|
||||
let id_table = driver.get_id_table();
|
||||
let id_table = driver.id_table();
|
||||
|
||||
let drivers = &mut self.0.lock().drivers;
|
||||
// 如果存在同类型的驱动,返回错误
|
||||
@ -112,7 +112,7 @@ impl LockedPlatformBusDriver {
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
fn unregister_platform_driver(&mut self, driver: Arc<dyn PlatformDriver>) {
|
||||
let id_table = driver.get_id_table();
|
||||
let id_table = driver.id_table();
|
||||
self.0.lock().drivers.remove(&id_table);
|
||||
}
|
||||
|
||||
@ -124,7 +124,7 @@ impl LockedPlatformBusDriver {
|
||||
&mut self,
|
||||
device: Arc<dyn PlatformDevice>,
|
||||
) -> Result<(), DeviceError> {
|
||||
let id_table = device.get_id_table();
|
||||
let id_table = device.id_table();
|
||||
|
||||
let devices = &mut self.0.lock().devices;
|
||||
if devices.contains_key(&id_table) {
|
||||
@ -141,7 +141,7 @@ impl LockedPlatformBusDriver {
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
fn unregister_platform_device(&mut self, device: Arc<dyn PlatformDevice>) {
|
||||
let id_table = device.get_id_table();
|
||||
let id_table = device.id_table();
|
||||
self.0.lock().devices.remove(&id_table);
|
||||
}
|
||||
|
||||
@ -155,8 +155,8 @@ impl LockedPlatformBusDriver {
|
||||
|
||||
for (_dev_id_table, device) in devices.iter() {
|
||||
if device
|
||||
.get_compatible_table()
|
||||
.matches(&driver.get_compatible_table())
|
||||
.compatible_table()
|
||||
.matches(&driver.compatible_table())
|
||||
{
|
||||
if !device.is_initialized() {
|
||||
// 设备未初始化,调用驱动probe函数
|
||||
@ -186,8 +186,8 @@ impl LockedPlatformBusDriver {
|
||||
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())
|
||||
.compatible_table()
|
||||
.matches(&device.compatible_table())
|
||||
{
|
||||
match driver.probe(device.clone()) {
|
||||
Ok(_driver) => {
|
||||
@ -234,7 +234,7 @@ impl Driver for LockedPlatformBusDriver {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_id_table(&self) -> IdTable {
|
||||
fn id_table(&self) -> IdTable {
|
||||
IdTable::new("PlatformBusDriver", 0)
|
||||
}
|
||||
|
||||
@ -262,6 +262,8 @@ impl BusDriver for LockedPlatformBusDriver {
|
||||
}
|
||||
}
|
||||
|
||||
impl KObject for LockedPlatformBusDriver {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LockedPlatform(SpinLock<Platform>);
|
||||
|
||||
@ -278,7 +280,7 @@ impl LockedPlatform {
|
||||
/// @return: platform总线匹配表
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
fn get_compatible_table(&self) -> CompatibleTable {
|
||||
fn compatible_table(&self) -> CompatibleTable {
|
||||
CompatibleTable::new(vec!["platform"])
|
||||
}
|
||||
|
||||
@ -350,13 +352,13 @@ impl Platform {
|
||||
impl Device for LockedPlatform {
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
fn get_type(&self) -> DeviceType {
|
||||
fn dev_type(&self) -> DeviceType {
|
||||
return DeviceType::Bus;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
fn get_id_table(&self) -> IdTable {
|
||||
fn id_table(&self) -> IdTable {
|
||||
IdTable::new("platform", 0)
|
||||
}
|
||||
|
||||
@ -370,11 +372,17 @@ impl Device for LockedPlatform {
|
||||
fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
|
||||
return self.0.lock().sys_info.clone();
|
||||
}
|
||||
|
||||
fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief: 为Platform实现Bus trait,platform总线是一种总线设备
|
||||
impl Bus for LockedPlatform {}
|
||||
|
||||
impl KObject for LockedPlatform {}
|
||||
|
||||
/// @brief: 初始化platform总线
|
||||
/// @parameter: None
|
||||
/// @return: None
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::{
|
||||
super::device::{Device, DeviceState, DeviceType},
|
||||
super::device::{Device, DeviceState},
|
||||
platform_driver::PlatformDriver,
|
||||
CompatibleTable,
|
||||
};
|
||||
@ -8,14 +8,10 @@ use alloc::sync::Arc;
|
||||
/// @brief: 实现该trait的设备实例应挂载在platform总线上,
|
||||
/// 同时应该实现Device trait
|
||||
pub trait PlatformDevice: Device {
|
||||
fn get_type(&self) -> DeviceType {
|
||||
DeviceType::PlatformDev
|
||||
}
|
||||
|
||||
/// @brief: 获取设备匹配表
|
||||
/// @parameter: None
|
||||
/// @return: 设备匹配表
|
||||
fn get_compatible_table(&self) -> CompatibleTable;
|
||||
fn compatible_table(&self) -> CompatibleTable;
|
||||
|
||||
/// @brief: 判断设备是否初始化
|
||||
/// @parameter: None
|
||||
|
@ -16,5 +16,5 @@ pub trait PlatformDriver: Driver {
|
||||
/// @brief: 获取驱动匹配表
|
||||
/// @parameter: None
|
||||
/// @return: 驱动匹配表
|
||||
fn get_compatible_table(&self) -> CompatibleTable;
|
||||
fn compatible_table(&self) -> CompatibleTable;
|
||||
}
|
||||
|
@ -1,4 +1,21 @@
|
||||
use crate::include::bindings::bindings::{io_in8, io_out8};
|
||||
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,
|
||||
},
|
||||
},
|
||||
filesystem::{
|
||||
sysfs::bus::{bus_device_register, bus_driver_register},
|
||||
vfs::IndexNode,
|
||||
},
|
||||
include::bindings::bindings::{io_in8, io_out8},
|
||||
libs::spinlock::SpinLock,
|
||||
syscall::SystemError,
|
||||
};
|
||||
use alloc::sync::Arc;
|
||||
use core::{char, intrinsics::offset, str};
|
||||
|
||||
const UART_SUCCESS: i32 = 0;
|
||||
@ -6,9 +23,17 @@ const E_UART_BITS_RATE_ERROR: i32 = 1;
|
||||
const E_UART_SERIAL_FAULT: i32 = 2;
|
||||
const UART_MAX_BITS_RATE: u32 = 115200;
|
||||
|
||||
lazy_static! {
|
||||
// 串口设备
|
||||
pub static ref UART_DEV: Arc<LockedUart> = Arc::new(LockedUart::default());
|
||||
// 串口驱动
|
||||
pub static ref UART_DRV: Arc<LockedUartDriver> = Arc::new(LockedUartDriver::default());
|
||||
}
|
||||
|
||||
// @brief 串口端口
|
||||
#[allow(dead_code)]
|
||||
#[repr(u16)]
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum UartPort {
|
||||
COM1 = 0x3f8,
|
||||
COM2 = 0x2f8,
|
||||
@ -57,6 +82,7 @@ impl UartPort {
|
||||
}
|
||||
}
|
||||
|
||||
// @brief 串口寄存器
|
||||
#[allow(dead_code)]
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@ -71,10 +97,88 @@ struct UartRegister {
|
||||
reg_scartch: u8,
|
||||
}
|
||||
|
||||
// @brief 串口设备结构体
|
||||
#[derive(Debug)]
|
||||
pub struct Uart {
|
||||
state: DeviceState, // 设备状态
|
||||
sys_info: Option<Arc<dyn IndexNode>>,
|
||||
driver: Option<Arc<dyn PlatformDriver>>,
|
||||
}
|
||||
|
||||
impl Default for Uart {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
state: DeviceState::NotInitialized,
|
||||
sys_info: None,
|
||||
driver: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @brief 串口设备结构体(加锁)
|
||||
#[derive(Debug)]
|
||||
pub struct LockedUart(SpinLock<Uart>);
|
||||
|
||||
impl Default for LockedUart {
|
||||
fn default() -> Self {
|
||||
Self(SpinLock::new(Uart::default()))
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
match state {
|
||||
DeviceState::Initialized => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_state(&self, set_state: DeviceState) {
|
||||
let state = &mut self.0.lock().state;
|
||||
*state = set_state;
|
||||
}
|
||||
|
||||
fn set_driver(&self, driver: Option<Arc<dyn PlatformDriver>>) {
|
||||
self.0.lock().driver = driver;
|
||||
}
|
||||
}
|
||||
|
||||
impl Device for LockedUart {
|
||||
fn id_table(&self) -> IdTable {
|
||||
IdTable::new("uart", 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>> {
|
||||
self.0.lock().sys_info.clone()
|
||||
}
|
||||
|
||||
fn dev_type(&self) -> DeviceType {
|
||||
DeviceType::Serial
|
||||
}
|
||||
|
||||
fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
// @brief 串口驱动结构体
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UartDriver {
|
||||
port: UartPort,
|
||||
baud_rate: u32,
|
||||
sys_info: Option<Arc<dyn IndexNode>>,
|
||||
}
|
||||
|
||||
impl Default for UartDriver {
|
||||
@ -82,11 +186,91 @@ impl Default for UartDriver {
|
||||
Self {
|
||||
port: UartPort::COM1,
|
||||
baud_rate: 115200,
|
||||
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(&'static self) -> &'static dyn core::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn id_table(&self) -> IdTable {
|
||||
return IdTable::new("uart_driver", 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();
|
||||
}
|
||||
}
|
||||
|
||||
impl CharDevice for LockedUartDriver {
|
||||
fn open(&self, _file: Arc<dyn IndexNode>) -> Result<(), crate::syscall::SystemError> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn close(&self, _file: Arc<dyn IndexNode>) -> Result<(), crate::syscall::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)))
|
||||
}
|
||||
}
|
||||
|
||||
impl PlatformDriver for LockedUartDriver {
|
||||
fn probe(
|
||||
&self,
|
||||
_device: Arc<dyn PlatformDevice>,
|
||||
) -> Result<(), crate::driver::base::device::driver::DriverError> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn compatible_table(&self) -> platform::CompatibleTable {
|
||||
return CompatibleTable::new(vec!["uart"]);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 串口初始化
|
||||
/// @param uart_port 端口号
|
||||
/// @param baud_rate 波特率
|
||||
@ -176,6 +360,11 @@ impl UartDriver {
|
||||
while UartDriver::serial_received(port) == false {} //TODO:pause
|
||||
unsafe { io_in8(port) as char }
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn port() -> u16 {
|
||||
UartPort::COM1.to_u16()
|
||||
}
|
||||
}
|
||||
|
||||
///@brief 发送数据
|
||||
@ -231,7 +420,7 @@ pub extern "C" fn c_uart_init(port: u16, baud_rate: u32) -> i32 {
|
||||
let divisor = UART_MAX_BITS_RATE / baud_rate;
|
||||
|
||||
io_out8(port + 0, (divisor & 0xff) as u8); // Set divisor (lo byte)
|
||||
io_out8(port + 1, ((divisor >> 8) & 0xff) as u8); // (hi byte)
|
||||
io_out8(port + 1, ((divisor >> 8) & 0xff) as u8); // CompatibleTable(hi byte)
|
||||
io_out8(port + 3, 0x03); // 8 bits, no parity, one stop bit
|
||||
io_out8(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
||||
io_out8(port + 4, 0x08); // IRQs enabled, RTS/DSR clear (现代计算机上一般都不需要hardware flow control,因此不需要置位RTS/DSR)
|
||||
@ -261,3 +450,18 @@ pub extern "C" fn c_uart_init(port: u16, baud_rate: u32) -> i32 {
|
||||
clears the DLAB again as well as setting various other bits.
|
||||
*/
|
||||
}
|
||||
|
||||
/// @brief 串口初始化,注册串口
|
||||
/// @param none
|
||||
/// @return 初始化成功,返回(),失败,返回错误码
|
||||
pub fn uart_init() -> Result<(), SystemError> {
|
||||
let device_inode = bus_device_register("platform:0", &UART_DEV.id_table().to_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())
|
||||
.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);
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
use super::{LockedSysFSInode, SYS_BUS_INODE};
|
||||
use crate::{filesystem::vfs::IndexNode, kdebug, syscall::SystemError};
|
||||
use crate::{
|
||||
filesystem::vfs::IndexNode,
|
||||
kdebug,
|
||||
syscall::SystemError,
|
||||
};
|
||||
use alloc::sync::Arc;
|
||||
|
||||
/// @brief: 注册bus,在sys/bus下生成文件夹
|
||||
@ -49,3 +53,51 @@ pub fn sys_bus_init(
|
||||
None => Err(SystemError::E2BIG),
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief: 在相应总线的device下生成设备文件夹
|
||||
/// @parameter bus_name: 总线名
|
||||
/// name: 设备名
|
||||
/// @return: 操作成功,返回device inode,操作失败,返回错误码
|
||||
pub fn bus_driver_register(
|
||||
bus_name: &str,
|
||||
name: &str,
|
||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||
match SYS_BUS_INODE().find(bus_name) {
|
||||
Ok(platform) => match platform.find("drivers") {
|
||||
Ok(device) => {
|
||||
device
|
||||
.as_any_ref()
|
||||
.downcast_ref::<LockedSysFSInode>()
|
||||
.ok_or(SystemError::E2BIG)
|
||||
.unwrap()
|
||||
.add_dir(name)
|
||||
}
|
||||
Err(_) => return Err(SystemError::EXDEV),
|
||||
},
|
||||
Err(_) => return Err(SystemError::EXDEV),
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief: 在相应总线的driver下生成驱动文件夹
|
||||
/// @parameter bus_name: 总线名
|
||||
/// name: 驱动名
|
||||
/// @return: 操作成功,返回drivers inode,操作失败,返回错误码
|
||||
pub fn bus_device_register(
|
||||
bus_name: &str,
|
||||
name: &str,
|
||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||
match SYS_BUS_INODE().find(bus_name) {
|
||||
Ok(platform) => match platform.find("devices") {
|
||||
Ok(device) => {
|
||||
device
|
||||
.as_any_ref()
|
||||
.downcast_ref::<LockedSysFSInode>()
|
||||
.ok_or(SystemError::E2BIG)
|
||||
.unwrap()
|
||||
.add_dir(name)
|
||||
}
|
||||
Err(_) => return Err(SystemError::EXDEV),
|
||||
},
|
||||
Err(_) => return Err(SystemError::EXDEV),
|
||||
}
|
||||
}
|
||||
|
@ -138,6 +138,8 @@ impl SysFS {
|
||||
}
|
||||
// 初始化platform总线
|
||||
crate::driver::base::platform::platform_bus_init().expect("platform bus init failed");
|
||||
// 初始化串口
|
||||
crate::driver::uart::uart::uart_init().expect("initilize uart error");
|
||||
return sysfs;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user