xref: /DragonOS/kernel/src/driver/video/fbdev/vesafb.rs (revision 45626c859f95054b76d8b59afcbd24c6b235026f)
1 use core::{
2     ffi::{c_uint, c_void},
3     mem::MaybeUninit,
4     sync::atomic::AtomicBool,
5 };
6 
7 use alloc::{
8     string::{String, ToString},
9     sync::{Arc, Weak},
10     vec::Vec,
11 };
12 use system_error::SystemError;
13 use unified_init::macros::unified_init;
14 
15 use crate::{
16     arch::MMArch,
17     driver::{
18         base::{
19             class::Class,
20             device::{
21                 bus::Bus, device_manager, driver::Driver, Device, DeviceState, DeviceType, IdTable,
22             },
23             kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
24             kset::KSet,
25             platform::{
26                 platform_device::{platform_device_manager, PlatformDevice},
27                 platform_driver::{platform_driver_manager, PlatformDriver},
28                 CompatibleTable,
29             },
30         },
31         tty::serial::serial8250::send_to_default_serial8250_port,
32         video::fbdev::base::{fbmem::frame_buffer_manager, FbVisual},
33     },
34     filesystem::{
35         kernfs::KernFSInode,
36         sysfs::{file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport},
37         vfs::syscall::ModeType,
38     },
39     include::bindings::bindings::{
40         multiboot2_get_Framebuffer_info, multiboot2_iter, multiboot_tag_framebuffer_info_t,
41     },
42     init::{boot_params, initcall::INITCALL_DEVICE},
43     libs::{
44         align::page_align_up,
45         once::Once,
46         rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
47         spinlock::SpinLock,
48     },
49     mm::{
50         allocator::page_frame::PageFrameCount, no_init::pseudo_map_phys, MemoryManagementArch,
51         PhysAddr, VirtAddr,
52     },
53 };
54 
55 use super::base::{
56     fbmem::FbDevice, BlankMode, BootTimeVideoType, FbAccel, FbActivateFlags, FbId, FbState, FbType,
57     FbVModeFlags, FbVarScreenInfo, FbVideoMode, FixedScreenInfo, FrameBuffer, FrameBufferInfo,
58     FrameBufferOps,
59 };
60 
61 /// 当前机器上面是否有vesa帧缓冲区
62 static HAS_VESA_FB: AtomicBool = AtomicBool::new(false);
63 
64 lazy_static! {
65     static ref VESAFB_FIX_INFO: RwLock<FixedScreenInfo> = RwLock::new(FixedScreenInfo {
66         id: FixedScreenInfo::name2id("VESA VGA"),
67         fb_type: FbType::PackedPixels,
68         accel: FbAccel::None,
69         ..Default::default()
70     });
71     static ref VESAFB_DEFINED: RwLock<FbVarScreenInfo> = RwLock::new(FbVarScreenInfo {
72         activate: FbActivateFlags::FB_ACTIVATE_NOW,
73         height: None,
74         width: None,
75         right_margin: 32,
76         upper_margin: 16,
77         lower_margin: 4,
78         vsync_len: 4,
79         vmode: FbVModeFlags::FB_VMODE_NONINTERLACED,
80 
81         ..Default::default()
82     });
83 }
84 
85 #[derive(Debug)]
86 #[cast_to([sync] Device)]
87 #[cast_to([sync] PlatformDevice)]
88 pub struct VesaFb {
89     inner: SpinLock<InnerVesaFb>,
90     kobj_state: LockedKObjectState,
91 }
92 
93 impl VesaFb {
94     pub const NAME: &'static str = "vesa_vga";
95     pub fn new() -> Self {
96         return Self {
97             inner: SpinLock::new(InnerVesaFb {
98                 bus: None,
99                 class: None,
100                 driver: None,
101                 kern_inode: None,
102                 parent: None,
103                 kset: None,
104                 kobj_type: None,
105                 device_state: DeviceState::NotInitialized,
106                 pdev_id: 0,
107                 pdev_id_auto: false,
108                 fb_id: FbId::INIT,
109                 fb_device: None,
110                 fb_state: FbState::Suspended,
111             }),
112             kobj_state: LockedKObjectState::new(None),
113         };
114     }
115 }
116 
117 #[derive(Debug)]
118 struct InnerVesaFb {
119     bus: Option<Weak<dyn Bus>>,
120     class: Option<Arc<dyn Class>>,
121     driver: Option<Weak<dyn Driver>>,
122     kern_inode: Option<Arc<KernFSInode>>,
123     parent: Option<Weak<dyn KObject>>,
124     kset: Option<Arc<KSet>>,
125     kobj_type: Option<&'static dyn KObjType>,
126     device_state: DeviceState,
127     pdev_id: i32,
128     pdev_id_auto: bool,
129     fb_id: FbId,
130     fb_device: Option<Arc<FbDevice>>,
131     fb_state: FbState,
132 }
133 
134 impl FrameBuffer for VesaFb {
135     fn fb_id(&self) -> FbId {
136         self.inner.lock().fb_id
137     }
138 
139     fn set_fb_id(&self, id: FbId) {
140         self.inner.lock().fb_id = id;
141     }
142 }
143 
144 impl PlatformDevice for VesaFb {
145     fn pdev_name(&self) -> &str {
146         Self::NAME
147     }
148 
149     fn set_pdev_id(&self, id: i32) {
150         self.inner.lock().pdev_id = id;
151     }
152 
153     fn set_pdev_id_auto(&self, id_auto: bool) {
154         self.inner.lock().pdev_id_auto = id_auto;
155     }
156 
157     fn compatible_table(&self) -> CompatibleTable {
158         todo!()
159     }
160 
161     fn is_initialized(&self) -> bool {
162         self.inner.lock().device_state == DeviceState::Initialized
163     }
164 
165     fn set_state(&self, set_state: DeviceState) {
166         self.inner.lock().device_state = set_state;
167     }
168 }
169 
170 impl Device for VesaFb {
171     fn dev_type(&self) -> DeviceType {
172         DeviceType::Char
173     }
174 
175     fn id_table(&self) -> IdTable {
176         IdTable::new(self.name(), None)
177     }
178 
179     fn bus(&self) -> Option<Weak<dyn Bus>> {
180         self.inner.lock().bus.clone()
181     }
182 
183     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
184         self.inner.lock().bus = bus;
185     }
186 
187     fn set_class(&self, class: Option<Arc<dyn Class>>) {
188         self.inner.lock().class = class;
189     }
190 
191     fn driver(&self) -> Option<Arc<dyn Driver>> {
192         self.inner.lock().driver.clone()?.upgrade()
193     }
194 
195     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
196         self.inner.lock().driver = driver;
197     }
198 
199     fn is_dead(&self) -> bool {
200         false
201     }
202 
203     fn can_match(&self) -> bool {
204         true
205     }
206 
207     fn set_can_match(&self, _can_match: bool) {}
208 
209     fn state_synced(&self) -> bool {
210         true
211     }
212 }
213 
214 impl KObject for VesaFb {
215     fn as_any_ref(&self) -> &dyn core::any::Any {
216         self
217     }
218 
219     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
220         self.inner.lock().kern_inode = inode;
221     }
222 
223     fn inode(&self) -> Option<Arc<KernFSInode>> {
224         self.inner.lock().kern_inode.clone()
225     }
226 
227     fn parent(&self) -> Option<Weak<dyn KObject>> {
228         self.inner.lock().parent.clone()
229     }
230 
231     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
232         self.inner.lock().parent = parent;
233     }
234 
235     fn kset(&self) -> Option<Arc<KSet>> {
236         self.inner.lock().kset.clone()
237     }
238 
239     fn set_kset(&self, kset: Option<Arc<KSet>>) {
240         self.inner.lock().kset = kset;
241     }
242 
243     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
244         self.inner.lock().kobj_type
245     }
246 
247     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
248         self.inner.lock().kobj_type = ktype;
249     }
250 
251     fn name(&self) -> String {
252         Self::NAME.to_string()
253     }
254 
255     fn set_name(&self, _name: String) {
256         // do nothing
257     }
258 
259     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
260         self.kobj_state.read()
261     }
262 
263     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
264         self.kobj_state.write()
265     }
266 
267     fn set_kobj_state(&self, state: KObjectState) {
268         *self.kobj_state.write() = state;
269     }
270 }
271 
272 impl FrameBufferOps for VesaFb {
273     fn fb_open(&self, _user: bool) {
274         todo!()
275     }
276 
277     fn fb_release(&self, _user: bool) {
278         todo!()
279     }
280 
281     fn fb_set_color_register(
282         &self,
283         _regno: u16,
284         _red: u16,
285         _green: u16,
286         _blue: u16,
287     ) -> Result<(), SystemError> {
288         todo!()
289     }
290 
291     fn fb_blank(&self, _blank_mode: BlankMode) -> Result<(), SystemError> {
292         todo!()
293     }
294 
295     fn fb_destroy(&self) {
296         todo!()
297     }
298 
299     fn fb_read(&self, buf: &mut [u8], pos: usize) -> Result<usize, SystemError> {
300         let bp = boot_params().read();
301 
302         let vaddr = bp.screen_info.lfb_virt_base.ok_or(SystemError::ENODEV)?;
303         let size = self.current_fb_fix().smem_len;
304         drop(bp);
305         if pos >= size {
306             return Ok(0);
307         }
308 
309         let pos = pos as i64;
310         let size = size as i64;
311 
312         let len = core::cmp::min(size - pos, buf.len() as i64) as usize;
313 
314         let slice = unsafe { core::slice::from_raw_parts(vaddr.as_ptr::<u8>(), size as usize) };
315         buf[..len].copy_from_slice(&slice[pos as usize..(pos as usize + len)]);
316 
317         return Ok(len);
318     }
319 
320     fn fb_write(&self, buf: &[u8], pos: usize) -> Result<usize, SystemError> {
321         let bp = boot_params().read();
322 
323         let vaddr = bp.screen_info.lfb_virt_base.ok_or(SystemError::ENODEV)?;
324         let size = self.current_fb_fix().smem_len;
325 
326         if pos >= size {
327             return Ok(0);
328         }
329 
330         let pos = pos as i64;
331         let size = size as i64;
332 
333         let len = core::cmp::min(size - pos, buf.len() as i64) as usize;
334 
335         let slice = unsafe { core::slice::from_raw_parts_mut(vaddr.as_ptr::<u8>(), size as usize) };
336         slice[pos as usize..(pos as usize + len)].copy_from_slice(&buf[..len]);
337 
338         return Ok(len);
339     }
340 }
341 
342 impl FrameBufferInfo for VesaFb {
343     fn fb_device(&self) -> Option<Arc<FbDevice>> {
344         self.inner.lock().fb_device.clone()
345     }
346 
347     fn set_fb_device(&self, device: Option<Arc<FbDevice>>) {
348         self.inner.lock().fb_device = device;
349     }
350 
351     fn screen_size(&self) -> usize {
352         todo!()
353     }
354 
355     fn current_fb_var(&self) -> FbVarScreenInfo {
356         VESAFB_DEFINED.read().clone()
357     }
358 
359     fn current_fb_fix(&self) -> FixedScreenInfo {
360         VESAFB_FIX_INFO.read().clone()
361     }
362 
363     fn video_mode(&self) -> Option<&FbVideoMode> {
364         todo!()
365     }
366 
367     fn state(&self) -> FbState {
368         self.inner.lock().fb_state
369     }
370 }
371 
372 #[derive(Debug)]
373 #[cast_to([sync] PlatformDriver)]
374 struct VesaFbDriver {
375     inner: SpinLock<InnerVesaFbDriver>,
376     kobj_state: LockedKObjectState,
377 }
378 
379 impl VesaFbDriver {
380     pub fn new() -> Arc<Self> {
381         let r = Arc::new(Self {
382             inner: SpinLock::new(InnerVesaFbDriver {
383                 ktype: None,
384                 kset: None,
385                 parent: None,
386                 kernfs_inode: None,
387                 devices: Vec::new(),
388                 bus: None,
389                 self_ref: Weak::new(),
390             }),
391             kobj_state: LockedKObjectState::new(None),
392         });
393 
394         r.inner.lock().self_ref = Arc::downgrade(&r);
395 
396         return r;
397     }
398 }
399 
400 #[derive(Debug)]
401 struct InnerVesaFbDriver {
402     ktype: Option<&'static dyn KObjType>,
403     kset: Option<Arc<KSet>>,
404     parent: Option<Weak<dyn KObject>>,
405     kernfs_inode: Option<Arc<KernFSInode>>,
406     devices: Vec<Arc<dyn Device>>,
407     bus: Option<Weak<dyn Bus>>,
408 
409     self_ref: Weak<VesaFbDriver>,
410 }
411 
412 impl VesaFbDriver {
413     const NAME: &'static str = "vesa-framebuffer";
414 }
415 
416 impl PlatformDriver for VesaFbDriver {
417     fn probe(&self, device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
418         let device = device
419             .clone()
420             .arc_any()
421             .downcast::<VesaFb>()
422             .map_err(|_| SystemError::EINVAL)?;
423 
424         device.set_driver(Some(self.inner.lock_irqsave().self_ref.clone()));
425 
426         return Ok(());
427     }
428 
429     fn remove(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
430         todo!()
431     }
432 
433     fn shutdown(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
434         // do nothing
435         return Ok(());
436     }
437 
438     fn suspend(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
439         // do nothing
440         return Ok(());
441     }
442 
443     fn resume(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
444         todo!()
445     }
446 }
447 
448 impl Driver for VesaFbDriver {
449     fn id_table(&self) -> Option<IdTable> {
450         Some(IdTable::new(VesaFb::NAME.to_string(), None))
451     }
452 
453     fn devices(&self) -> Vec<Arc<dyn Device>> {
454         self.inner.lock().devices.clone()
455     }
456 
457     fn add_device(&self, device: Arc<dyn Device>) {
458         let mut guard = self.inner.lock();
459         // check if the device is already in the list
460         if guard.devices.iter().any(|dev| Arc::ptr_eq(dev, &device)) {
461             return;
462         }
463 
464         guard.devices.push(device);
465     }
466 
467     fn delete_device(&self, device: &Arc<dyn Device>) {
468         let mut guard = self.inner.lock();
469         guard.devices.retain(|dev| !Arc::ptr_eq(dev, device));
470     }
471 
472     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
473         self.inner.lock().bus = bus;
474     }
475 
476     fn bus(&self) -> Option<Weak<dyn Bus>> {
477         self.inner.lock().bus.clone()
478     }
479 
480     fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
481         return &[&VesaFbAnonAttributeGroup];
482     }
483 }
484 
485 impl KObject for VesaFbDriver {
486     fn as_any_ref(&self) -> &dyn core::any::Any {
487         self
488     }
489 
490     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
491         self.inner.lock().kernfs_inode = inode;
492     }
493 
494     fn inode(&self) -> Option<Arc<KernFSInode>> {
495         self.inner.lock().kernfs_inode.clone()
496     }
497 
498     fn parent(&self) -> Option<Weak<dyn KObject>> {
499         self.inner.lock().parent.clone()
500     }
501 
502     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
503         self.inner.lock().parent = parent;
504     }
505 
506     fn kset(&self) -> Option<Arc<KSet>> {
507         self.inner.lock().kset.clone()
508     }
509 
510     fn set_kset(&self, kset: Option<Arc<KSet>>) {
511         self.inner.lock().kset = kset;
512     }
513 
514     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
515         self.inner.lock().ktype
516     }
517 
518     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
519         self.inner.lock().ktype = ktype;
520     }
521 
522     fn name(&self) -> String {
523         Self::NAME.to_string()
524     }
525 
526     fn set_name(&self, _name: String) {
527         // do nothing
528     }
529 
530     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
531         self.kobj_state.read()
532     }
533 
534     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
535         self.kobj_state.write()
536     }
537 
538     fn set_kobj_state(&self, state: KObjectState) {
539         *self.kobj_state.write() = state;
540     }
541 }
542 
543 #[derive(Debug)]
544 struct VesaFbAnonAttributeGroup;
545 
546 impl AttributeGroup for VesaFbAnonAttributeGroup {
547     fn name(&self) -> Option<&str> {
548         None
549     }
550 
551     fn attrs(&self) -> &[&'static dyn Attribute] {
552         &[&AnonAttrPhysAddr as &'static dyn Attribute]
553     }
554 
555     fn is_visible(
556         &self,
557         _kobj: Arc<dyn KObject>,
558         attr: &'static dyn Attribute,
559     ) -> Option<ModeType> {
560         Some(attr.mode())
561     }
562 }
563 
564 #[derive(Debug)]
565 struct AnonAttrPhysAddr;
566 
567 impl Attribute for AnonAttrPhysAddr {
568     fn name(&self) -> &str {
569         "smem_start"
570     }
571 
572     fn mode(&self) -> ModeType {
573         ModeType::S_IRUGO
574     }
575 
576     fn support(&self) -> SysFSOpsSupport {
577         SysFSOpsSupport::SHOW
578     }
579 
580     fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
581         sysfs_emit_str(
582             buf,
583             format!(
584                 "0x{:x}\n",
585                 VESAFB_FIX_INFO
586                     .read()
587                     .smem_start
588                     .unwrap_or(PhysAddr::new(0))
589                     .data()
590             )
591             .as_str(),
592         )
593     }
594 }
595 
596 #[unified_init(INITCALL_DEVICE)]
597 pub fn vesa_fb_driver_init() -> Result<(), SystemError> {
598     let driver = VesaFbDriver::new();
599 
600     platform_driver_manager().register(driver)?;
601 
602     return Ok(());
603 }
604 
605 /// 在内存管理初始化之前,初始化vesafb
606 pub fn vesafb_early_init() -> Result<VirtAddr, SystemError> {
607     let mut _reserved: u32 = 0;
608 
609     let mut fb_info: MaybeUninit<multiboot_tag_framebuffer_info_t> = MaybeUninit::uninit();
610     //从multiboot2中读取帧缓冲区信息至fb_info
611 
612     // todo: 换成rust的,并且检测是否成功获取
613     unsafe {
614         multiboot2_iter(
615             Some(multiboot2_get_Framebuffer_info),
616             fb_info.as_mut_ptr() as usize as *mut c_void,
617             &mut _reserved as *mut c_uint,
618         )
619     };
620     unsafe { fb_info.assume_init() };
621     let fb_info: multiboot_tag_framebuffer_info_t = unsafe { core::mem::transmute(fb_info) };
622 
623     // todo: 判断是否有vesa帧缓冲区,这里暂时直接设置true
624     HAS_VESA_FB.store(true, core::sync::atomic::Ordering::SeqCst);
625 
626     let width = fb_info.framebuffer_width;
627     let height = fb_info.framebuffer_height;
628 
629     let mut boot_params_guard = boot_params().write();
630     let boottime_screen_info = &mut boot_params_guard.screen_info;
631 
632     boottime_screen_info.is_vga = true;
633 
634     boottime_screen_info.lfb_base = PhysAddr::new(fb_info.framebuffer_addr as usize);
635 
636     if fb_info.framebuffer_type == 2 {
637         //当type=2时,width与height用字符数表示,故depth=8
638         boottime_screen_info.origin_video_cols = width as u8;
639         boottime_screen_info.origin_video_lines = height as u8;
640         boottime_screen_info.video_type = BootTimeVideoType::Mda;
641         boottime_screen_info.lfb_depth = 8;
642     } else {
643         //否则为图像模式,depth应参照帧缓冲区信息里面的每个像素的位数
644         boottime_screen_info.lfb_width = width;
645         boottime_screen_info.lfb_height = height;
646         boottime_screen_info.video_type = BootTimeVideoType::Vlfb;
647         boottime_screen_info.lfb_depth = fb_info.framebuffer_bpp as u8;
648     }
649 
650     boottime_screen_info.lfb_size =
651         (width * height * ((fb_info.framebuffer_bpp as u32 + 7) / 8)) as usize;
652 
653     let buf_vaddr = VirtAddr::new(0xffff800003200000);
654     boottime_screen_info.lfb_virt_base = Some(buf_vaddr);
655 
656     let init_text = "Video driver to map.\n\0";
657     send_to_default_serial8250_port(init_text.as_bytes());
658 
659     // 地址映射
660     let paddr = PhysAddr::new(fb_info.framebuffer_addr as usize);
661     let count =
662         PageFrameCount::new(page_align_up(boottime_screen_info.lfb_size) / MMArch::PAGE_SIZE);
663     unsafe { pseudo_map_phys(buf_vaddr, paddr, count) };
664     return Ok(buf_vaddr);
665 }
666 
667 #[unified_init(INITCALL_DEVICE)]
668 fn vesa_fb_device_init() -> Result<(), SystemError> {
669     // 如果没有vesa帧缓冲区,直接返回
670     if !HAS_VESA_FB.load(core::sync::atomic::Ordering::SeqCst) {
671         return Ok(());
672     }
673 
674     static INIT: Once = Once::new();
675     INIT.call_once(|| {
676         kinfo!("vesa fb device init");
677 
678         let mut fix_info_guard = VESAFB_FIX_INFO.write_irqsave();
679         let mut var_info_guard = VESAFB_DEFINED.write_irqsave();
680 
681         let boot_params_guard = boot_params().read();
682         let boottime_screen_info = &boot_params_guard.screen_info;
683 
684         fix_info_guard.smem_start = Some(boottime_screen_info.lfb_base);
685         fix_info_guard.smem_len = boottime_screen_info.lfb_size;
686 
687         if boottime_screen_info.video_type == BootTimeVideoType::Mda {
688             fix_info_guard.visual = FbVisual::Mono10;
689             var_info_guard.bits_per_pixel = 8;
690             fix_info_guard.line_length = (boottime_screen_info.origin_video_cols as u32)
691                 * (var_info_guard.bits_per_pixel / 8);
692             var_info_guard.xres_virtual = boottime_screen_info.origin_video_cols as u32;
693             var_info_guard.yres_virtual = boottime_screen_info.origin_video_lines as u32;
694         } else {
695             fix_info_guard.visual = FbVisual::TrueColor;
696             var_info_guard.bits_per_pixel = boottime_screen_info.lfb_depth as u32;
697             fix_info_guard.line_length =
698                 (boottime_screen_info.lfb_width as u32) * (var_info_guard.bits_per_pixel / 8);
699             var_info_guard.xres_virtual = boottime_screen_info.lfb_width as u32;
700             var_info_guard.yres_virtual = boottime_screen_info.lfb_height as u32;
701         }
702 
703         drop(var_info_guard);
704         drop(fix_info_guard);
705 
706         let device = Arc::new(VesaFb::new());
707         device_manager().device_default_initialize(&(device.clone() as Arc<dyn Device>));
708 
709         platform_device_manager()
710             .device_add(device.clone() as Arc<dyn PlatformDevice>)
711             .expect("vesa_fb_device_init: platform_device_manager().device_add failed");
712 
713         frame_buffer_manager()
714             .register_fb(device.clone() as Arc<dyn FrameBuffer>)
715             .expect("vesa_fb_device_init: frame_buffer_manager().register_fb failed");
716 
717         // 设置vesa fb的状态为运行中
718         device.inner.lock().fb_state = FbState::Running;
719     });
720 
721     return Ok(());
722 }
723