使用rust重构softirq机制;解决Rtc驱动的编译警告问题 (#138)

* 使用rust重构softirq机制
* 解决Rtc驱动的编译警告问题

Co-authored-by: longjin <longjin@RinGoTek.cn>
This commit is contained in:
Gou Ngai
2023-01-07 23:15:37 +08:00
committed by GitHub
parent e9fdc57bf8
commit 62e4613978
10 changed files with 386 additions and 257 deletions

View File

@ -1,4 +1,9 @@
pub struct rtc_time_t {
use crate::{
arch::interrupt::{cli, sti},
include::bindings::bindings::{io_in8, io_out8},
};
pub struct RtcTime {
pub second: i32,
pub minute: i32,
pub hour: i32,
@ -7,10 +12,79 @@ pub struct rtc_time_t {
pub year: i32,
}
use crate::{
arch::interrupt::{cli, sti},
include::bindings::bindings::{io_in8, io_out8},
};
impl Default for RtcTime {
fn default() -> Self {
Self {
second: (0),
minute: (0),
hour: (0),
day: (0),
month: (0),
year: (0),
}
}
}
impl RtcTime {
///@brief 从主板cmos中获取时间
///
///@param self time结构体
///@return int 成功则为0
pub fn get(&mut self) -> Result<i32, i32> {
// 为防止中断请求打断该过程,需要先关中断
cli();
//0x0B
let status_register_b: u8 = read_cmos(0x0B); // 读取状态寄存器B
let is_24h: bool = if (status_register_b & 0x02) != 0 {
true
} else {
false
}; // 判断是否启用24小时模式
let is_binary: bool = if (status_register_b & 0x04) != 0 {
true
} else {
false
}; // 判断是否为二进制码
loop {
self.year = read_cmos(CMOSTimeSelector::Year as u8) as i32;
self.month = read_cmos(CMOSTimeSelector::Month as u8) as i32;
self.day = read_cmos(CMOSTimeSelector::Day as u8) as i32;
self.hour = read_cmos(CMOSTimeSelector::Hour as u8) as i32;
self.minute = read_cmos(CMOSTimeSelector::Minute as u8) as i32;
self.second = read_cmos(CMOSTimeSelector::Second as u8) as i32;
if self.second == read_cmos(CMOSTimeSelector::Second as u8) as i32 {
break;
} // 若读取时间过程中时间发生跳变则重新读取
}
unsafe {
io_out8(0x70, 0x00);
}
if !is_binary
// 把BCD转为二进制
{
self.second = (self.second & 0xf) + (self.second >> 4) * 10;
self.minute = (self.minute & 0xf) + (self.minute >> 4) * 10;
self.hour = ((self.hour & 0xf) + ((self.hour & 0x70) >> 4) * 10) | (self.hour & 0x80);
self.day = (self.day & 0xf) + ((self.day / 16) * 10);
self.month = (self.month & 0xf) + (self.month >> 4) * 10;
self.year = (self.year & 0xf) + (self.year >> 4) * 10;
}
self.year += 2000;
if (!is_24h) && (self.hour & 0x80) != 0 {
self.hour = ((self.hour & 0x7f) + 12) % 24;
} // 将十二小时制转为24小时
sti();
return Ok(0);
}
}
///置位0x70的第7位禁止不可屏蔽中断
#[inline]
@ -21,69 +95,13 @@ fn read_cmos(addr: u8) -> u8 {
}
}
/// used in the form of u8
#[repr(u8)]
enum CMOSTimeSelector {
T_SECOND = 0x00,
T_MINUTE = 0x02,
T_HOUR = 0x04,
T_DAY = 0x07,
T_MONTH = 0x08,
T_YEAR = 0x09,
}
///@brief 从主板cmos中获取时间
///
///@param t time结构体
///@return int 成功则为0
pub fn rtc_get_cmos_time(t: &mut rtc_time_t) -> Result<i32,i32> {
unsafe {
// 为防止中断请求打断该过程,需要先关中断
cli();
//0x0B
let status_register_B: u8 = read_cmos(0x0B); // 读取状态寄存器B
let is_24h: bool = if (status_register_B & 0x02) != 0 {
true
} else {
false
}; // 判断是否启用24小时模式
let is_binary: bool = if (status_register_B & 0x04) != 0 {
true
} else {
false
}; // 判断是否为二进制码
loop {
t.year = read_cmos(CMOSTimeSelector::T_YEAR as u8) as i32;
t.month = read_cmos(CMOSTimeSelector::T_MONTH as u8) as i32;
t.day = read_cmos(CMOSTimeSelector::T_DAY as u8) as i32;
t.hour = read_cmos(CMOSTimeSelector::T_HOUR as u8) as i32;
t.minute = read_cmos(CMOSTimeSelector::T_MINUTE as u8) as i32;
t.second = read_cmos(CMOSTimeSelector::T_SECOND as u8) as i32;
if t.second == read_cmos(CMOSTimeSelector::T_SECOND as u8) as i32 {
break;
} // 若读取时间过程中时间发生跳变则重新读取
}
io_out8(0x70, 0x00);
if !is_binary
// 把BCD转为二进制
{
t.second = (t.second & 0xf) + (t.second >> 4) * 10;
t.minute = (t.minute & 0xf) + (t.minute >> 4) * 10;
t.hour = ((t.hour & 0xf) + ((t.hour & 0x70) >> 4) * 10) | (t.hour & 0x80);
t.day = (t.day & 0xf) + ((t.day / 16) * 10);
t.month = (t.month & 0xf) + (t.month >> 4) * 10;
t.year = (t.year & 0xf) + (t.year >> 4) * 10;
}
t.year += 2000;
if (!is_24h) && (t.hour & 0x80) != 0 {
t.hour = ((t.hour & 0x7f) + 12) % 24;
} // 将十二小时制转为24小时
sti();
}
return Ok(0);
Second = 0x00,
Minute = 0x02,
Hour = 0x04,
Day = 0x07,
Month = 0x08,
Year = 0x09,
}