Skip to content

Commit 6e0fcb9

Browse files
committed
feat: erase_apps
Signed-off-by: addrian-77 <lunguadrian30@gmail.com>
1 parent 65e43ff commit 6e0fcb9

6 files changed

Lines changed: 111 additions & 3 deletions

File tree

tockloader-cli/src/cli.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ fn get_subcommands() -> Vec<Command> {
5353
.args(get_app_args())
5454
.args(get_channel_args())
5555
.arg_required_else_help(false),
56+
Command::new("erase-apps")
57+
.about("Erase apps")
58+
.args(get_app_args())
59+
.args(get_channel_args())
60+
.arg_required_else_help(false),
5661
]
5762
}
5863

tockloader-cli/src/main.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use tockloader_lib::connection::{
1818
use tockloader_lib::known_boards::KnownBoard;
1919
use tockloader_lib::tabs::tab::Tab;
2020
use tockloader_lib::{
21-
list_debug_probes, list_serial_ports, CommandInfo, CommandInstall, CommandList,
21+
list_debug_probes, list_serial_ports, CommandInfo, CommandInstall, CommandList, CommandEraseApps,
2222
};
2323

2424
fn get_serial_target_info(user_options: &ArgMatches) -> SerialTargetInfo {
@@ -228,6 +228,15 @@ async fn main() -> Result<()> {
228228
.await
229229
.context("Failed to install app.")?;
230230
}
231+
Some(("erase-apps", sub_matches)) => {
232+
cli::validate(&mut cmd, sub_matches);
233+
let mut conn = open_connection(sub_matches).await?;
234+
let settings = get_board_settings(sub_matches);
235+
236+
conn.erase_apps(&settings)
237+
.await
238+
.context("Failed to erase apps.")?;
239+
}
231240
_ => {
232241
println!("Could not run the provided subcommand.");
233242
_ = make_cli().print_help();

tockloader-lib/src/command_impl/generalized.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::board_settings::BoardSettings;
66
use crate::connection::TockloaderConnection;
77
use crate::errors::TockloaderError;
88
use crate::tabs::tab::Tab;
9-
use crate::{CommandInfo, CommandInstall, CommandList};
9+
use crate::{CommandInfo, CommandInstall, CommandList, CommandEraseApps};
1010

1111
#[async_trait]
1212
impl CommandList for TockloaderConnection {
@@ -47,3 +47,16 @@ impl CommandInstall for TockloaderConnection {
4747
}
4848
}
4949
}
50+
51+
#[async_trait]
52+
impl CommandEraseApps for TockloaderConnection {
53+
async fn erase_apps(
54+
&mut self,
55+
settings: &BoardSettings,
56+
) -> Result<(), TockloaderError> {
57+
match self {
58+
TockloaderConnection::ProbeRS(conn) => conn.erase_apps(settings).await,
59+
TockloaderConnection::Serial(_conn) => todo!(),
60+
}
61+
}
62+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use async_trait::async_trait;
2+
use probe_rs::flashing::DownloadOptions;
3+
use probe_rs::{MemoryInterface};
4+
use tbf_parser::parse::{parse_tbf_header_lengths};
5+
6+
use crate::board_settings::BoardSettings;
7+
use crate::connection::{Connection, ProbeRSConnection};
8+
use crate::errors::{InternalError, TockloaderError};
9+
use crate::CommandEraseApps;
10+
11+
#[async_trait]
12+
impl CommandEraseApps for ProbeRSConnection {
13+
async fn erase_apps(
14+
&mut self,
15+
settings: &BoardSettings,
16+
) -> Result<(), TockloaderError> {
17+
if !self.is_open() {
18+
return Err(InternalError::ConnectionNotOpen.into());
19+
}
20+
let session = self.session.as_mut().expect("Board must be open");
21+
22+
let mut appaddr: u64 = settings.start_address;
23+
// All applications are stored sequentially in memory, so we read until
24+
// we fail to parse.
25+
let mut total_size: u32 = 0;
26+
loop {
27+
let mut board_core = session.core(self.target_info.core)?;
28+
let mut appdata = vec![0u8; 8];
29+
30+
board_core.read(appaddr, &mut appdata)?;
31+
32+
let app_size: u32;
33+
34+
// The first 8 bytes of the application data contain the TBF header
35+
// lengths and version.
36+
//
37+
// Note on expect: `read` always fills up the entire buffer, which
38+
// was previously declared as 8 bytes.
39+
log::info!("app data? {:?}", appdata);
40+
match parse_tbf_header_lengths(
41+
&appdata
42+
.try_into()
43+
.expect("Buffer length must be at least 8 bytes long."),
44+
) {
45+
Ok(data) => {
46+
app_size = data.2;
47+
}
48+
_ => break,
49+
};
50+
51+
appaddr += app_size as u64;
52+
total_size += app_size;
53+
}
54+
55+
let mut loader = session.target().flash_loader();
56+
57+
let address = settings.start_address;
58+
// (adi): fill the memory with total_size values of 0xFF
59+
let buffer = [0x0].repeat(total_size as usize);
60+
loader.add_data(
61+
(address as u32).into(),
62+
&buffer
63+
)?;
64+
65+
let mut options = DownloadOptions::default();
66+
options.keep_unwritten_bytes = true;
67+
68+
// Finally, the data can be programmed
69+
loader.commit(session, options)?;
70+
Ok(())
71+
}
72+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod erase_apps;
12
pub mod info;
23
pub mod install;
3-
pub mod list;
4+
pub mod list;

tockloader-lib/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,11 @@ pub trait CommandInstall {
5959
tab_file: Tab,
6060
) -> Result<(), TockloaderError>;
6161
}
62+
63+
#[async_trait]
64+
pub trait CommandEraseApps {
65+
async fn erase_apps(
66+
&mut self,
67+
settings: &BoardSettings,
68+
) -> Result<(), TockloaderError>;
69+
}

0 commit comments

Comments
 (0)