GithubHelp home page GithubHelp logo

i-can-hack / automotive Goto Github PK

View Code? Open in Web Editor NEW
37.0 2.0 7.0 210 KB

Rust crate providing a variety of automotive related libraries, such as communicating with CAN interfaces and diagnostic APIs

License: MIT License

Rust 96.94% Shell 0.29% Python 2.77%
automotive isotp rust uds

automotive's Introduction

The Automotive Crate

crates.io docs.rs

Welcome to the automotive crate documentation. The purpose of this crate is to help you with all things automotive related. Most importantly, it provides a fully async CAN interface supporting multiple adapters.

Async CAN Example

The following adapter opens the first available adapter on the system, and then receives all frames. Note how the sent frame is awaited, which waits until the message is ACKed on the CAN bus.

use automotive::StreamExt;
async fn can_example() -> automotive::Result<()> {
    let adapter = automotive::can::get_adapter()?;
    let mut stream = adapter.recv();

    let frame = automotive::can::Frame::new(0, 0x541.into(), &[0xff; 8])?;
    adapter.send(&frame).await;

    while let Some(frame) = stream.next().await {
        let id: u32 = frame.id.into();
        println!("[{}]\t0x{:x}\t{}", frame.bus, id, hex::encode(frame.data));
    }
    Ok(())
}

UDS Example

The automotive crate also supplies interfaces for various diagnostic protocols such as UDS. The adapter is first wrapped to support the ISO Transport Layer, then a UDS Client is created. All methods are fully async, making it easy to communicate with multiple ECUs in parallel. See automotive#21 for progress on the supported SIDs.

 async fn uds_example() -> automotive::Result<()> {
    let adapter = automotive::can::get_adapter()?;
    let isotp = automotive::isotp::IsoTPAdapter::from_id(&adapter, 0x7a1);
    let uds = automotive::uds::UDSClient::new(&isotp);

    uds.tester_present().await.unwrap();
    let response = uds.read_data_by_identifier(automotive::uds::DataIdentifier::ApplicationSoftwareIdentification as u16).await?;

    println!("Application Software Identification: {}", hex::encode(response));
    Ok(())
 }

CAN Adapters

The following CAN adapters are supported.

Supported CAN adapters

  • SocketCAN (Linux only)
  • comma.ai panda (all platforms using rusb)

Known limitations / Notes

This library has some unique features that might expose (performance) issues in drivers you wouldn't otherwise notice, so check the list of known limitations below.

This library supports awaiting a sent frame and waiting for the ACK on the CAN bus. This requires receiving these ACKs from the adapter, and matching them to the appropriate sent frame. This requires some level of hardware support that is not offered by all adapters/drivers. If this is not supported by the driver, an ACK will be simulated as soon as the frame is transmitted, but this can cause issues if precise timing is needed.

  • SocketCAN drivers without IFF_ECHO: This class of SocketCAN drivers has no hardware support for notifying the driver when a frame was ACKed. This is instead emulated by the Linux kernel. Due to transmitted frames immediately being received again this can cause the receive queue to fill up if more than 476 (default RX queue size on most systems) are transmitted in one go. To solve this we implement emulated ACKs ourself, instead of relying on the ACKs from the kernel.
  • comma.ai panda
    • The panda does not retry frames that are not ACKed, and drops them instead. This can cause panics in some internal parts of the library when frames are dropped. panda#1922 tracks this issue.
    • The CAN-FD flag on a frame is ignored, if the hardware is configured for CAN-FD all frames will be interpreted as FD regardless of the FD frame bit (r0 bit).
  • PCAN-USB: The Peak CAN adapters have two drivers:
    • Kenel built in driver (peak_usb). The kernel driver properly implements IFF_ECHO, but has a rather small TX queue. This should not cause any issues, but it can be inreased with ifconfig can0 txqueuelen <size>.
    • Out-of-tree driver (pcan) that can be downloaded from Peak System's website. The out-of-tree driver is not recommended as it does not implement IFF_ECHO.
  • neoVI/ValueCAN: Use of Intrepid Control System's devices is not recommended due to issues in their SocketCAN driver. If many frames are transmitted simultaneously it will cause the whole system/kernel to hang. intrepid-socketcan-kernel-module#20 tracks this issue.

Implementing a New Adapter

Implementing a new adapter is done by implementing the CanAdapter Trait. Hardware implementations can be blocking, as the AsyncCanAdapter takes care of presenting an async interface to the user. The library makes some assumptions around sending/receiving frames. These assumption are also verified by the tests in tests/adapter_tests.rs.

  • The send function takes a &mut VecDequeue of frames. Frames to be sent are taken from the front of this queue. If there is no space in the hardware or driver buffer to send out all messages it's OK to return before the queue is fully empty. If an error occurs make sure to put the message back at the beginning of the queue and return.
  • The hardware or driver is free to prioritize sending frames with a lower Arbitration ID to prevent priority inversion. However frames with the same Arbitration ID need to be send out on the CAN bus in the same order as they were queued. This assumption is needed to match a received ACK to the correct frame.
  • Once a frame is ACKed it should be put in the receive queue with the loopback flag set. The AsyncCanAdapter wrapper will take care of matching it against the right transmit frame and resolving the Future. If this is not supported by the underlying hardware, this can be faked by looping back all transmitted frames immediately.

Roadmap

Features I'd like to add in the future. Also check the issues page.

  • CCP/XCP Client
  • Update file extraction (e.g. .frf and .odx)
  • VIN Decoding
  • J2534 Support on Windows
  • More device support
  • WebUSB support
  • Python bindings

automotive's People

Contributors

