#automotive #parser #lin #networking #ldf #linbus

lin-ldf

Parser for LDF files that describe automotive LIN bus networks

24 releases

new 0.0.24 Nov 21, 2024
0.0.23 Nov 21, 2024
0.0.19 Oct 30, 2024

#436 in Development tools

Download history 1016/week @ 2024-10-17 354/week @ 2024-10-24 189/week @ 2024-10-31 26/week @ 2024-11-07 97/week @ 2024-11-14

1,014 downloads per month

MIT license

94KB
1.5K SLoC

lin-ldf

LIN Description File (.ldf) parser using Rust's nom parser combinator library. LIN is an automotive network protocol used for communication between ECUs in a vehicle. The LDF file is used to describe the network configuration, including the different nodes and signals sent between them.


Crates.io Documentation

Supported LDF sections (so far)

  • LIN_protocol_version
  • LIN_language_version
  • LIN_speed
  • (Channel_name)
  • Nodes
  • (Node_composition)
  • Signals
  • (Diagnostic_signals)
  • Frames
  • (Sporadic_frame)
  • (Event_triggered_frame)
  • (Diagnostic_frames)
  • Node_attributes
  • Schedule_table
  • (Signal_groups)
  • (Signal_encoding_type)
  • (Signal_representation)

(optional sections are in parentheses)

Example

use lin_ldf::parse_ldf;

let ldf = r#"
LIN_description_file ;
LIN_protocol_version = "2.1" ;
LIN_language_version = "2.1" ;
LIN_speed = 19.2 kbps ;

/* PARSING IGNORES BLOCK COMMENTS */
// AND LINE COMMENTS

Nodes {
    Master: Master, 5 ms, 0.1 ms ;
    Slaves: Slave1, Slave2, Slave3 ;
}

Signals {
    Signal1: 10, 0, Master, Slave1 , Slave2 ;
    Signal2: 10, 0, Master, Slave1 ;
    Signal3: 10, 0, Slave1, Master ;
    Signal4: 10, 0, Slave1, Master ;
    Signal5: 2, 0, Slave1, Master ;
    Signal6: 1, 0, Slave1, Master ;
}

Frames {
    Frame1: 0, Master, 8 {
        Signal1, 0 ;
        Signal2, 10 ;
    }
    Frame2: 0x16, Slave1, 8 {
        Signal3, 0 ;
        Signal4, 10 ;
    }
}

Node_attributes {
   Slave1 {
       LIN_protocol = "2.1" ;
       configured_NAD = 0xB ;
       initial_NAD = 0xB ;
       product_id = 0x123, 0x4567, 8 ;
       response_error = Signal1 ;
       P2_min = 100 ms ;
       ST_min = 0 ms ;
       N_As_timeout = 1000 ms ;
       N_Cr_timeout = 1000 ms ;
       configurable_frames {
           Frame1 ;
           Frame2 ;
       }
   }
   Slave2 {
       LIN_protocol = "2.1" ;
       configured_NAD = 0xC ;
       initial_NAD = 0xC ;
       product_id = 0x124, 0x4568, 0x66 ;
       response_error = Signal2 ;
       P2_min = 100 ms ;
       ST_min = 0 ms ;
       N_As_timeout = 1000 ms ;
       N_Cr_timeout = 1000 ms ;
       configurable_frames {
           Frame1 ;
           Frame2 ;
       }
   }
}

Schedule_tables {
    AllFrames {
        Frame1 delay 10 ms ;
        Frame2 delay 10 ms ;
    }
}
"#;

let parsed_ldf = parse_ldf(ldf).expect("Failed to parse LDF file");

println!("LIN Version: {}", parsed_ldf.lin_protocol_version); // 2.1
println!("LIN Speed: {}", parsed_ldf.lin_speed); // 19200

for frame in parsed_ldf.frames {
    println!("Frame: `{}` is {} bytes long", frame.frame_name, frame.frame_size);
    for signal in frame.signals {
        println!("\tSignal: `{}` at bit position {}", signal.signal_name, signal.start_bit);
    }
}

Dependencies

~1MB
~19K SLoC