Skip to content

Commit 94e3382

Browse files
addrian-77eva-cosma
authored andcommitted
refactor: read_apps_data
Signed-off-by: Adrian Lungu <lunguadrian30@gmail.com>
1 parent bbccf8e commit 94e3382

3 files changed

Lines changed: 18 additions & 165 deletions

File tree

tockloader-lib/src/attributes/app_attributes.rs

Lines changed: 14 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
33
// Copyright OXIDOS AUTOMOTIVE 2024.
44

5-
use probe_rs::{Core, MemoryInterface};
6-
75
use tbf_parser::parse::{parse_tbf_footer, parse_tbf_header, parse_tbf_header_lengths};
86
use tbf_parser::types::{TbfFooterV2Credentials, TbfHeader};
97
use tbf_parser::{self};
10-
use tokio_serial::SerialStream;
118

12-
use crate::bootloader_serial::{issue_command, Command, Response};
139
use crate::errors::{TockError, TockloaderError};
10+
use crate::IO;
1411

1512
/// This structure contains all relevant information about a tock application.
1613
///
@@ -55,20 +52,19 @@ impl AppAttributes {
5552
}
5653

5754
/// Retrieve all application attributes from the device's memory using a
58-
/// probe-rs connection.
55+
/// generalized connection.
5956
///
6057
/// Applications are layed out in memory sequentially, starting from the
6158
/// `appaddr` address. This function will attempt to read all applications
6259
/// until it fails to parse.
6360
///
6461
/// # Parameters
65-
/// - `board_core`: Core access, obtained from a
66-
/// [ProbeRSConnection](crate::connection::ProbeRSConnection)
62+
/// - `conn` : Either a SerialConnection or a ProbeRSConnection
6763
/// - `addr`: The starting address of the first application in memory.
6864
/// Board-specific. See also
6965
/// [BoardSettings](crate::board_settings::BoardSettings).
70-
pub(crate) fn read_apps_data_probe(
71-
board_core: &mut Core,
66+
pub(crate) async fn read_apps_data(
67+
conn: &mut dyn IO,
7268
addr: u64,
7369
) -> Result<Vec<AppAttributes>, TockloaderError> {
7470
let mut appaddr: u64 = addr;
@@ -78,9 +74,7 @@ impl AppAttributes {
7874
// All applications are stored sequentially in memory, so we read until
7975
// we fail to parse.
8076
loop {
81-
let mut appdata = vec![0u8; 8];
82-
83-
board_core.read(appaddr, &mut appdata)?;
77+
let appdata = conn.read(appaddr, 8).await?;
8478

8579
let tbf_version: u16;
8680
let header_size: u16;
@@ -101,16 +95,14 @@ impl AppAttributes {
10195
header_size = data.1;
10296
total_size = data.2;
10397
}
104-
_ => return Ok(apps_details),
98+
_ => break,
10599
};
106100

107101
log::debug!(
108102
"App #{apps_counter}: TBF version {tbf_version}, header size {header_size}, total size {total_size}",
109103
);
110104

111-
let mut header_data = vec![0u8; header_size as usize];
112-
113-
board_core.read(appaddr, &mut header_data)?;
105+
let header_data = conn.read(appaddr, header_size as usize).await?;
114106
log::debug!("App #{apps_counter}: Header data: {header_data:?}");
115107
let header = parse_tbf_header(&header_data, tbf_version)
116108
.map_err(TockError::InvalidAppTbfHeader)?;
@@ -141,149 +133,12 @@ impl AppAttributes {
141133
// We don't know the size of the current footer, so we read the
142134
// remaining bytes in the application (`footer_offset -
143135
// binary_end_offset`) , even if we overread.
144-
let mut appfooter =
145-
vec![0u8; (total_footers_size - (footer_offset - binary_end_offset)) as usize];
146-
147-
board_core.read(appaddr + footer_offset as u64, &mut appfooter)?;
148-
149-
let footer_info =
150-
parse_tbf_footer(&appfooter).map_err(TockError::InvalidAppTbfHeader)?;
151-
152-
footers.insert(footer_number, TbfFooter::new(footer_info.0, footer_info.1));
153-
154-
footer_number += 1;
155-
// we add 4 because that is the size of TL part of the TLV header (2 bytes type + 2 bytes length)
156-
footer_offset += footer_info.1 + 4;
157-
}
158-
159-
let details: AppAttributes = AppAttributes::new(appaddr, header, footers);
160-
161-
apps_details.insert(apps_counter, details);
162-
apps_counter += 1;
163-
appaddr += total_size as u64;
164-
}
165-
}
166-
167-
/// Retrieve all application attributes from the device's memory using a
168-
/// serial connection.
169-
///
170-
/// Applications are layed out in memory sequentially, starting from the
171-
/// `appaddr` address. This function will attempt to read all applications
172-
/// until it fails to parse.
173-
///
174-
/// # Parameters
175-
/// - `port`: Serial access, obtained from a
176-
/// [SerialConnection](crate::connection::SerialConnection)
177-
/// - `addr`: The starting address of the first application in memory.
178-
/// Board-specific. See also
179-
/// [BoardSettings](crate::board_settings::BoardSettings).
180-
pub(crate) async fn read_apps_data_serial(
181-
port: &mut SerialStream,
182-
addr: u64,
183-
) -> Result<Vec<AppAttributes>, TockloaderError> {
184-
let mut appaddr: u64 = addr;
185-
let mut apps_counter = 0;
186-
let mut apps_details: Vec<AppAttributes> = vec![];
187-
188-
// All applications are stored sequentially in memory, so we read until
189-
// we fail to parse.
190-
loop {
191-
// The tockloader protocol only supports 32-bit architectures,
192-
// though in the future support will be extended to 64-bit.
193-
let mut pkt = (appaddr as u32).to_le_bytes().to_vec();
194-
let length = (8_u16).to_le_bytes().to_vec();
195-
for i in length {
196-
pkt.push(i);
197-
}
198-
199-
// Read the first 8 bytes, which is the length of a TLV header.
200-
let (_, appdata) =
201-
issue_command(port, Command::ReadRange, pkt, true, 8, Response::ReadRange).await?;
202-
203-
let tbf_version: u16;
204-
let header_size: u16;
205-
let total_size: u32;
206-
207-
// The first 8 bytes of the application data contain the TBF header
208-
// lengths and version.
209-
//
210-
// Note on expect: `read` always fills up the entire buffer, which
211-
// was previously declared as 8 bytes.
212-
match parse_tbf_header_lengths(
213-
&appdata[0..8]
214-
.try_into()
215-
.expect("Buffer length must be at least 8 bytes long."),
216-
) {
217-
Ok(data) => {
218-
tbf_version = data.0;
219-
header_size = data.1;
220-
total_size = data.2;
221-
}
222-
_ => break,
223-
};
224-
225-
log::debug!(
226-
"App #{apps_counter}: TBF version {tbf_version}, header size {header_size}, total size {total_size}",
227-
);
228-
229-
let mut pkt = (appaddr as u32).to_le_bytes().to_vec();
230-
let length = (header_size).to_le_bytes().to_vec();
231-
for i in length {
232-
pkt.push(i);
233-
}
234-
235-
// Read the rest of the header
236-
let (_, header_data) = issue_command(
237-
port,
238-
Command::ReadRange,
239-
pkt,
240-
true,
241-
header_size.into(),
242-
Response::ReadRange,
243-
)
244-
.await?;
245-
246-
log::debug!("App #{apps_counter}: Header data: {header_data:?}");
247-
let header = parse_tbf_header(&header_data, tbf_version)
248-
.map_err(TockError::InvalidAppTbfHeader)?;
249-
let binary_end_offset = header.get_binary_end();
250-
251-
match &header {
252-
TbfHeader::TbfHeaderV2(_hd) => {}
253-
_ => {
254-
appaddr += total_size as u64;
255-
continue;
256-
}
257-
};
258-
259-
let mut footers: Vec<TbfFooter> = vec![];
260-
let total_footers_size = total_size - binary_end_offset;
261-
let mut footer_offset = binary_end_offset;
262-
let mut footer_number = 0;
263-
264-
// Try to parse footers until we reach the end of the application.
265-
while footer_offset < total_size {
266-
// We don't know the size of the current footer, so we read the
267-
// remaining bytes in the application (`footer_offset -
268-
// binary_end_offset`) , even if we overread.
269-
let mut pkt = (appaddr as u32 + footer_offset).to_le_bytes().to_vec();
270-
let length = ((total_footers_size - (footer_offset - binary_end_offset)) as u16)
271-
.to_le_bytes()
272-
.to_vec();
273-
for i in length {
274-
pkt.push(i);
275-
}
276-
277-
// Read the next header (and perhaps data beyond it)
278-
let (_, appfooter) = issue_command(
279-
port,
280-
Command::ReadRange,
281-
pkt,
282-
true,
283-
(total_footers_size - (footer_offset - binary_end_offset)) as usize,
284-
Response::ReadRange,
285-
)
286-
.await?;
136+
let appfooter = conn
137+
.read(
138+
appaddr + footer_offset as u64,
139+
(total_footers_size - (footer_offset - binary_end_offset)) as usize,
140+
)
141+
.await?;
287142

288143
let footer_info =
289144
parse_tbf_footer(&appfooter).map_err(TockError::InvalidAppTbfHeader)?;

tockloader-lib/src/command_impl/probers/io.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,7 @@ impl IOCommands for ProbeRSConnection {
4646
return Err(InternalError::ConnectionNotOpen.into());
4747
}
4848
let start_address = self.get_settings().start_address;
49-
let session = self.session.as_mut().expect("Board must be open");
50-
let mut core = session.core(self.target_info.core)?;
51-
52-
AppAttributes::read_apps_data_probe(&mut core, start_address)
49+
AppAttributes::read_apps_data(self, start_address).await
5350
}
5451

5552
async fn read_system_attributes(&mut self) -> Result<SystemAttributes, TockloaderError> {

tockloader-lib/src/command_impl/serial/io.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,13 @@ impl IOCommands for SerialConnection {
6767
if !self.is_open() {
6868
return Err(InternalError::ConnectionNotOpen.into());
6969
}
70-
let start_address = self.get_settings().start_address;
7170
let stream = self.stream.as_mut().expect("Board must be open");
7271

7372
ping_bootloader_and_wait_for_response(stream).await?;
7473

75-
AppAttributes::read_apps_data_serial(stream, start_address).await
74+
let start_address = self.get_settings().start_address;
75+
76+
AppAttributes::read_apps_data(self, start_address).await
7677
}
7778

7879
async fn read_system_attributes(&mut self) -> Result<SystemAttributes, TockloaderError> {

0 commit comments

Comments
 (0)