@@ -2,10 +2,10 @@ extern crate alloc;
22use crate :: drivers:: { CharDevice , Device , DeviceError , DeviceInner , DeviceType , SharedDeviceOps } ;
33use alloc:: string:: String ;
44use alloc:: sync:: Arc ;
5- use alloc:: vec:: Vec ;
65use pc_keyboard:: {
76 layouts, DecodedKey , HandleControl , KeyCode , KeyState , Keyboard as PcKeyboard , ScancodeSet1 ,
87} ;
8+ use ringbuf:: { traits:: * , HeapRb } ;
99use spin:: Mutex ;
1010
1111// 缓冲区大小(增加到256字节)
@@ -117,7 +117,6 @@ pub struct KeyboardInner {
117117 pc_keyboard : PcKeyboard < layouts:: Us104Key , ScancodeSet1 > ,
118118 enabled : bool ,
119119 nonblocking : bool ,
120- buffer : Vec < char > ,
121120 modifiers : ModifierState ,
122121 leds : LedState ,
123122 mode : KeyboardMode ,
@@ -151,6 +150,8 @@ fn send_keyboard_command(command: u8, data: u8) {
151150
152151pub struct Keyboard {
153152 inner : Mutex < KeyboardInner > ,
153+ producer : Mutex < ringbuf:: wrap:: caching:: Caching < Arc < HeapRb < char > > , true , false > > ,
154+ consumer : Mutex < ringbuf:: wrap:: caching:: Caching < Arc < HeapRb < char > > , false , true > > ,
154155 name : String ,
155156}
156157
@@ -164,7 +165,6 @@ impl KeyboardInner {
164165 ) ,
165166 enabled : true ,
166167 nonblocking : false ,
167- buffer : Vec :: with_capacity ( BUFFER_SIZE ) ,
168168 modifiers : ModifierState :: default ( ) ,
169169 leds : LedState :: default ( ) ,
170170 mode : KeyboardMode :: Unicode ,
@@ -210,26 +210,16 @@ impl KeyboardInner {
210210 _ => { }
211211 }
212212 }
213-
214- /// 添加字符到缓冲区(使用滑动窗口策略)
215- fn push_char ( & mut self , c : char ) {
216- if self . buffer . len ( ) >= BUFFER_SIZE {
217- // 缓冲区满时,丢弃最旧的数据
218- self . buffer . remove ( 0 ) ;
219- }
220- self . buffer . push ( c) ;
221- }
222-
223- /// 清空缓冲区
224- fn clear_buffer ( & mut self ) {
225- self . buffer . clear ( ) ;
226- }
227213}
228214
229215impl Default for Keyboard {
230216 fn default ( ) -> Self {
217+ let rb = HeapRb :: < char > :: new ( BUFFER_SIZE ) ;
218+ let ( prod, cons) = rb. split ( ) ;
231219 Self {
232220 inner : Mutex :: new ( KeyboardInner :: new ( ) ) ,
221+ producer : Mutex :: new ( prod) ,
222+ consumer : Mutex :: new ( cons) ,
233223 name : String :: from ( "keyboard" ) ,
234224 }
235225 }
@@ -260,38 +250,51 @@ impl Keyboard {
260250 x86_64:: instructions:: interrupts:: without_interrupts ( || self . inner . lock ( ) . nonblocking )
261251 }
262252
253+ /// 添加字符到环形缓冲区
254+ fn push_char ( & self , c : char ) {
255+ let mut producer = self . producer . lock ( ) ;
256+ // 缓冲区满时,直接丢弃字符以避免在中断上下文中进行复杂的同步或死锁风险
257+ // 256 字节对于键盘来说通常足够大
258+ let _ = producer. try_push ( c) ;
259+ }
260+
263261 pub fn handle_scancode ( & self , scancode : u8 ) {
264- let mut inner = self . inner . lock ( ) ;
265- if !inner. enabled {
266- return ;
267- }
262+ let mut key_to_push = None ;
263+ {
264+ let mut inner = self . inner . lock ( ) ;
265+ if !inner. enabled {
266+ return ;
267+ }
268268
269- if let Ok ( Some ( key_event) ) = inner. pc_keyboard . add_byte ( scancode) {
270- // 更新修饰键状态
271- inner. update_modifier ( key_event. code , key_event. state ) ;
269+ if let Ok ( Some ( key_event) ) = inner. pc_keyboard . add_byte ( scancode) {
270+ // 更新修饰键状态
271+ inner. update_modifier ( key_event. code , key_event. state ) ;
272272
273- if let Some ( key) = inner. pc_keyboard . process_keyevent ( key_event) {
274- match inner. mode {
275- KeyboardMode :: Unicode => {
276- if let DecodedKey :: Unicode ( character) = key {
277- inner. push_char ( character) ;
273+ if let Some ( key) = inner. pc_keyboard . process_keyevent ( key_event) {
274+ match inner. mode {
275+ KeyboardMode :: Unicode => {
276+ if let DecodedKey :: Unicode ( character) = key {
277+ key_to_push = Some ( character) ;
278+ }
278279 }
279- }
280- KeyboardMode :: Raw => {
281- // 原始模式:将扫描码直接放入缓冲区
282- let raw_char = scancode as char ;
283- inner. push_char ( raw_char) ;
284- }
285- KeyboardMode :: MediumRaw => {
286- // 中等原始模式:处理后的键码
287- if let DecodedKey :: RawKey ( key_code) = key {
288- let code_char = ( key_code as u8 ) as char ;
289- inner. push_char ( code_char) ;
280+ KeyboardMode :: Raw => {
281+ // 原始模式:将扫描码直接放入缓冲区
282+ key_to_push = Some ( scancode as char ) ;
283+ }
284+ KeyboardMode :: MediumRaw => {
285+ // 中等原始模式:处理后的键码
286+ if let DecodedKey :: RawKey ( key_code) = key {
287+ key_to_push = Some ( ( key_code as u8 ) as char ) ;
288+ }
290289 }
291290 }
292291 }
293292 }
294293 }
294+
295+ if let Some ( c) = key_to_push {
296+ self . push_char ( c) ;
297+ }
295298 }
296299
297300 pub fn get_modifier_state ( & self ) -> ModifierState {
@@ -315,7 +318,8 @@ impl Keyboard {
315318
316319 pub fn clear_buffer ( & self ) {
317320 x86_64:: instructions:: interrupts:: without_interrupts ( || {
318- self . inner . lock ( ) . clear_buffer ( ) ;
321+ let mut consumer = self . consumer . lock ( ) ;
322+ while consumer. try_pop ( ) . is_some ( ) { }
319323 } ) ;
320324 }
321325
@@ -405,17 +409,24 @@ impl SharedDeviceOps for Keyboard {
405409impl CharDevice for Keyboard {
406410 fn read ( & self , buf : & mut [ u8 ] ) -> Result < usize , DeviceError > {
407411 x86_64:: instructions:: interrupts:: without_interrupts ( || {
408- let mut inner = self . inner . lock ( ) ;
412+ let nonblocking = self . inner . lock ( ) . nonblocking ;
413+ let mut consumer = self . consumer . lock ( ) ;
409414
410415 // 非阻塞模式检查
411- if inner . nonblocking && inner . buffer . is_empty ( ) {
416+ if nonblocking && consumer . is_empty ( ) {
412417 return Err ( DeviceError :: WouldBlock ) ;
413418 }
414419
415420 let mut read_count = 0 ;
416421
417- while read_count < buf. len ( ) && !inner. buffer . is_empty ( ) {
418- let c = inner. buffer . remove ( 0 ) ;
422+ while read_count < buf. len ( ) && !consumer. is_empty ( ) {
423+ // Peek the front character
424+ let ( s1, s2) : ( & [ char ] , & [ char ] ) = consumer. as_slices ( ) ;
425+ let c = if let Some ( & c) = s1. first ( ) . or_else ( || s2. first ( ) ) {
426+ c
427+ } else {
428+ break ;
429+ } ;
419430
420431 let mut char_buf = [ 0u8 ; 4 ] ;
421432 let char_str = c. encode_utf8 ( & mut char_buf) ;
@@ -424,9 +435,10 @@ impl CharDevice for Keyboard {
424435 if read_count + bytes. len ( ) <= buf. len ( ) {
425436 buf[ read_count..read_count + bytes. len ( ) ] . copy_from_slice ( bytes) ;
426437 read_count += bytes. len ( ) ;
438+ // Successfully read, pop it
439+ consumer. try_pop ( ) ;
427440 } else {
428- // 缓冲区空间不足,将字符重新放回
429- inner. buffer . insert ( 0 , c) ;
441+ // 缓冲区空间不足
430442 break ;
431443 }
432444 }
@@ -445,16 +457,17 @@ impl CharDevice for Keyboard {
445457
446458 fn peek ( & self , buf : & mut [ u8 ] ) -> Result < usize , DeviceError > {
447459 x86_64:: instructions:: interrupts:: without_interrupts ( || {
448- let inner = self . inner . lock ( ) ;
460+ let consumer = self . consumer . lock ( ) ;
449461
450- if inner . buffer . is_empty ( ) {
462+ if consumer . is_empty ( ) {
451463 return Err ( DeviceError :: WouldBlock ) ;
452464 }
453465
454466 let mut read_count = 0 ;
455- let buffer_copy = inner. buffer . clone ( ) ;
456467
457- for c in buffer_copy. iter ( ) . take ( buf. len ( ) ) {
468+ // 使用 as_slices 遍历环形缓冲区
469+ let ( s1, s2) : ( & [ char ] , & [ char ] ) = consumer. as_slices ( ) ;
470+ for & c in s1. iter ( ) . chain ( s2. iter ( ) ) {
458471 let mut char_buf = [ 0u8 ; 4 ] ;
459472 let char_str = c. encode_utf8 ( & mut char_buf) ;
460473 let bytes = char_str. as_bytes ( ) ;
@@ -472,10 +485,7 @@ impl CharDevice for Keyboard {
472485 }
473486
474487 fn has_data ( & self ) -> bool {
475- x86_64:: instructions:: interrupts:: without_interrupts ( || {
476- let inner = self . inner . lock ( ) ;
477- !inner. buffer . is_empty ( )
478- } )
488+ x86_64:: instructions:: interrupts:: without_interrupts ( || !self . consumer . lock ( ) . is_empty ( ) )
479489 }
480490
481491 fn set_nonblocking ( & self , nonblocking : bool ) -> Result < ( ) , DeviceError > {
0 commit comments