22// SPDX-License-Identifier: Apache-2.0 OR MIT
33// Copyright OXIDOS AUTOMOTIVE 2024.
44
5- use probe_rs:: { Core , MemoryInterface } ;
6-
75use tbf_parser:: parse:: { parse_tbf_footer, parse_tbf_header, parse_tbf_header_lengths} ;
86use tbf_parser:: types:: { TbfFooterV2Credentials , TbfHeader } ;
97use tbf_parser:: { self } ;
10- use tokio_serial:: SerialStream ;
118
12- use crate :: bootloader_serial:: { issue_command, Command , Response } ;
139use 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 ) ?;
0 commit comments