Skip to content

Commit

Permalink
Merge pull request #82 from trnila/extended_id
Browse files Browse the repository at this point in the history
Support extended IDs and generate impls for embedded_can::Frame trait
  • Loading branch information
Pascal Hertleif authored Aug 21, 2024
2 parents b3fcfb7 + 56c4fcb commit b14c392
Show file tree
Hide file tree
Showing 12 changed files with 967 additions and 165 deletions.
27 changes: 23 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ rust-version = "1.78.0"
std = []

[dependencies]
can-dbc = "5.0.0"
can-dbc = "6.0.0"
anyhow = "1.0.68"
heck = "0.4.0"
typed-builder = "0.18.0"
embedded-can = "0.4.1"

[workspace]
members = [
Expand Down
25 changes: 21 additions & 4 deletions fuzz/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions src/includes/errors.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CanError {
UnknownMessageId(u32),
UnknownMessageId(embedded_can::Id),
/// Signal parameter is not within the range
/// defined in the dbc
ParameterOutOfRange {
/// dbc message id
message_id: u32,
message_id: embedded_can::Id,
},
InvalidPayloadSize,
/// Multiplexor value not defined in the dbc
InvalidMultiplexor {
/// dbc message id
message_id: u32,
message_id: embedded_can::Id,
/// Multiplexor value not defined in the dbc
multiplexor: u16,
},
Expand Down
94 changes: 81 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ pub struct Config<'a> {
#[builder(default)]
pub impl_error: FeatureConfig<'a>,

/// Optional: Generate `embedded_can::Frame` impl for each frame. Default: `Always`
#[builder(default = FeatureConfig::Always)]
pub impl_embedded_can_frame: FeatureConfig<'a>,

/// Optional: Validate min and max values in generated signal setters. Default: `Always`
#[builder(default = FeatureConfig::Always)]
pub check_ranges: FeatureConfig<'a>,
Expand Down Expand Up @@ -143,6 +147,7 @@ pub fn codegen(config: Config<'_>, out: impl Write) -> Result<()> {
writeln!(&mut w)?;
writeln!(&mut w, "use core::ops::BitOr;")?;
writeln!(&mut w, "use bitvec::prelude::*;")?;
writeln!(&mut w, "use embedded_can::{{Id, StandardId, ExtendedId}};")?;

writeln!(w, r##"#[cfg(feature = "arb")]"##)?;
writeln!(&mut w, "use arbitrary::{{Arbitrary, Unstructured}};")?;
Expand Down Expand Up @@ -210,7 +215,7 @@ fn render_root_enum(mut w: impl Write, dbc: &DBC, config: &Config<'_>) -> Result
writeln!(w, "#[inline(never)]")?;
writeln!(
&mut w,
"pub fn from_can_message(id: u32, payload: &[u8]) -> Result<Self, CanError> {{",
"pub fn from_can_message(id: Id, payload: &[u8]) -> Result<Self, CanError> {{",
)?;
{
let mut w = PadAdapter::wrap(&mut w);
Expand All @@ -221,12 +226,11 @@ fn render_root_enum(mut w: impl Write, dbc: &DBC, config: &Config<'_>) -> Result
for msg in get_relevant_messages(dbc) {
writeln!(
w,
"{} => Messages::{1}({1}::try_from(payload)?),",
msg.message_id().0,
"{0}::MESSAGE_ID => Messages::{0}({0}::try_from(payload)?),",
type_name(msg.message_name())
)?;
}
writeln!(w, r#"n => return Err(CanError::UnknownMessageId(n)),"#)?;
writeln!(w, r#"id => return Err(CanError::UnknownMessageId(id)),"#)?;
}
writeln!(&mut w, "}};")?;
writeln!(&mut w, "Ok(res)")?;
Expand All @@ -243,7 +247,10 @@ fn render_root_enum(mut w: impl Write, dbc: &DBC, config: &Config<'_>) -> Result
fn render_message(mut w: impl Write, config: &Config<'_>, msg: &Message, dbc: &DBC) -> Result<()> {
writeln!(w, "/// {}", msg.message_name())?;
writeln!(w, "///")?;
writeln!(w, "/// - ID: {0} (0x{0:x})", msg.message_id().0)?;
match msg.message_id() {
can_dbc::MessageId::Standard(id) => writeln!(w, "/// - Standard ID: {0} (0x{0:x})", id),
can_dbc::MessageId::Extended(id) => writeln!(w, "/// - Extended ID: {0} (0x{0:x})", id),
}?;
writeln!(w, "/// - Size: {} bytes", msg.message_size())?;
if let can_dbc::Transmitter::NodeName(transmitter) = msg.transmitter() {
writeln!(w, "/// - Transmitter: {}", transmitter)?;
Expand Down Expand Up @@ -274,8 +281,18 @@ fn render_message(mut w: impl Write, config: &Config<'_>, msg: &Message, dbc: &D

writeln!(
&mut w,
"pub const MESSAGE_ID: u32 = {};",
msg.message_id().0
"pub const MESSAGE_ID: embedded_can::Id = {};",
match msg.message_id() {
// use StandardId::new().unwrap() once const_option is stable
can_dbc::MessageId::Standard(id) => format!(
"Id::Standard(unsafe {{ StandardId::new_unchecked({0:#x})}})",
id
),
can_dbc::MessageId::Extended(id) => format!(
"Id::Extended(unsafe {{ ExtendedId::new_unchecked({0:#x})}})",
id
),
}
)?;
writeln!(w)?;

Expand Down Expand Up @@ -415,6 +432,8 @@ fn render_message(mut w: impl Write, config: &Config<'_>, msg: &Message, dbc: &D
writeln!(w, "}}")?;
writeln!(w)?;

render_embedded_can_frame(&mut w, config, msg)?;

render_debug_impl(&mut w, config, msg)?;

render_arbitrary(&mut w, config, msg)?;
Expand Down Expand Up @@ -623,8 +642,8 @@ fn render_set_signal(
let mut w = PadAdapter::wrap(&mut w);
writeln!(
w,
r##"return Err(CanError::ParameterOutOfRange {{ message_id: {message_id} }});"##,
message_id = msg.message_id().0,
r##"return Err(CanError::ParameterOutOfRange {{ message_id: {}::MESSAGE_ID }});"##,
type_name(msg.message_name())
)?;
}
writeln!(w, r"}}")?;
Expand Down Expand Up @@ -742,8 +761,8 @@ fn render_multiplexor_signal(
}
writeln!(
&mut w,
"multiplexor => Err(CanError::InvalidMultiplexor {{ message_id: {}, multiplexor: multiplexor.into() }}),",
msg.message_id().0
"multiplexor => Err(CanError::InvalidMultiplexor {{ message_id: {}::MESSAGE_ID, multiplexor: multiplexor.into() }}),",
type_name(msg.message_name())
)?;
}

Expand Down Expand Up @@ -914,8 +933,7 @@ fn signal_to_payload(mut w: impl Write, signal: &Signal, msg: &Message) -> Resul
}
writeln!(
&mut w,
" .ok_or(CanError::ParameterOutOfRange {{ message_id: {} }})?;",
msg.message_id().0,
" .ok_or(CanError::ParameterOutOfRange {{ message_id: Self::MESSAGE_ID }})?;",
)?;
writeln!(
&mut w,
Expand Down Expand Up @@ -1273,6 +1291,56 @@ fn multiplexed_enum_variant_name(
))
}

fn render_embedded_can_frame(
w: &mut impl Write,
config: &Config<'_>,
msg: &Message,
) -> Result<(), std::io::Error> {
config.impl_embedded_can_frame.fmt_cfg(w, |w| {
writeln!(
w,
"\
impl embedded_can::Frame for {0} {{
fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self> {{
if id.into() != Self::MESSAGE_ID {{
None
}} else {{
data.try_into().ok()
}}
}}
fn new_remote(_id: impl Into<Id>, _dlc: usize) -> Option<Self> {{
unimplemented!()
}}
fn is_extended(&self) -> bool {{
match self.id() {{
Id::Standard(_) => false,
Id::Extended(_) => true,
}}
}}
fn is_remote_frame(&self) -> bool {{
false
}}
fn id(&self) -> Id {{
Self::MESSAGE_ID
}}
fn dlc(&self) -> usize {{
self.raw.len()
}}
fn data(&self) -> &[u8] {{
&self.raw
}}
}}",
type_name(msg.message_name())
)
})
}

fn render_debug_impl(mut w: impl Write, config: &Config<'_>, msg: &Message) -> Result<()> {
match &config.impl_debug {
FeatureConfig::Always => {}
Expand Down
1 change: 1 addition & 0 deletions testing/can-embedded/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ build-messages = ["dep:can-messages"]

[dependencies]
bitvec = { version = "1.0", default-features = false }
embedded-can = "0.4.1"


# This is optional and default so we can turn it off for the embedded target.
Expand Down
3 changes: 2 additions & 1 deletion testing/can-messages/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"
[dependencies]
bitvec = { version = "1.0", default-features = false }
arbitrary = { version = "1.0", optional = true }
embedded-can = "0.4.1"

[build-dependencies]
anyhow = "1.0"
Expand All @@ -15,4 +16,4 @@ dbc-codegen = { path = "../../" }
[features]
default = ["arb", "std"]
arb = ["arbitrary"]
std = []
std = []
Loading

0 comments on commit b14c392

Please sign in to comment.