Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Message serialization refactoring #140

Merged
merged 1 commit into from
Dec 2, 2022

Conversation

qwerty19106
Copy link
Contributor

This refactoring optimizes code for embedded context and tiny increases performance generally.
Also it simplify AsyncReader code, which I plan to send in next PR.

  1. Message serialization moved to MAVLinkV1MessageRaw::serialize_message and MAVLinkV2MessageRaw::serialize_message methods to get common serialization API. The write_v1_msg and write_v2_msg methods has been left as thin wrapper.
    As variant, this code should be placed to MavFrame::ser method. But MavFrame::ser body causes the some questions.

  2. MAVLinkV1MessageRaw and MAVLinkV2MessageRaw has been make as thin struct over byte array. It allows send serialized message over Direct Memory Acces on embedded and other contexts. DMA is very fast in comparison with interrupts or polling.
    It break MAVLinkV1MessageRaw and MAVLinkV2MessageRaw API: fields becomes methods.

  3. I removed unnecessary bytes copying at payload serialization. BytesMut was been rewrite as thin wrapper over slice.
    It is breaking change: Message::ser method was changed. But I hope that no one uses Message::ser method directly.

@qwerty19106
Copy link
Contributor Author

The v1_encode_decode_tests is failed, but CI is succesfull. It is strange.

@qwerty19106 qwerty19106 changed the title [WIP] Message serialization refactoring Message serialization refactoring Nov 28, 2022
@qwerty19106
Copy link
Contributor Author

It is ready to review

src/bytes_mut.rs Outdated Show resolved Hide resolved
@patrickelectric
Copy link
Member

The code looks great, the only thing necessary is to remove the old commented code.

src/lib.rs Outdated Show resolved Hide resolved
@patrickelectric
Copy link
Member

I would just recommend to squash the latest commit on the specific commits that it's fixing.
@danieleades, any more comments ?


let payload = &mut message.payload_buffer[..message.payload_length as usize];
reader.read_exact(payload)?;
let mut message = MAVLinkV1MessageRaw::new();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let mut message = MAVLinkV1MessageRaw::new();
let mut message = Self::new();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The read_v1_raw_message function is not method. I could not apply Self here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

src/lib.rs Outdated
pub fn payload(&self) -> &[u8] {
&self.payload_buffer[..self.payload_length as usize]
let payload_length = self.payload_length() as usize;
Copy link
Contributor

@danieleades danieleades Dec 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lossless conversions-

Suggested change
let payload_length = self.payload_length() as usize;
let payload_length: u8 = self.payload_length().into();

the type annotation might not even be required here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The payload_length method return u8. Casting from u8 to usize is loseless.

Casting from a smaller integer to a larger integer (e.g. u8 -> u32) will
zero-extend if the source is unsigned

I could change payload_length return type to usize if needed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The payload_length method return u8. Casting from u8 to usize is loseless.

Casting from a smaller integer to a larger integer (e.g. u8 -> u32) will
zero-extend if the source is unsigned

I could change payload_length return type to usize if needed.

I understand the cast is lossless. That's why you might as well use the explicitly lossless method.

Doing the conversion once, inside the payload_length method, sounds like a good approach

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the mavlink protocol defines the payload_length as u8, we should stay with it to make the protocol definition clear.

src/lib.rs Outdated
&mut self.payload_buffer[..self.payload_length as usize]
#[inline]
pub fn checksum(&self) -> u16 {
let payload_length = self.payload_length() as usize;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use lossless conversion

src/lib.rs Outdated
}

fn mut_payload_and_checksum_and_sign(&mut self) -> &mut [u8] {
let payload_length = self.payload_length() as usize;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use lossless conversion

i won't bother writing all of these out. You should be find them all with something like

cargo +nightly clippy -- -A clippy::all -W clippy::cast_lossless

src/utils.rs Outdated
@@ -1,14 +1,11 @@
use crate::{bytes_mut::BytesMut, MAX_FRAME_SIZE};

/// Removes the trailing zeroes in the payload
///
/// # Note:
///
/// There must always be at least one remaining byte even if it is a
/// zero byte.
#[allow(dead_code)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to allow dead code here?

Copy link
Member

@patrickelectric patrickelectric Dec 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not related to the PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was #[allow(dead_code)] before this PR. I will remove it.

Copy link
Contributor

@danieleades danieleades left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple of little nits

@qwerty19106
Copy link
Contributor Author

@patrickelectric, could I squash all commits to single commit?

@patrickelectric
Copy link
Member

@patrickelectric, could I squash all commits to single commit?

Yes.

@patrickelectric
Copy link
Member

Thanks for the PR @qwerty19106, nice work!

@patrickelectric patrickelectric merged commit 2f9ef39 into mavlink:master Dec 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants