Skip to content

Commit bbccf8e

Browse files
addrian-77eva-cosma
authored andcommitted
refactor: read system attributes
Signed-off-by: Adrian Lungu <lunguadrian30@gmail.com>
1 parent 6d0302c commit bbccf8e

3 files changed

Lines changed: 13 additions & 162 deletions

File tree

tockloader-lib/src/attributes/system_attributes.rs

Lines changed: 11 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
// Copyright OXIDOS AUTOMOTIVE 2024.
44

55
use byteorder::{ByteOrder, LittleEndian};
6-
use probe_rs::{Core, MemoryInterface};
7-
use tokio_serial::SerialStream;
86

9-
use crate::bootloader_serial::{issue_command, Command, Response};
107
use crate::errors::{AttributeParseError, TockError, TockloaderError};
8+
use crate::IO;
119

1210
use super::decode::{bytes_to_string, decode_attribute};
1311

@@ -50,29 +48,27 @@ impl SystemAttributes {
5048
}
5149
}
5250

53-
/// Read system attributes using a probe-rs connection. A bootloader must be
51+
/// Read system attributes using a generalized connection. A bootloader must be
5452
/// present on this board for this function to work properly.
5553
///
5654
/// # Parameters
57-
/// - `board_core` : Core access, obtained from a
58-
/// [ProbeRSConnection](crate::connection::ProbeRSConnection)
55+
/// - `conn` : Either a SerialConnection or a ProbeRSConnection
5956
///
6057
/// # Returns
6158
/// - Ok(result): if attributes were read successfully
6259
/// - Err(TockloaderError::MisconfiguredBoard): if no start address is found or valid
6360
/// - Err(TockloaderError::MisconfiguredBoard): if attributes don't follow the UTF-8 format
64-
/// - Err(TockloaderError::ProbeRsReadError): if reading fails
65-
pub(crate) fn read_system_attributes_probe(
66-
board_core: &mut Core,
67-
) -> Result<Self, TockloaderError> {
61+
/// - Err(TockloaderError::ProbeRsReadError): if reading fails on ProbeRS
62+
/// - Err(TockloaderError::SerialReadError): if reading fails on Serial
63+
pub(crate) async fn read_system_attributes(
64+
conn: &mut dyn IO,
65+
) -> Result<SystemAttributes, TockloaderError> {
6866
let mut result = SystemAttributes::new();
6967
// System attributes start at 0x600 and up to 0x9FF. See:
7068
// https://book.tockos.org/doc/memory_layout#flash-1
7169
let address = 0x600;
72-
// Each attribute is 64 bytes exactly, and there are 16 slots
73-
let mut buf = [0u8; 64 * 16];
7470

75-
board_core.read(address, &mut buf)?;
71+
let buf = conn.read(address, 64 * 16).await?;
7672

7773
let mut data = buf.chunks(64);
7874

@@ -125,9 +121,8 @@ impl SystemAttributes {
125121
// TODO(george-cosma): separate kernel attributes from kernel flags.
126122

127123
let address = 0x40E;
128-
let mut buf = [0u8; 8];
129124

130-
board_core.read_8(address, &mut buf)?;
125+
let buf = conn.read(address, 8).await?;
131126

132127
let string = String::from_utf8(buf.to_vec())
133128
.map_err(|e| TockError::AttributeParsing(AttributeParseError::InvalidString(e)))?;
@@ -137,151 +132,11 @@ impl SystemAttributes {
137132
result.bootloader_version = Some(string.to_owned());
138133

139134
// The 100 bytes prior to the application start address are reserved for the kernel attributes and flags
140-
let mut kernel_attr_binary = [0u8; 100];
141135
let kernel_attr_addr = result
142136
.appaddr
143137
.ok_or(TockError::MissingAttribute("appaddr".to_owned()))?
144138
- 100;
145-
board_core.read(kernel_attr_addr, &mut kernel_attr_binary)?;
146-
147-
let sentinel = bytes_to_string(&kernel_attr_binary[96..100]);
148-
let kernel_version = LittleEndian::read_uint(&kernel_attr_binary[95..96], 1);
149-
150-
let app_memory_len = LittleEndian::read_u32(&kernel_attr_binary[84..92]);
151-
let app_memory_start = LittleEndian::read_u32(&kernel_attr_binary[80..84]);
152-
153-
let kernel_binary_start = LittleEndian::read_u32(&kernel_attr_binary[68..72]);
154-
let kernel_binary_len = LittleEndian::read_u32(&kernel_attr_binary[72..76]);
155-
156-
result.sentinel = Some(sentinel);
157-
result.kernel_version = Some(kernel_version);
158-
result.app_mem_start = Some(app_memory_start);
159-
result.app_mem_len = Some(app_memory_len);
160-
result.kernel_bin_start = Some(kernel_binary_start);
161-
result.kernel_bin_len = Some(kernel_binary_len);
162-
163-
Ok(result)
164-
}
165-
166-
/// Read system attributes using a serial connection. A bootloader must be
167-
/// present on this board for this function to work properly.
168-
///
169-
/// # Parameters
170-
/// - `port`: Serial access, obtained from a
171-
/// [SerialConnection](crate::connection::SerialConnection)
172-
///
173-
/// # Returns
174-
/// - Ok(result): if attributes were read successfully
175-
/// - Err(TockloaderError::MisconfiguredBoard): if no start address is found or valid
176-
/// - Err(TockloaderError::MisconfiguredBoard): if attributes don't follow the UTF-8 format
177-
/// - Err(TockloaderError::SerialReadError): if reading fails
178-
pub(crate) async fn read_system_attributes_serial(
179-
port: &mut SerialStream,
180-
) -> Result<Self, TockloaderError> {
181-
let mut result = SystemAttributes::new();
182-
183-
// System attributes start at 0x600 and up to 0x9FF. See:
184-
// https://book.tockos.org/doc/memory_layout#flash-1
185-
let mut pkt = (0x600_u32).to_le_bytes().to_vec();
186-
// Each attribute is 64 bytes exactly, and there are 16 slots
187-
let length = (1024_u16).to_le_bytes().to_vec();
188-
for i in length {
189-
pkt.push(i);
190-
}
191-
192-
// Read the kernel attributes
193-
let (_, buf) = issue_command(
194-
port,
195-
Command::ReadRange,
196-
pkt,
197-
true,
198-
64 * 16,
199-
Response::ReadRange,
200-
)
201-
.await?;
202-
203-
let mut data = buf.chunks(64);
204-
205-
for current_slot in 0..data.len() {
206-
let slot_data = match data.next() {
207-
Some(data) => data,
208-
None => break,
209-
};
210-
211-
if let Some(decoded_attributes) = decode_attribute(slot_data) {
212-
match current_slot {
213-
0 => {
214-
result.board = Some(decoded_attributes.value.to_string());
215-
}
216-
1 => {
217-
result.arch = Some(decoded_attributes.value.to_string());
218-
}
219-
2 => {
220-
// Parse hex string like "0x40000" into actual u64 value
221-
result.appaddr = Some(
222-
u64::from_str_radix(
223-
decoded_attributes
224-
.value
225-
.to_string()
226-
.trim_start_matches("0x"),
227-
16,
228-
)
229-
.map_err(|e| {
230-
TockError::AttributeParsing(AttributeParseError::InvalidNumber(e))
231-
})?,
232-
);
233-
}
234-
3 => {
235-
result.boothash = Some(decoded_attributes.value.to_string());
236-
}
237-
_ => {}
238-
}
239-
} else {
240-
continue;
241-
}
242-
}
243-
244-
// TODO(george-cosma): separate kernel attributes from kernel flags.
245-
246-
let mut pkt = (0x40E_u32).to_le_bytes().to_vec();
247-
let length = (8_u16).to_le_bytes().to_vec();
248-
for i in length {
249-
pkt.push(i);
250-
}
251-
252-
// Read bootloader version
253-
let (_, buf) =
254-
issue_command(port, Command::ReadRange, pkt, true, 8, Response::ReadRange).await?;
255-
256-
let string = String::from_utf8(buf)
257-
.map_err(|e| TockError::AttributeParsing(AttributeParseError::InvalidString(e)))?;
258-
259-
// Strip null bytes
260-
let string = string.trim_matches(char::from(0));
261-
result.bootloader_version = Some(string.to_owned());
262-
263-
// The 100 bytes prior to the application start address are reserved
264-
// for the kernel attributes and flags
265-
let kernel_attr_addr = (result
266-
.appaddr
267-
.ok_or(TockError::MissingAttribute("appaddr".to_owned()))?
268-
- 100) as u32;
269-
let mut pkt = kernel_attr_addr.to_le_bytes().to_vec();
270-
let length = (100_u16).to_le_bytes().to_vec();
271-
for i in length {
272-
pkt.push(i);
273-
}
274-
275-
// Read kernel flags
276-
let (_, kernel_attr_binary) = issue_command(
277-
port,
278-
Command::ReadRange,
279-
pkt,
280-
true,
281-
100,
282-
Response::ReadRange,
283-
)
284-
.await?;
139+
let kernel_attr_binary = conn.read(kernel_attr_addr, 100).await?;
285140

286141
let sentinel = bytes_to_string(&kernel_attr_binary[96..100]);
287142
let kernel_version = LittleEndian::read_uint(&kernel_attr_binary[95..96], 1);

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,7 @@ impl IOCommands for ProbeRSConnection {
5656
if !self.is_open() {
5757
return Err(InternalError::ConnectionNotOpen.into());
5858
}
59-
let session = self.session.as_mut().expect("Board must be open");
60-
61-
let mut core = session.core(self.target_info.core)?;
62-
63-
let system_attributes = SystemAttributes::read_system_attributes_probe(&mut core)?;
59+
let system_attributes = SystemAttributes::read_system_attributes(self).await?;
6460
Ok(system_attributes)
6561
}
6662
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl IOCommands for SerialConnection {
8383

8484
ping_bootloader_and_wait_for_response(stream).await?;
8585

86-
let system_attributes = SystemAttributes::read_system_attributes_serial(stream).await?;
86+
let system_attributes = SystemAttributes::read_system_attributes(self).await?;
8787
Ok(system_attributes)
8888
}
8989
}

0 commit comments

Comments
 (0)