pd0wm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

automotive's Issues

[ISO-TP] Check frame length

10.4.2.2	 CAN frame data optimization (TX_DL = 8)
If this solution is used, the DLC does not always need to be 8. If the N_PDU to be transmitted is shorter
than 8 bytes, then the sender may optimize the CAN bus load by shortening the CAN frame data to
contain only the number of bytes occupied by the N_PDU (no padding of unused data bytes). CAN frame
data optimization can only be used for an SF, FC frame or the last CF of a segmented message.

Improve typing for CAN/CAN-FD

Try to make impossible states not representable, but hopefully not by making the UX worse. E.g.

  • Remote frames cannot contain any data. Separate type?
  • Remote frames cannot be CAN-FD.
  • Split out CAN/CAN-FD data frames into separate types? Or keep as a flag? CAN-FD has special flags (e.g. BRS).
  • Split out Error frame as separate type?
  • Investigate use of [u8; 64] instead of Vec for CAN data storage

[AsyncCAN] Ensure send future resolves when packet is ACKed

Currently the send future resolves as soon as it's sent to the background thread. This makes it not possible to properly implement frame separation between ISO-TP frames when there is other traffic on the bus.

TODO:

  • Delay resolving send future: d3e40dd
  • Call callback when frame is actually received #30
  • Test that all adapters return frames in the same order as they were queued to send

UDS Client

Implement all UDS SIDs from ISO Standard

  • Diagnostic and Communication Management
    • DiagnosticSessionControl = 0x10
    • EcuReset = 0x11
    • SecurityAccess = 0x27
    • CommunicationControl = 0x28
    • TesterPresent = 0x3e
    • AccessTimingParameter = 0x83
    • SecuredDataTransmission = 0x84
    • ControlDTCSetting = 0x85
    • ResponseOnEvent = 0x86
    • LinkControl = 0x87
  • Data Transmission
    • ReadDataByIdentifier = 0x22
    • ReadMemoryByAddress = 0x23
    • ReadScalingDataByIdentifier = 0x24
    • ReadDataByPeriodicIdentifier = 0x2a
    • DynamicallyDefineDataIdentifier = 0x2c
    • WriteDataByIdentifier = 0x2e
    • WriteMemoryByAddress = 0x3d
  • Stored Data Transmission
    • ClearDiagnosticInformation = 0x14
    • ReadDTCInformation = 0x19
      • ReportNumberOfDTCByStatusMask = 0x01
      • ReportDTCByStatusMask = 0x02
      • ReportDTCSnapshotIdentification = 0x03
      • ReportDTCSnapshotRecordByDTCNumber = 0x04
      • ReportDTCStoredDataByRecordNumber = 0x05
      • ReportDTCExtDataRecordByDTCNumber = 0x06
      • ReportNumberOfDTCBySeverityMaskRecord = 0x07
      • ReportDTCBySeverityMaskRecord = 0x08
      • ReportSeverityInformationOfDTC = 0x09
      • ReportSupportedDTC = 0x0A
      • ReportFirstTestFailedDTC = 0x0B
      • ReportFirstConfirmedDTC = 0x0C
      • ReportMostRecentTestFailedDTC = 0x0D
      • ReportMostRecentConfirmedDTC = 0x0F
      • ReportMirrorMemoryDTCByStatusMask = 0x10
      • ReportMirrorMemoryDTCExtDataRecordByDTCNumber = 0x11
      • ReportNumberOfMirrorMemoryDTCByStatusMask = 0x12
      • ReportNumberOfEmissionsOBDDTCByStatusMask = 0x13
      • ReportEmissionsOBDDTCByStatusMask = 0x14
      • ReportDTCFaultDetectionCounter = 0x15
      • ReportDTCWithPermanentStatus = 0x16
      • ReportDTCExtDataRecordByRecordNumber = 0x17
      • ReportUserDefMemoryDTCByStatusMask = 0x18
      • ReportUserDefMemoryDTCSnapshotRecordByDTCNumber = 0x19
      • ReportUserDefMemoryDTCExtDataRecordByDTCNumber = 0x42
      • ReportWWHOBDDTCWithPermanentStatus = 0x55
  • Input/Output Control
    • InputOutputControlByIdentifier = 0x2f
  • Routine
    • RoutineControl = 0x31
  • Upload/Download
    • RequestDownload = 0x34
    • RequestUpload = 0x35
    • TransferData = 0x36
    • RequestTransferExit = 0x37
    • RequestFileTransfer = 0x38

Build WASM demo

Using a comma.ai panda make a simple demo web-page that displays incoming CAN messages.

Look into the cross_usb package to supplement or replace the current libusb backend.

[Panda] Clean up CAN-FD behavior

The CAN-FD flag on a frame is ignored, if the hardware is configured for CAN-FD all frames will be interpreted as FD regardless of the FD frame bit (r0 bit).

Mostly requires upstream changes to the USB protocol.

[SocketCAN] Drivers without `IFF_ECHO` fail to confirm all messages

Everything seems fine up to burst of up to 238 messages, above that all MSG_CONFIRM/loopback messages are dropped. This is only an issues for drivers not setting the IFF_ECHO flag.

For example this happens on both vcan as well as the pcan driver. peak_usb is fine, as it's implementing IFF_ECHO.

[CAN] Adapter support

Issue for tracking support for new CAN adapters:

  • SLCan (serial based)
  • Peak-CAN devices (E.g. PCAN-USB FD)
  • Intrepid Devices (e.g. ValueCAN and NEOVI)
  • Vector Devices (e.g. VN1610)
  • J2534 DLL support (passthru, Windows only)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.