浏览代码

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

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

Co-authored-by: longjin <longjin@RinGoTek.cn>
Gou Ngai 2 年之前
父节点
当前提交
62e4613978

+ 66 - 48
kernel/src/driver/timers/rtc/rtc.rs

@@ -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,83 +12,96 @@ pub struct rtc_time_t {
     pub year: i32,
 }
 
-use crate::{
-    arch::interrupt::{cli, sti},
-    include::bindings::bindings::{io_in8, io_out8},
-};
-
-///置位0x70的第7位,禁止不可屏蔽中断
-#[inline]
-fn read_cmos(addr: u8) -> u8 {
-    unsafe {
-        io_out8(0x70, 0x80 | addr);
-        return io_in8(0x71);
+impl Default for RtcTime {
+    fn default() -> Self {
+        Self {
+            second: (0),
+            minute: (0),
+            hour: (0),
+            day: (0),
+            month: (0),
+            year: (0),
+        }
     }
 }
 
-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 {
+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 {
+        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 {
+        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;
+            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 t.second == read_cmos(CMOSTimeSelector::T_SECOND as u8) as i32 {
+            if self.second == read_cmos(CMOSTimeSelector::Second as u8) as i32 {
                 break;
             } // 若读取时间过程中时间发生跳变则重新读取
         }
 
-        io_out8(0x70, 0x00);
+        unsafe {
+            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;
+            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;
         }
-        t.year += 2000;
+        self.year += 2000;
 
-        if (!is_24h) && (t.hour & 0x80) != 0 {
-            t.hour = ((t.hour & 0x7f) + 12) % 24;
+        if (!is_24h) && (self.hour & 0x80) != 0 {
+            self.hour = ((self.hour & 0x7f) + 12) % 24;
         } // 将十二小时制转为24小时
 
         sti();
+
+        return Ok(0);
     }
-    return Ok(0);
+}
+
+///置位0x70的第7位,禁止不可屏蔽中断
+#[inline]
+fn read_cmos(addr: u8) -> u8 {
+    unsafe {
+        io_out8(0x70, 0x80 | addr);
+        return io_in8(0x71);
+    }
+}
+
+/// used in the form of u8
+#[repr(u8)]
+enum CMOSTimeSelector {
+    Second = 0x00,
+    Minute = 0x02,
+    Hour = 0x04,
+    Day = 0x07,
+    Month = 0x08,
+    Year = 0x09,
 }

+ 1 - 4
kernel/src/exception/Makefile

@@ -2,7 +2,7 @@
 CFLAGS += -I .
 
 
-all: entry.o irq.o softirq.o trap.o
+all: entry.o irq.o trap.o
 
 entry.o: entry.S
 	$(CC) -E entry.S > _entry.s
@@ -11,8 +11,5 @@ entry.o: entry.S
 trap.o: trap.c
 	$(CC) $(CFLAGS) -c trap.c -o trap.o
 
-softirq.o: softirq.c
-	$(CC) $(CFLAGS) -c softirq.c -o softirq.o
-
 irq.o: irq.c
 	$(CC) $(CFLAGS) -c irq.c -o irq.o

+ 0 - 1
kernel/src/exception/irq.c

@@ -175,7 +175,6 @@ int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter
     p->parameter = paramater;
     p->flags = 0;
     p->handler = handler;
-
     io_mfence();
     p->controller->install(irq_num, arg);
     io_mfence();

+ 1 - 0
kernel/src/exception/mod.rs

@@ -0,0 +1 @@
+pub mod softirq;

+ 0 - 120
kernel/src/exception/softirq.c

@@ -1,120 +0,0 @@
-#include "softirq.h"
-#include <common/kprint.h>
-#include <process/process.h>
-#include <driver/video/video.h>
-#include <common/spinlock.h>
-
-static struct softirq_t softirq_vector[MAX_SOFTIRQ_NUM] = {0};
-static spinlock_t softirq_modify_lock; // 软中断状态(status)
-static volatile uint64_t softirq_pending = 0;
-static volatile uint64_t softirq_running = 0;
-
-void set_softirq_pending(uint64_t status)
-{
-    softirq_pending |= status;
-}
-
-uint64_t get_softirq_pending()
-{
-    return softirq_pending;
-}
-
-#define get_softirq_running() (softirq_running)
-
-/**
- * @brief 设置软中断运行结束
- *
- * @param softirq_num
- */
-#define clear_softirq_running(softirq_num)        \
-    do                                            \
-    {                                             \
-        softirq_running &= (~(1 << softirq_num)); \
-    } while (0)
-
-// 设置软中断的运行状态(只应在do_softirq中调用此宏)
-#define set_softirq_running(softirq_num)       \
-    do                                         \
-    {                                          \
-        softirq_running |= (1 << softirq_num); \
-    } while (0)
-
-/**
- * @brief 清除软中断pending标志位
- *
- */
-#define softirq_ack(sirq_num)                  \
-    do                                         \
-    {                                          \
-        softirq_pending &= (~(1 << sirq_num)); \
-    } while (0);
-
-/**
- * @brief 软中断注册函数
- *
- * @param irq_num 软中断号
- * @param action 响应函数
- * @param data 响应数据结构体
- */
-void register_softirq(uint32_t irq_num, void (*action)(void *data), void *data)
-{
-    softirq_vector[irq_num].action = action;
-    softirq_vector[irq_num].data = data;
-}
-
-/**
- * @brief 卸载软中断
- *
- * @param irq_num 软中断号
- */
-void unregister_softirq(uint32_t irq_num)
-{
-    softirq_vector[irq_num].action = NULL;
-    softirq_vector[irq_num].data = NULL;
-}
-
-/**
- * @brief 软中断处理程序
- *
- */
-void do_softirq()
-{
-    sti();
-
-    for (uint32_t i = 0; i < MAX_SOFTIRQ_NUM && softirq_pending; ++i)
-    {
-        if (softirq_pending & (1 << i) && softirq_vector[i].action != NULL && (!(get_softirq_running() & (1 << i))))
-        {
-            if (spin_trylock(&softirq_modify_lock))
-            {
-                // 检测该软中断是否已经被其他进程执行
-                if(get_softirq_running() & (1 << i))
-                {
-                    spin_unlock(&softirq_modify_lock);
-                    continue;
-                }
-                softirq_ack(i);
-                set_softirq_running(i);
-                spin_unlock(&softirq_modify_lock);
-
-                softirq_vector[i].action(softirq_vector[i].data);
-
-                clear_softirq_running(i);
-            }
-        }
-    }
-
-    cli();
-}
-
-int clear_softirq_pending(uint32_t irq_num)
-{
-    clear_softirq_running(irq_num);
-}
-
-void softirq_init()
-{
-    softirq_pending = 0;
-    memset(softirq_vector, 0, sizeof(struct softirq_t) * MAX_SOFTIRQ_NUM);
-    spin_init(&softirq_modify_lock);
-}

+ 10 - 45
kernel/src/exception/softirq.h

@@ -12,51 +12,16 @@
 
 #include <common/glib.h>
 
+// ==================implementation with rust===================
+extern void softirq_init();
+extern void raise_softirq(uint64_t sirq_num);
+extern int register_softirq(uint32_t irq_num, void (*action)(void *data), void *data);
+extern int unregister_softirq(uint32_t irq_num);
+extern void set_softirq_pending(uint64_t status);
+extern void clear_softirq_pending(uint32_t irq_num);
+extern void do_softirq();
+
+// for temporary
 #define MAX_SOFTIRQ_NUM 64
-
 #define TIMER_SIRQ 0         // 时钟软中断号
 #define VIDEO_REFRESH_SIRQ 1 // 帧缓冲区刷新软中断
-
-/**
- * @brief 发起软中断
- *
- */
-#define raise_softirq(sirq_num)                                                                                        \
-    do                                                                                                                 \
-    {                                                                                                                  \
-        set_softirq_pending(1 << sirq_num);                                                                            \
-    } while (0);
-
-struct softirq_t
-{
-    void (*action)(void *data); // 软中断处理函数
-    void *data;
-};
-
-/**
- * @brief 软中断注册函数
- *
- * @param irq_num 软中断号
- * @param action 响应函数
- * @param data 响应数据结构体
- */
-void register_softirq(uint32_t irq_num, void (*action)(void *data), void *data);
-
-/**
- * @brief 卸载软中断
- *
- * @param irq_num 软中断号
- */
-void unregister_softirq(uint32_t irq_num);
-
-void set_softirq_pending(uint64_t status);
-uint64_t get_softirq_pending();
-
-int clear_softirq_pending(uint32_t irq_num);
-/**
- * @brief 软中断处理程序
- *
- */
-void do_softirq();
-
-void softirq_init();

+ 266 - 0
kernel/src/exception/softirq.rs

@@ -0,0 +1,266 @@
+use core::{ffi::c_void, ptr::null_mut};
+
+use alloc::boxed::Box;
+
+use crate::{
+    arch::interrupt::{cli, sti},
+    include::bindings::bindings::{verify_area, EBUSY, EEXIST, EPERM},
+    kBUG,
+    libs::spinlock::RawSpinlock,
+};
+
+const MAX_SOFTIRQ_NUM: u64 = 64;
+const MAX_LOCK_TRIAL_TIME: u64 = 50;
+pub static mut SOFTIRQ_HANDLER_PTR: *mut Softirq = null_mut();
+
+/// 软中断向量号码
+#[allow(dead_code)]
+#[repr(u8)]
+pub enum SoftirqNumber {
+    TIMER = 0,        //时钟软中断信号
+    VideoRefresh = 1, //帧缓冲区刷新软中断
+}
+
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct SoftirqVector {
+    pub action: Option<unsafe extern "C" fn(data: *mut ::core::ffi::c_void)>, //软中断处理函数
+    pub data: *mut c_void,
+}
+
+impl Default for SoftirqVector {
+    fn default() -> Self {
+        Self {
+            action: None,
+            data: null_mut(),
+        }
+    }
+}
+
+pub struct Softirq {
+    modify_lock: RawSpinlock,
+    pending: u64,
+    running: u64,
+    table: [SoftirqVector; MAX_SOFTIRQ_NUM as usize],
+}
+
+#[no_mangle]
+#[allow(dead_code)]
+/// @brief 提供给c的接口函数,用于初始化静态指针
+pub extern "C" fn softirq_init() {
+    if unsafe { SOFTIRQ_HANDLER_PTR.is_null() } {
+        unsafe {
+            SOFTIRQ_HANDLER_PTR = Box::leak(Box::new(Softirq::default()));
+        }
+    } else {
+        kBUG!("Try to init SOFTIRQ_HANDLER_PTR twice.");
+        panic!("Try to init SOFTIRQ_HANDLER_PTR twice.");
+    }
+}
+
+/// @brief 将raw pointer转换为指针,减少unsafe块
+#[inline]
+pub fn __get_softirq_handler_mut() -> &'static mut Softirq {
+    return unsafe { SOFTIRQ_HANDLER_PTR.as_mut().unwrap() };
+}
+
+#[no_mangle]
+#[allow(dead_code)]
+pub extern "C" fn raise_softirq(sirq_num: u64) {
+    let softirq_handler = __get_softirq_handler_mut();
+    softirq_handler.set_softirq_pending(1 << sirq_num);
+}
+
+/// @brief 软中断注册函数
+///
+/// @param irq_num 软中断号
+/// @param action 响应函数
+/// @param data 响应数据结构体
+#[no_mangle]
+#[allow(dead_code)]
+pub extern "C" fn register_softirq(
+    irq_num: u32,
+    action: Option<unsafe extern "C" fn(data: *mut ::core::ffi::c_void)>,
+    data: *mut c_void,
+) {
+    let softirq_handler = __get_softirq_handler_mut();
+    softirq_handler.register_softirq(irq_num, action, data);
+}
+
+/// @brief 卸载软中断
+/// @param irq_num 软中断号
+#[no_mangle]
+#[allow(dead_code)]
+pub extern "C" fn unregister_softirq(irq_num: u32) {
+    let softirq_handler = __get_softirq_handler_mut();
+    softirq_handler.unregister_softirq(irq_num);
+}
+
+/// 设置软中断的运行状态(只应在do_softirq中调用此宏)
+#[no_mangle]
+#[allow(dead_code)]
+pub extern "C" fn set_softirq_pending(irq_num: u32) {
+    let softirq_handler = __get_softirq_handler_mut();
+    softirq_handler.set_softirq_pending(irq_num);
+}
+
+/// @brief 设置软中断运行结束
+///
+/// @param softirq_num
+#[no_mangle]
+#[allow(dead_code)]
+pub extern "C" fn clear_softirq_pending(irq_num: u32) {
+    let softirq_handler = __get_softirq_handler_mut();
+    softirq_handler.clear_softirq_pending(irq_num);
+}
+
+/// @brief 软中断处理程序
+#[no_mangle]
+#[allow(dead_code)]
+pub extern "C" fn do_softirq() {
+    let softirq_handler = __get_softirq_handler_mut();
+    softirq_handler.do_softirq();
+}
+
+impl Default for Softirq {
+    fn default() -> Self {
+        Self {
+            modify_lock: RawSpinlock::INIT,
+            pending: (0),
+            running: (0),
+            table: [Default::default(); MAX_SOFTIRQ_NUM as usize],
+        }
+    }
+}
+
+impl Softirq {
+    #[inline]
+    #[allow(dead_code)]
+    pub fn get_softirq_pending(&self) -> u64 {
+        return self.pending;
+    }
+
+    #[inline]
+    #[allow(dead_code)]
+    pub fn get_softirq_running(&self) -> u64 {
+        return self.running;
+    }
+
+    #[inline]
+    pub fn set_softirq_pending(&mut self, softirq_num: u32) {
+        self.pending |= 1 << softirq_num;
+    }
+
+    #[inline]
+    pub fn set_softirq_running(&mut self, softirq_num: u32) {
+        self.running |= 1 << softirq_num;
+    }
+
+    #[inline]
+    pub fn clear_softirq_running(&mut self, softirq_num: u32) {
+        self.running &= !(1 << softirq_num);
+    }
+
+    /// @brief 清除软中断pending标志位
+    #[inline]
+    pub fn clear_softirq_pending(&mut self, softirq_num: u32) {
+        self.pending &= !(1 << softirq_num);
+    }
+
+    /// @brief 判断对应running标志位是否为0
+    /// @return true: 标志位为1; false: 标志位为0
+    #[inline]
+    pub fn is_running(&mut self, softirq_num: u32) -> bool {
+        return (self.running & (1 << softirq_num)).ne(&0);
+    }
+
+    /// @brief 判断对应pending标志位是否为0
+    /// @return true: 标志位为1; false: 标志位为0
+    #[inline]
+    pub fn is_pending(&mut self, softirq_num: u32) -> bool {
+        return (self.pending & (1 << softirq_num)).ne(&0);
+    }
+
+    /// @brief 注册软中断向量
+    /// @param irq_num 中断向量号码
+    /// @param action 中断函数的入口地址
+    /// @param data 中断函数的操作数据
+    pub fn register_softirq(
+        &mut self,
+        irq_num: u32,
+        action: Option<unsafe extern "C" fn(data: *mut ::core::ffi::c_void)>,
+        data: *mut c_void,
+    ) -> i32 {
+        if self.table[irq_num as usize].action.is_some() {
+            return -(EEXIST as i32);
+        }
+
+        if unsafe { verify_area(action.unwrap() as u64, 1) } {
+            return -(EPERM as i32);
+        }
+        self.modify_lock.lock();
+        self.table[irq_num as usize].action = action;
+        self.table[irq_num as usize].data = data;
+        self.modify_lock.unlock();
+        return 0;
+    }
+
+    /// @brief 解注册软中断向量
+    /// @param irq_num 中断向量号码
+    pub fn unregister_softirq(&mut self, irq_num: u32) -> i32 {
+        for _trial_time in 0..MAX_LOCK_TRIAL_TIME {
+            if self.is_running(irq_num) {
+                continue; //running标志位为1
+            }
+            if self.modify_lock.try_lock() {
+                if self.is_running(irq_num) {
+                    self.modify_lock.unlock();
+                    continue;
+                }
+                break;
+            }
+        }
+        // 存在尝试加锁规定次数后仍加锁失败的情况,报告错误并退出
+        if !self.modify_lock.is_locked() {
+            return -(EBUSY as i32);
+        }
+        self.clear_softirq_running(irq_num);
+        self.clear_softirq_pending(irq_num);
+        self.table[irq_num as usize].action = None;
+        self.table[irq_num as usize].data = null_mut();
+        self.modify_lock.unlock();
+        return 0;
+    }
+
+    /// @brief 遍历执行软中断
+    pub fn do_softirq(&mut self) {
+        sti();
+        let mut softirq_index: u32 = 0; //软中断向量号码
+        while (softirq_index as u64) < MAX_SOFTIRQ_NUM && self.pending != 0 {
+            if self.is_pending(softirq_index)
+                && self.table[softirq_index as usize].action.is_some()
+                && !self.is_running(softirq_index)
+            {
+                if self.modify_lock.try_lock() {
+                    if self.is_running(softirq_index)
+                        || self.table[softirq_index as usize].action.is_none()
+                    {
+                        self.modify_lock.unlock();
+                        continue;
+                    }
+                    self.clear_softirq_pending(softirq_index);
+                    self.set_softirq_running(softirq_index);
+                    self.modify_lock.unlock();
+                    unsafe {
+                        (self.table[softirq_index as usize].action.unwrap())(
+                            self.table[softirq_index as usize].data,
+                        );
+                    }
+                    self.clear_softirq_running(softirq_index);
+                }
+            }
+            softirq_index += 1;
+        }
+        cli();
+    }
+}

+ 2 - 1
kernel/src/lib.rs

@@ -4,7 +4,7 @@
 #![feature(alloc_error_handler)]
 #![feature(panic_info_message)]
 #![feature(drain_filter)] // 允许Vec的drain_filter特性
-
+#![feature(c_void_variant)] //not stable, used in /home/su/Documents/VSCode/DragonOS/kernel/src/exception/softirq.rs
 #[allow(non_upper_case_globals)]
 #[allow(non_camel_case_types)]
 #[allow(non_snake_case)]
@@ -28,6 +28,7 @@ mod process;
 mod sched;
 mod smp;
 mod time;
+mod exception;
 
 extern crate alloc;
 

+ 10 - 6
kernel/src/main.c

@@ -52,7 +52,8 @@ void reload_gdt()
     gdtp.size = bsp_gdt_size - 1;
     gdtp.gdt_vaddr = (ul)phys_2_virt((ul)&GDT_Table);
 
-    asm volatile("lgdt (%0)   \n\t" ::"r"(&gdtp) : "memory");
+    asm volatile("lgdt (%0)   \n\t" ::"r"(&gdtp)
+                 : "memory");
 }
 
 void reload_idt()
@@ -63,7 +64,8 @@ void reload_idt()
     // kdebug("gdtvaddr=%#018lx", p.gdt_vaddr);
     // kdebug("gdt size=%d", p.size);
 
-    asm volatile("lidt (%0)   \n\t" ::"r"(&idtp) : "memory");
+    asm volatile("lidt (%0)   \n\t" ::"r"(&idtp)
+                 : "memory");
 }
 
 // 初始化系统各模块
@@ -124,17 +126,18 @@ void system_initialize()
     irq_init();
 
     softirq_init();
+
     current_pcb->cpu_id = 0;
     current_pcb->preempt_count = 0;
     // 先初始化系统调用模块
     syscall_init();
+
     io_mfence();
     //  再初始化进程模块。顺序不能调转
     // sched_init();
     io_mfence();
 
     timer_init();
-
     // 这里必须加内存屏障,否则会出错
     io_mfence();
     smp_init();
@@ -143,7 +146,7 @@ void system_initialize()
     vfs_init();
     devfs_init();
     procfs_init();
-    
+
     cpu_init();
     ps2_keyboard_init();
     tty_init();
@@ -167,11 +170,12 @@ void system_initialize()
     // 启用double buffer
     // scm_enable_double_buffer();  // 因为时序问题, 该函数调用被移到 initial_kernel_thread
     io_mfence();
-    // fat32_init();
+    
     HPET_enable();
 
     io_mfence();
     // 系统初始化到此结束,剩下的初始化功能应当放在初始内核线程中执行
+
     apic_timer_init();
     io_mfence();
 
@@ -180,7 +184,7 @@ void system_initialize()
     //     pause();
 }
 
-//操作系统内核从这里开始执行
+// 操作系统内核从这里开始执行
 void Start_Kernel(void)
 {
 

+ 10 - 12
kernel/src/time/timekeep.rs

@@ -1,6 +1,6 @@
 #![allow(dead_code)]
 
-use crate::driver::timers::rtc::rtc::{rtc_get_cmos_time, rtc_time_t};
+use crate::driver::timers::rtc::rtc::RtcTime;
 
 #[allow(non_camel_case_types)]
 pub type ktime_t = i64;
@@ -15,17 +15,15 @@ fn ktime_to_ns(kt: ktime_t) -> i64 {
 /// 时间戳为从UTC+0 1970-01-01 00:00到当前UTC+0时间,所经过的纳秒数。
 /// 注意,由于当前未引入时区,因此本函数默认时区为UTC+8来计算
 fn ktime_get_real() -> ktime_t {
-    let mut rtc_time: rtc_time_t = rtc_time_t {
-        second: (0),
-        minute: (0),
-        hour: (0),
-        day: (0),
-        month: (0),
-        year: (0),
-    };
-
-    //调用rtc.h里面的函数
-    rtc_get_cmos_time(&mut rtc_time);
+    let mut rtc_time: RtcTime = RtcTime::default();
+
+    {
+        let r = rtc_time.get();
+        // 返回错误码
+        if r.is_err() {
+            return r.unwrap_err() as ktime_t;
+        }
+    }
 
     let mut day_count: i32 = 0;
     for year in 1970..rtc_time.year {