Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit05851f6

Browse files
authored
Merge pull request#75 from davidkirchner/master
Fix DLC and add padding for CANFD frames
2 parentsd7942d5 +abe7063 commit05851f6

File tree

1 file changed

+84
-5
lines changed

1 file changed

+84
-5
lines changed

‎src/frame.rs

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,10 @@ impl AsRef<can_frame> for CanErrorFrame {
10751075
///
10761076
/// This is highly compatible with the `canfd_frame` from libc.
10771077
/// ([ref](https://docs.rs/libc/latest/libc/struct.canfd_frame.html))
1078+
///
1079+
/// Payload data that is greater than 8 bytes and whose data length does
1080+
/// not match a valid CANFD data length is padded with 0 bytes to the
1081+
/// next higher valid CANFD data length.
10781082
#[derive(Clone,Copy)]
10791083
pubstructCanFdFrame(canfd_frame);
10801084

@@ -1095,9 +1099,20 @@ impl CanFdFrame {
10951099
nif n <=CANFD_MAX_DLEN =>{
10961100
letmut frame =canfd_frame_default();
10971101
frame.can_id = can_id;
1098-
frame.len = nasu8;
10991102
frame.flags = fd_flags.bits();
1100-
frame.data[..n].copy_from_slice(data);
1103+
if n >8 && !CanFdFrame::is_valid_data_len(n){
1104+
// data must be 0 padded to the next valid DataLength
1105+
let new_len =CanFdFrame::next_valid_ext_dlen(n);
1106+
letmut padded_data:Vec<u8> =Vec::from(data);
1107+
padded_data.resize(new_len,0);
1108+
frame.len = new_lenasu8;
1109+
frame.data[..new_len].copy_from_slice(&padded_data);
1110+
}else{
1111+
// payload length is a valid CANFD data length so no padding is required
1112+
frame.len = nasu8;
1113+
frame.data[..n].copy_from_slice(data);
1114+
}
1115+
11011116
Ok(Self(frame))
11021117
}
11031118
_ =>Err(ConstructionError::TooMuchData),
@@ -1140,6 +1155,28 @@ impl CanFdFrame {
11401155
self.0.flags &= !CANFD_ESIasu8;
11411156
}
11421157
}
1158+
1159+
/// Checks whether a given length is a valid CANFD data length.
1160+
///
1161+
/// Valid values are `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`,
1162+
/// `12`, `16`, `20`, `24`, `32`, `48` or `64`.
1163+
fnis_valid_data_len(len:usize) ->bool{
1164+
(0..=8).contains(&len) ||[12,16,20,24,32,48,64].contains(&len)
1165+
}
1166+
1167+
/// Returns the next larger valid CANFD extended data length into which the given
1168+
/// length fits, up to a maximum of CANFD_MAX_DLEN.
1169+
fnnext_valid_ext_dlen(len:usize) ->usize{
1170+
let valid_ext_dlengths:[usize;7] =[12,16,20,24,32,48,64];
1171+
1172+
for valid_ext_lenin valid_ext_dlengths{
1173+
if valid_ext_len >= len{
1174+
return valid_ext_len;
1175+
}
1176+
}
1177+
// return CANFD_MAX_DLEN if len > CANFD_MAX_DLEN
1178+
CANFD_MAX_DLEN
1179+
}
11431180
}
11441181

11451182
implAsPtrforCanFdFrame{
@@ -1187,7 +1224,19 @@ impl EmbeddedFrame for CanFdFrame {
11871224

11881225
/// Data length code
11891226
fndlc(&self) ->usize{
1190-
self.0.lenasusize
1227+
matchself.0.len{
1228+
0..=8 =>self.0.lenasusize,
1229+
12 =>0x09,
1230+
16 =>0x0A,
1231+
20 =>0x0B,
1232+
24 =>0x0C,
1233+
32 =>0x0D,
1234+
48 =>0x0E,
1235+
64 =>0x0F,
1236+
// invalid data length, should never occur as the data is
1237+
// padded to a valid CANFD data length on frame creation
1238+
_ =>0x00,
1239+
}
11911240
}
11921241

11931242
/// A slice into the actual data.
@@ -1213,8 +1262,17 @@ impl Frame for CanFdFrame {
12131262
fnset_data(&mutself,data:&[u8]) ->Result<(),ConstructionError>{
12141263
match data.len(){
12151264
nif n <=CANFD_MAX_DLEN =>{
1216-
self.0.len = nasu8;
1217-
self.0.data[..n].copy_from_slice(data);
1265+
if n >8 && !CanFdFrame::is_valid_data_len(n){
1266+
// data must be 0 padded to the next valid DataLength
1267+
let new_len =CanFdFrame::next_valid_ext_dlen(n);
1268+
letmut padded_data:Vec<u8> =Vec::from(data);
1269+
padded_data.resize(new_len,0);
1270+
self.0.len = new_lenasu8;
1271+
self.0.data[..new_len].copy_from_slice(&padded_data);
1272+
}else{
1273+
self.0.len = nasu8;
1274+
self.0.data[..n].copy_from_slice(data);
1275+
}
12181276
Ok(())
12191277
}
12201278
_ =>Err(ConstructionError::TooMuchData),
@@ -1285,6 +1343,16 @@ mod tests {
12851343
constDATA:&[u8] =&[0,1,2,3];
12861344
constDATA_LEN:usize =DATA.len();
12871345

1346+
constEXT_DATA:&[u8] =&[0xAB;32];
1347+
constEXT_DATA_DLC:usize =0x0D;
1348+
1349+
constEXT_DATA_INVALID_DLEN:&[u8] =
1350+
&[0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA];
1351+
constEXT_DATA_PADDED:&[u8] =&[
1352+
0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0x00,0x00,
1353+
];
1354+
constEXT_DATA_PADDED_DLC:usize =0x09;
1355+
12881356
constEMPTY_DATA:&[u8] =&[];
12891357
constZERO_DATA:&[u8] =&[0u8;DATA_LEN];
12901358

@@ -1526,6 +1594,17 @@ mod tests {
15261594
assert_eq!(EXT_LOW_ID, frame.id());
15271595
assert!(!frame.is_standard());
15281596
assert!(frame.is_extended());
1597+
1598+
letmut frame =CanFdFrame::new(STD_ID,EXT_DATA).unwrap();
1599+
assert_eq!(frame.dlc(),EXT_DATA_DLC);
1600+
assert_eq!(frame.data(),EXT_DATA);
1601+
frame.set_data(EXT_DATA_INVALID_DLEN).unwrap();
1602+
assert_eq!(frame.data(),EXT_DATA_PADDED);
1603+
assert_eq!(frame.dlc(),EXT_DATA_PADDED_DLC);
1604+
1605+
let frame =CanFdFrame::new(STD_ID,EXT_DATA_INVALID_DLEN).unwrap();
1606+
assert_eq!(frame.data(),EXT_DATA_PADDED);
1607+
assert_eq!(frame.dlc(),EXT_DATA_PADDED_DLC);
15291608
}
15301609

15311610
#[test]

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp