From 9ae3349a40487ecc277d474c2281a8f16a4e940f Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Wed, 23 Apr 2025 20:55:15 +0800 Subject: [PATCH 1/2] chromium_ec: Fix reading EC console Now it can get all of the EC console buffer. I see ~100 lines. Much more than the previous ~10 lines. Follow also seems to properly work now. A good way to force messages to appear on the console is to plug in or unplug a charger, or to close and open the lid. TEST=`framework_tool --console recent` shows the same output as `ectool console` TEST=`framework_tool --console follow` keeps properly refreshing endlessly. Signed-off-by: Daniel Schaefer --- framework_lib/src/chromium_ec/mod.rs | 63 ++++++++++++++++++---------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index acbd5c0c..687e6893 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -822,22 +822,23 @@ impl CrosEc { /// Requests recent console output from EC and constantly asks for more /// Prints the output and returns it when an error is encountered - pub fn console_read(&self) -> EcResult { - let mut console = String::new(); + pub fn console_read(&self) -> EcResult<()> { + EcRequestConsoleSnapshot {}.send_command(self)?; + let mut cmd = EcRequestConsoleRead { - subcmd: ConsoleReadSubCommand::ConsoleReadRecent as u8, + subcmd: ConsoleReadSubCommand::ConsoleReadNext as u8, }; - - EcRequestConsoleSnapshot {}.send_command(self)?; loop { match cmd.send_command_vec(self) { Ok(data) => { - // EC Buffer is empty. We can wait a bit and see if there's more - // Can't run it too quickly, otherwise the commands might fail + // EC Buffer is empty. That means we've read everything from the snapshot if data.is_empty() { - trace!("Empty EC response"); - println!("---"); - os_specific::sleep(1_000_000); // 1s + debug!("Empty EC response. Stopping console read"); + // Don't read too fast, wait a second before reading more + os_specific::sleep(1_000_000); + EcRequestConsoleSnapshot {}.send_command(self)?; + cmd.subcmd = ConsoleReadSubCommand::ConsoleReadRecent as u8; + continue; } let utf8 = std::str::from_utf8(&data).unwrap(); @@ -846,35 +847,51 @@ impl CrosEc { .replace(['\0'], ""); print!("{}", ascii); - console.push_str(ascii.as_str()); } Err(err) => { error!("Err: {:?}", err); - return Ok(console); - //return Err(err) + return Err(err); } }; - cmd.subcmd = ConsoleReadSubCommand::ConsoleReadNext as u8; // Need to explicitly handle CTRL-C termination on UEFI Shell #[cfg(feature = "uefi")] if shell_get_execution_break_flag() { - return Ok(console); + return Ok(()); } } } + /// Read all of EC console buffer and return it pub fn console_read_one(&self) -> EcResult { EcRequestConsoleSnapshot {}.send_command(self)?; - let data = EcRequestConsoleRead { - subcmd: ConsoleReadSubCommand::ConsoleReadRecent as u8, + + let mut console = String::new(); + let cmd = EcRequestConsoleRead { + subcmd: ConsoleReadSubCommand::ConsoleReadNext as u8, + }; + loop { + match cmd.send_command_vec(self) { + Ok(data) => { + // EC Buffer is empty. That means we've read everything + if data.is_empty() { + debug!("Empty EC response. Stopping console read"); + return Ok(console); + } + + let utf8 = std::str::from_utf8(&data).unwrap(); + let ascii = utf8 + .replace(|c: char| !c.is_ascii(), "") + .replace(['\0'], ""); + + console.push_str(ascii.as_str()); + } + Err(err) => { + error!("Err: {:?}", err); + return Err(err); + } + }; } - .send_command_vec(self)?; - let utf8 = std::str::from_utf8(&data).unwrap(); - let ascii = utf8 - .replace(|c: char| !c.is_ascii(), "") - .replace(['\0'], ""); - Ok(ascii) } /// Check features supported by the firmware From fd7d49fe696e2bd0d209d38c5db971a79e4e12d3 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Thu, 24 Apr 2025 10:31:35 +0800 Subject: [PATCH 2/2] console: Handle all NULL response from driver BUG=`framework_tool --console recent` would hang and never return because it's stuck in the loop TEST=Make sure `framework_tool --console recent` can run properly on windows and return >50 lines of log Signed-off-by: Daniel Schaefer --- framework_lib/src/chromium_ec/mod.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index 687e6893..d3f08658 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -820,7 +820,7 @@ impl CrosEc { Ok(result.valid) } - /// Requests recent console output from EC and constantly asks for more + /// Requests console output from EC and constantly asks for more /// Prints the output and returns it when an error is encountered pub fn console_read(&self) -> EcResult<()> { EcRequestConsoleSnapshot {}.send_command(self)?; @@ -832,7 +832,8 @@ impl CrosEc { match cmd.send_command_vec(self) { Ok(data) => { // EC Buffer is empty. That means we've read everything from the snapshot - if data.is_empty() { + // The windows crosecbus driver returns all NULL instead of empty response + if data.is_empty() || data.iter().all(|x| *x == 0) { debug!("Empty EC response. Stopping console read"); // Don't read too fast, wait a second before reading more os_specific::sleep(1_000_000); @@ -874,7 +875,8 @@ impl CrosEc { match cmd.send_command_vec(self) { Ok(data) => { // EC Buffer is empty. That means we've read everything - if data.is_empty() { + // The windows crosecbus driver returns all NULL instead of empty response + if data.is_empty() || data.iter().all(|x| *x == 0) { debug!("Empty EC response. Stopping console read"); return Ok(console); }