I hope I got this right (safety-proprty), i.e. so that references are enforced to have equal life-time:
impl<'a> From<&'a Header> for &'a [u8] {
fn from(value: &Header) -> Self {
// SAFETY: out-of-boundary is not possible, given that the size constraint
// exists in the struct definition. The lifetime parameter links the lifetime
// of the header reference to the slice.
unsafe { from_raw_parts((value as *const Header) as *const u8, size_of::<Header>()) }
}
}
great implemented transmutable (with u8
) enum
for the frame type of the #ZMODEM transfer protocol header: https://github.com/jarkkojs/zmodem2/commit/c76316c2ecae097be03506e8ce19d61287e6468a
I can use this as a reference model for refactoring rest of the code base.
Next, I’ll replace encoding: u8
with a similar enum Encoding
.
After trial and error, i.e. brute force going through crc
crate algorithms, I can say that CRC32_32_ISO_HDLC
is the correct variant for ZMODEM 32-bit transfers, i.e. cipher can be acquired by:
const CRC32: Crc<u32> = Crc::<u32>::new(&CRC_32_ISO_HDLC);
It is better to declare like this so that it gets compiled into .rodata
and not initialized at run-time.
I really like this heapless
. It sort of helps to implement my strategy for developing Rust programs:
1.Maximize no_std
surface. 2 Minimize heap allocations.
It is easier to see then the hot zones where the program actually dynamically grows for a good reason, similarly as with unsafe
blocks it is easy to the red zones for memory errors. This helps a lot with availability and protection against denial-of-service (DoS) attacks.
So to summarize I don’t split Rust program in my mind just to “unsafe” and “safe” but instead I split it “unsafe”, “static” and “dynamic”, or along the lines.
really like this fsmetry
crate (also no_std
):
fsmentry::dsl! {
#[derive(Debug)]
pub Mode {
WaitingInput -> WaitingCommand -> WaitingInput;
WaitingCommand -> SendingFile -> WaitingInput;
WaitingCommand -> ReceivingFile -> WaitingInput;
WaitingCommand -> Exit;
}
}
I use it manage life-cycle in my small serial port tool tior
. I also have some #zmodem code together but it is apparently much bigger leap to implement the #cli interface than it is to implement the protocol. I had to take some time to refactor existing code (e.g. to put FSM in place) and now I’m doing file path auto-completing interface for sending and receiving files with zmodem.
For the text input I’m going to use inquire.
I guess the definition of feature complete for 0.1 version is fully working zmodem transfers and known bugs have been fixed. Right now there is a single known bug: https://github.com/jarkkojs/tior/issues/1.
I wonder if #BeagleV has similar #DIP switch as #VisionFive2, which works as a selector for different boot modes?
In VisionFive2 you can choose to:
These VisionFive2 e.g. pretty capable board for prototyping CPU extensions.