Compare commits

...

3 Commits

Author SHA1 Message Date
occheung e6df69fe04 drtio_proto: add allocate step for flashing
This avoids reallocation while transfering binaries.
2024-10-24 12:32:01 +08:00
occheung b561099ec3 satman: fix checksum error message 2024-10-24 11:52:26 +08:00
occheung 5c2efa7989 runtime: check crc when flashing 2024-10-24 11:52:04 +08:00
5 changed files with 100 additions and 22 deletions

View File

@ -331,11 +331,15 @@ pub enum Packet {
CoreMgmtAllocatorDebugRequest { CoreMgmtAllocatorDebugRequest {
destination: u8, destination: u8,
}, },
CoreMgmtFlashRequest { CoreMgmtFlashRequest {
destination: u8,
payload_length: u32,
},
CoreMgmtFlashAddDataRequest {
destination: u8, destination: u8,
last: bool, last: bool,
length: u16, length: u16,
data: [u8; MASTER_PAYLOAD_MAX_SIZE], data: [u8; MASTER_PAYLOAD_MAX_SIZE]
}, },
CoreMgmtDropLinkAck { CoreMgmtDropLinkAck {
destination: u8, destination: u8,
@ -692,24 +696,28 @@ impl Packet {
0xda => Packet::CoreMgmtAllocatorDebugRequest { 0xda => Packet::CoreMgmtAllocatorDebugRequest {
destination: reader.read_u8()?, destination: reader.read_u8()?,
}, },
0xdb => { 0xdb => Packet::CoreMgmtFlashRequest {
destination: reader.read_u8()?,
payload_length: reader.read_u32()?,
},
0xdc => {
let destination = reader.read_u8()?; let destination = reader.read_u8()?;
let last = reader.read_bool()?; let last = reader.read_bool()?;
let length = reader.read_u16()?; let length = reader.read_u16()?;
let mut data: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE]; let mut data: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE];
reader.read_exact(&mut data[0..length as usize])?; reader.read_exact(&mut data[0..length as usize])?;
Packet::CoreMgmtFlashRequest { Packet::CoreMgmtFlashAddDataRequest {
destination: destination, destination: destination,
last: last, last: last,
length: length, length: length,
data: data, data: data,
} }
} }
0xdc => Packet::CoreMgmtDropLinkAck { 0xdd => Packet::CoreMgmtDropLinkAck {
destination: reader.read_u8()?, destination: reader.read_u8()?,
}, },
0xdd => Packet::CoreMgmtDropLink, 0xde => Packet::CoreMgmtDropLink,
0xde => { 0xdf => {
let last = reader.read_bool()?; let last = reader.read_bool()?;
let length = reader.read_u16()?; let length = reader.read_u16()?;
let mut data: [u8; SAT_PAYLOAD_MAX_SIZE] = [0; SAT_PAYLOAD_MAX_SIZE]; let mut data: [u8; SAT_PAYLOAD_MAX_SIZE] = [0; SAT_PAYLOAD_MAX_SIZE];
@ -720,7 +728,7 @@ impl Packet {
data: data, data: data,
} }
} }
0xdf => { 0xe0 => {
let last = reader.read_bool()?; let last = reader.read_bool()?;
let length = reader.read_u16()?; let length = reader.read_u16()?;
let mut value: [u8; SAT_PAYLOAD_MAX_SIZE] = [0; SAT_PAYLOAD_MAX_SIZE]; let mut value: [u8; SAT_PAYLOAD_MAX_SIZE] = [0; SAT_PAYLOAD_MAX_SIZE];
@ -731,7 +739,7 @@ impl Packet {
value: value, value: value,
} }
} }
0xe0 => Packet::CoreMgmtReply { 0xe1 => Packet::CoreMgmtReply {
succeeded: reader.read_bool()?, succeeded: reader.read_bool()?,
}, },
@ -1178,37 +1186,42 @@ impl Packet {
writer.write_u8(0xda)?; writer.write_u8(0xda)?;
writer.write_u8(destination)?; writer.write_u8(destination)?;
} }
Packet::CoreMgmtFlashRequest { Packet::CoreMgmtFlashRequest { destination, payload_length } => {
writer.write_u8(0xdb)?;
writer.write_u8(destination)?;
writer.write_u32(payload_length)?;
}
Packet::CoreMgmtFlashAddDataRequest {
destination, destination,
last, last,
length, length,
data, data,
} => { } => {
writer.write_u8(0xdb)?; writer.write_u8(0xdc)?;
writer.write_u8(destination)?; writer.write_u8(destination)?;
writer.write_bool(last)?; writer.write_bool(last)?;
writer.write_u16(length)?; writer.write_u16(length)?;
writer.write_all(&data[..length as usize])?; writer.write_all(&data[..length as usize])?;
} }
Packet::CoreMgmtDropLinkAck { destination } => { Packet::CoreMgmtDropLinkAck { destination } => {
writer.write_u8(0xdc)?; writer.write_u8(0xdd)?;
writer.write_u8(destination)?; writer.write_u8(destination)?;
} }
Packet::CoreMgmtDropLink => writer.write_u8(0xdd)?, Packet::CoreMgmtDropLink => writer.write_u8(0xde)?,
Packet::CoreMgmtGetLogReply { last, length, data } => { Packet::CoreMgmtGetLogReply { last, length, data } => {
writer.write_u8(0xde)?; writer.write_u8(0xdf)?;
writer.write_bool(last)?; writer.write_bool(last)?;
writer.write_u16(length)?; writer.write_u16(length)?;
writer.write_all(&data[0..length as usize])?; writer.write_all(&data[0..length as usize])?;
} }
Packet::CoreMgmtConfigReadReply { last, length, value } => { Packet::CoreMgmtConfigReadReply { last, length, value } => {
writer.write_u8(0xdf)?; writer.write_u8(0xe0)?;
writer.write_bool(last)?; writer.write_bool(last)?;
writer.write_u16(length)?; writer.write_u16(length)?;
writer.write_all(&value[0..length as usize])?; writer.write_all(&value[0..length as usize])?;
} }
Packet::CoreMgmtReply { succeeded } => { Packet::CoreMgmtReply { succeeded } => {
writer.write_u8(0xe0)?; writer.write_u8(0xe1)?;
writer.write_bool(succeeded)?; writer.write_bool(succeeded)?;
} }
} }

