Skip to content

Commit 2b6a62b

Browse files
committed
新增环境变量设置和获取功能,优化命令执行逻辑
1 parent 5f236e5 commit 2b6a62b

File tree

2 files changed

+83
-8
lines changed

2 files changed

+83
-8
lines changed

uboot-shell/examples/env_var.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
use std::{
2+
net::TcpStream,
3+
process::{Child, Command},
4+
time::Duration,
5+
};
6+
7+
use log::info;
8+
use uboot_shell::UbootShell;
9+
10+
fn main() {
11+
env_logger::init();
12+
13+
let (mut out, mut uboot) = new_uboot();
14+
15+
uboot.set_env("fdt_addr", "0x40000000").unwrap();
16+
info!("set fdt_addr ok");
17+
assert_eq!(uboot.env_int("fdt_addr").unwrap(), 0x40000000);
18+
19+
info!("finish");
20+
let _ = out.kill();
21+
let _ = out.wait();
22+
}
23+
24+
fn new_uboot() -> (Child, UbootShell) {
25+
// qemu-system-aarch64 -machine virt -cpu cortex-a57 -nographic -bios assets/u-boot.bin -serial tcp::12345,server
26+
let out = Command::new("qemu-system-aarch64")
27+
.args([
28+
"-machine",
29+
"virt",
30+
"-cpu",
31+
"cortex-a57",
32+
"-nographic",
33+
"-serial",
34+
"tcp::12345,server",
35+
"-bios",
36+
"assets/u-boot.bin",
37+
])
38+
.spawn()
39+
.unwrap();
40+
41+
let tx;
42+
43+
loop {
44+
std::thread::sleep(Duration::from_millis(100));
45+
match TcpStream::connect("127.0.0.1:12345") {
46+
Ok(s) => {
47+
tx = s;
48+
break;
49+
}
50+
Err(e) => {
51+
println!("wait for qemu serial port ready: {e}");
52+
}
53+
}
54+
}
55+
56+
let rx = tx.try_clone().unwrap();
57+
rx.set_read_timeout(Some(Duration::from_millis(300)))
58+
.unwrap();
59+
println!("connect ok");
60+
(out, UbootShell::new(tx, rx).unwrap())
61+
}

uboot-shell/src/lib.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -169,17 +169,24 @@ impl UbootShell {
169169

170170
pub fn cmd_without_reply(&mut self, cmd: &str) -> Result<()> {
171171
self.tx().write_all(cmd.as_bytes())?;
172-
self.tx().write_all("\r\n".as_bytes())?;
172+
self.tx().write_all("\n".as_bytes())?;
173173
self.tx().flush()?;
174-
self.wait_for_reply(cmd)?;
175-
debug!("cmd ok");
174+
// self.wait_for_reply(cmd)?;
175+
// debug!("cmd ok");
176176
Ok(())
177177
}
178178

179179
pub fn cmd(&mut self, cmd: &str) -> Result<String> {
180+
info!("cmd: {cmd}");
180181
self.cmd_without_reply(cmd)?;
181182
let perfix = self.perfix.clone();
182-
self.wait_for_reply(&perfix)
183+
let res = self
184+
.wait_for_reply(&perfix)?
185+
.trim_end()
186+
.trim_end_matches(self.perfix.as_str().trim())
187+
.trim_end()
188+
.to_string();
189+
Ok(res)
183190
}
184191

185192
pub fn set_env(&mut self, name: impl Into<String>, value: impl Into<String>) -> Result<()> {
@@ -190,18 +197,25 @@ impl UbootShell {
190197
pub fn env(&mut self, name: impl Into<String>) -> Result<String> {
191198
let name = name.into();
192199
let s = self.cmd(&format!("echo ${}", name))?;
193-
if s.is_empty() {
194-
return Err(Error::new(
200+
let sp = s
201+
.split("\n")
202+
.filter(|s| !s.trim().is_empty())
203+
.collect::<Vec<_>>();
204+
let s = sp
205+
.last()
206+
.ok_or(Error::new(
195207
ErrorKind::NotFound,
196208
format!("env {} not found", name),
197-
));
198-
}
209+
))?
210+
.to_string();
199211
Ok(s)
200212
}
201213

202214
pub fn env_int(&mut self, name: impl Into<String>) -> Result<usize> {
203215
let name = name.into();
204216
let line = self.env(&name)?;
217+
debug!("env {name} = {line}");
218+
205219
parse_int(&line).ok_or(Error::new(
206220
ErrorKind::InvalidData,
207221
format!("env {name} is not a number"),

0 commit comments

Comments
 (0)