View File

@ -20,6 +20,7 @@ cslice = "0.3"
log = "0.4" log = "0.4"
embedded-hal = "0.2" embedded-hal = "0.2"
core_io = { version = "0.1", features = ["collections"] } core_io = { version = "0.1", features = ["collections"] }
crc = { version = "1.7", default-features = false }
byteorder = { version = "1.3", default-features = false } byteorder = { version = "1.3", default-features = false }
void = { version = "1", default-features = false } void = { version = "1", default-features = false }
futures = { version = "0.3", default-features = false, features = ["async-await"] } futures = { version = "0.3", default-features = false, features = ["async-await"] }

View File

@ -1,6 +1,8 @@
use alloc::{rc::Rc, string::String, vec::Vec}; use alloc::{rc::Rc, string::String, vec::Vec};
use core::cell::RefCell; use core::cell::RefCell;
use byteorder::{ByteOrder, NativeEndian};
use crc::crc32;
use futures::{future::poll_fn, task::Poll}; use futures::{future::poll_fn, task::Poll};
use libasync::{smoltcp::TcpStream, task}; use libasync::{smoltcp::TcpStream, task};
use libboard_artiq::{drtio_routing::RoutingTable, use libboard_artiq::{drtio_routing::RoutingTable,
@ -638,6 +640,31 @@ mod remote_coremgmt {
) -> Result<()> { ) -> Result<()> {
let mut image = &image[..]; let mut image = &image[..];
let alloc_reply = drtio::aux_transact(
aux_mutex,
linkno,
routing_table,
&Packet::CoreMgmtFlashRequest {
destination: destination,
payload_length: image.len() as u32,
},
timer,
).await;
match alloc_reply {
Ok(Packet::CoreMgmtReply { succeeded: true }) => Ok(()),
Ok(packet) => {
error!("received unexpected aux packet: {:?}", packet);
write_i8(stream, Reply::Error as i8).await?;
Err(drtio::Error::UnexpectedReply)
}
Err(e) => {
error!("aux packet error ({})", e);
write_i8(stream, Reply::Error as i8).await?;
Err(drtio::Error::AuxError)
}
}?;
while !image.is_empty() { while !image.is_empty() {
let mut data = [0; MASTER_PAYLOAD_MAX_SIZE]; let mut data = [0; MASTER_PAYLOAD_MAX_SIZE];
let len = image.read(&mut data).unwrap(); let len = image.read(&mut data).unwrap();
@ -647,7 +674,7 @@ mod remote_coremgmt {
aux_mutex, aux_mutex,
linkno, linkno,
routing_table, routing_table,
&Packet::CoreMgmtFlashRequest { &Packet::CoreMgmtFlashAddDataRequest {
destination: destination, destination: destination,
last: last, last: last,
length: len as u16, length: len as u16,
@ -825,12 +852,27 @@ mod local_coremgmt {
} }
pub async fn image_write(stream: &mut TcpStream, cfg: &Rc<Config>, image: Vec<u8>) -> Result<()> { pub async fn image_write(stream: &mut TcpStream, cfg: &Rc<Config>, image: Vec<u8>) -> Result<()> {
let value = cfg.write("boot", image); let mut image = image.clone();
if value.is_ok() { let image_ref = &image[..];
let bin_len = image.len() - 4;
let (image_ref, expected_crc) = {
let (image_ref, crc_slice) = image_ref.split_at(bin_len);
(image_ref, NativeEndian::read_u32(crc_slice))
};
let actual_crc = crc32::checksum_ieee(image_ref);
if actual_crc == expected_crc {
info!("CRC passed. Writing boot image to SD card...");
image.truncate(bin_len);
cfg.write("boot", image).expect("failed to write boot image");
reboot(stream).await?; reboot(stream).await?;
} else { } else {
// this is an error because we do not expect write to fail error!(
error!("failed to write boot file: {:?}", value); "CRC failed, images have not been written to flash.\n(actual {:08x}, expected {:08x})",
actual_crc, expected_crc
);
write_i8(stream, Reply::Error as i8).await?; write_i8(stream, Reply::Error as i8).await?;
} }
Ok(()) Ok(())

View File

@ -1280,6 +1280,24 @@ fn process_aux_packet(
drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false }) drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false })
} }
drtioaux::Packet::CoreMgmtFlashRequest { drtioaux::Packet::CoreMgmtFlashRequest {
destination: _destination,
payload_length
} => {
forward!(
router,
_routing_table,
_destination,
*rank,
*self_destination,
_repeaters,
&packet,
timer
);
core_manager.allocate_image_buffer(payload_length as usize);
drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: true })
}
drtioaux::Packet::CoreMgmtFlashAddDataRequest {
destination: _destination, destination: _destination,
last, last,
length, length,

View File

@ -115,6 +115,10 @@ impl<'a> Manager<'_> {
.map_err(|err| warn!("failed to erase: {:?}", err)) .map_err(|err| warn!("failed to erase: {:?}", err))
} }
pub fn allocate_image_buffer(&mut self, image_size: usize) {
self.image_payload = Vec::with_capacity(image_size);
}
pub fn add_image_data(&mut self, data: &[u8], data_len: usize) { pub fn add_image_data(&mut self, data: &[u8], data_len: usize) {
self.image_payload.extend(&data[..data_len]); self.image_payload.extend(&data[..data_len]);
} }
@ -137,7 +141,7 @@ impl<'a> Manager<'_> {
self.cfg.write("boot", image).expect("failed to write boot image"); self.cfg.write("boot", image).expect("failed to write boot image");
} else { } else {
panic!( panic!(
"CRC failed in SDRAM (actual {:08x}, expected {:08x})", "CRC failed, images have not been written to flash.\n(actual {:08x}, expected {:08x})",
actual_crc, expected_crc actual_crc, expected_crc
); );
} }