Code Monkey home page Code Monkey logo

ecu_diagnostics's Introduction

ecu_diagnostics

crates.io version docs.rs docs

A cross-platform crate for the diagnostic servers used for ECU diagnostics.

Ensure you are running Rust 1.56.0 (2021 edition) or higher to use this crate!

Features

  • Easy to use (Check the examples folder)
  • Implements UDS, KWP2000 and OBD2
  • Hardware API for accessing common OBD-2 adapter types (Passthru)
  • FFI bindings for use in C/C++ projects! (Check the examples folder)
  • Safe to use (Cannot inadvertently send incorrect requests to the ECU)
  • Parsing support - Where possible, data is returned in data structures, being interpreted from the ECU's response, rather than just bytes which have to be manually interpreted
  • ISO-TP transport layer, LIN, J1850 and DoIP is work in progress at this time
  • Diagnostic servers (For KWP2000 and UDS) automatically handle disconnects from ECU
  • Optional diagnostic server event receiving for logging internal server events

A quick overview of diagnostic servers used by ECUs

On-board diagnostics (OBD2)

ISO9141 - OBD2 is a legal requirement on all vehicles produced from 2002, allowing for reading of sensor data, reading and clearing standard DTCs, and reading basic vehicle information. OBD2 is designed to be safe and simple, and does not write data to the ECU.

Keyword protocol 2000 (KWP2000)

ISO14230 - KWP2000 is a advanced diagnostic protocol utilized by many vehicle manufacturers from 2000-2006 (Superseded by UDS). Unlike OBD2, KWP2000 allows for much more complex operations, which could potentially cause damage to a vehicle if used incorrectly.
A few examples of features allowed by KWP2000 are

  • ECU flashing
  • Clearing and reading of permanent DTCs
  • Manipulation of ECU communication parameters
  • Low level manipulation of ECU's EEPROM or RAM
  • Gateway access in vehicles which have them

The specification implemented in this crate is v2.2, dated 05-08-2002

Unified diagnostic services (UDS)

ISO14429 - UDS is an advanced diagnostic protocol utilized by almost all vehicle manufacturers from 2006 onwards. Like KWP2000, this protocol allows for reading/writing directly to the ECU, and should therefore be used with caution.

The specification implemented in this crate is the second edition, dated 01-12-2006.

NEW (as of v0.91 UNIFIED DIAGNOSTIC SERVER)

The individual diagnostic servers are now merged into 1 diagnostic server that can handle all the different protocols (Diagnostic protocol is specified at the servers creation). This dramatically reduces the crates bloat (Less copy/paste code), and the refactoring has also introduced some new features:

  • It is also possible now to define your own ECU Diagnostic protocol and session modes. Check the examples folder for how to do this!
  • You can now set a hook function for when the ECU has received the request and is processing (Useful for longer running operations)
  • You can now set a hook function for when transmit is completed and the server is waiting for the ECUs reply
  • The diagnostic server can now inform you if the ECU is connected or has been disconnected
  • The diagnostic server can now automtically change the ECUs diagnostic session mode after a reboot to avoid 'ServiceNotSupportedInActiveSession'

Diagnostic server checklist

OBD2

Custom service support: YES

Working specification services:

  • Service 01 - Show current data
  • Service 02 - Show data of freeze frame
  • Service 09 - Request vehicle information

KWP2000

Custom service support: YES

Working specification services:

  • StartDiagnosticSession
  • ECUReset
  • ReadDTCByStatus
  • ReadECUIdentification
  • ReadStatusOfDTC
  • ClearDiagnosticInformation

UDS

Custom service support: YES

Working specification services:

  • DiagnosticSessionControl
  • ECUReset
  • ReadDTCInformation
  • SecurityAccess

Hardware API checklist

The Hardware API contains a common interface for scanning for compatible devices on a system as well as an API for creating Channels for diagnostic servers using the hardware

Passthru (SAE J2534)

  • ISO-TP
  • CAN
  • Read Battery voltage

SocketCAN

  • ISO-TP
  • CAN

D-PDU (ISO 22900-2)

TBA

Notable contributions

  • @LLBlumire
  • @nyurik (Created the automotive_diag crate, which this project now relies on)

ecu_diagnostics's People

Contributors

afonso360 avatar lights0123 avatar nyurik avatar rnd-ash 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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ecu_diagnostics's Issues

Further standardizations

Hi, its been a while since I touched automotive_diag - wanted to syncup with you to follow up on postponed #21 stuff, and possibly more:

  • normalizing routine IDs, at least the standard plus possibly manufacturer-specific ones (we can add a sub-namespace for specific ones too)
  • units (pressure/temp/...) - how can we consolidate that in the automotive_diag for it to be reusable on all sides
  • scaling formulas
    • is scaling documented anywhere?
  • any other enums you have that you may not want to maintain because they are (semi-) standard

thx!

no-std UDS support

Hi, I am thinking of implementing UDS in embedded (no-std) environment, and as always - it is better to have one common code everyone uses than lots of slightly incompatible/buggy projects. Do you think UDS can be refactored to operate without memory allocations, possibly as a standalone (sub-) crate? Thanks!

UDSCommand missing services

Going based off Wikipedia (again, sorry I don't have access to the official standard), it appears the UDSCommand enum is missing SID 0x29 (Authentication) and 0x38 (Request File Transfer). If you have access to the standard, can you please check it to see if these are actually missing standard services?

Move MSRV into Cargo.toml

Don't specify MSRV in the Readme (maybe add it as a badge? But i didn't find anything usable for that). Instead, use msrv Cargo.toml value.

Software based ISO-TP channel

Taking inspiration from the D-PDU API, It is probably best to convert the Passthru ISO-TP methodology to software driven.

Currently, Passthru device opens a dedicated ISO-TP channel at a hardware level. This is good for performance, but it means that a dedicated CAN Channel cannot be opened at the same time as they conflict one another.

One down side to this method is it means it is impossible for the tester to send keep alive CAN messages to other ECUs in a vehicle whilst trying to maintain an ISO-TP channel with a target ECU.

Therefore, it is best to create a software ISO-TP channel, which uses a PT CAN channel to operate on. This will allow both ISO-TP messages and regular CAN messages to be exchanged at the same time.

the project does not compile

this language is new to me, build error is -

warning: unused imports: BorrowMut, Borrow, LockResult, cell::RefCell, convert::TryInto, default--> src\hardware\passthru\mod.rs:22:14 | 22 | borrow::{Borrow, BorrowMut}, | ^^^^^^ ^^^^^^^^^ 23 | cell::RefCell, | ^^^^^^^^^^^^^ 24 | convert::TryInto, | ^^^^^^^^^^^^^^^^ 25 | default, | ^^^^^^^ 26 | ffi::c_void, 27 | sync::{Arc, LockResult, Mutex, PoisonError}, | ^^^^^^^^^^ | = note:#[warn(unused_imports)]` on by default

warning: unused import: RegValue
--> src\hardware\passthru\mod.rs:35:22
|
35 | use winreg::{RegKey, RegValue};
| ^^^^^^^^

warning: unused import: RwLock
--> src\hardware\passthru\lib_funcs.rs:5:22
|
5 | use std::sync::{Arc, RwLock};
| ^^^^^^

warning: unused import: winreg::enums::*
--> src\hardware\passthru\lib_funcs.rs:9:5
|
9 | use winreg::enums::*;
| ^^^^^^^^^^^^^^^^

warning: unused imports: RegKey, RegValue
--> src\hardware\passthru\lib_funcs.rs:12:14
|
12 | use winreg::{RegKey, RegValue};
| ^^^^^^ ^^^^^^^^

warning: unused variable: x
--> src\hardware\passthru\mod.rs:811:13
|
811 | fn from(x: PoisonError) -> Self {
| ^ help: if this is intentional, prefix it with an underscore: _x
|
= note: #[warn(unused_variables)] on by default

warning: unused variable: x
--> src\hardware\passthru\mod.rs:820:13
|
820 | fn from(x: PoisonError) -> Self {
| ^ help: if this is intentional, prefix it with an underscore: _x

warning: variable does not need to be mutable
--> src\kwp2000\read_dtc_by_status.rs:90:9
|
90 | let mut res: Vec = Vec::new();
| ----^^^
| |
| help: remove this mut
|
= note: #[warn(unused_mut)] on by default

warning: associated function is never used: get_version
--> src\hardware\passthru\lib_funcs.rs:291:12
|
291 | pub fn get_version(&self, dev_id: u32) -> PassthruResult {
| ^^^^^^^^^^^
|
= note: #[warn(dead_code)] on by default

warning: associated function is never used: stop_msg_filter
--> src\hardware\passthru\lib_funcs.rs:439:12
|
439 | pub fn stop_msg_filter(&self, channel_id: u32, filter_id: u32) -> PassthruResult<()> {
| ^^^^^^^^^^^^^^^

warning: unused Result that must be used
--> src\hardware\passthru\mod.rs:464:17
|
464 | self.close();
| ^^^^^^^^^^^^^
|
= note: #[warn(unused_must_use)] on by default
= note: this Result may be an Err variant, which should be handled

warning: unused Result that must be used
--> src\hardware\passthru\mod.rs:636:17
|
636 | self.close();
| ^^^^^^^^^^^^^
|
= note: this Result may be an Err variant, which should be handled

warning: 12 warnings emitted`

J2534-2 implement CAN_MIXED_FORMAT

Needed for some J2534 devices for ISO-TP.

When an ECU responds with an ISO-TP frame that is not padded with 00 eg:

01A4: [02 10 20 76 54 32 10 99]

The adapter will reject this frame as ISO-TP as it expected the following formatted message:

01A4: [02 10 20 00 00 00 00 00]

Sending an IOCTL SET_CONFIG request of CAN_MIXED_FORMAT to the adapters ISO-TP channel will allow it to read and accept these ISO-TP frames

Hardware support

I'm assuming this currently only supports the Macchina A0/M2 for OSX/Linux usage?

The M2 seems to be out of stock everywhere unfortunately which makes using this library a bit difficult.

OBD2 CAN IDs not matching spec

Background

According to Wikipedia (sorry I don't have access to the actual OBD-II specification):

The PID query and response occurs on the vehicle's CAN bus. Standard OBD requests and responses use functional addresses. The diagnostic reader initiates a query using CAN ID 7DFh, which acts as a broadcast address, and accepts responses from any ID in the range 7E8h to 7EFh. ECUs that can respond to OBD queries listen both to the functional broadcast ID of 7DFh and one assigned ID in the range 7E0h to 7E7h. Their response has an ID of their assigned ID plus 8 e.g. 7E8h through 7EFh.

This approach allows up to eight ECUs, each independently responding to OBD queries. The diagnostic reader can use the ID in the ECU response frame to continue communication with a specific ECU. In particular, multi-frame communication requires a response to the specific ECU ID rather than to ID 7DFh.

This library's current code has you specify a sid/did (tx_id, rx_id) for OBD messages, and uses a single socket (socketCAN ISO-TP kernel interface) to handle sending/receiving messages on just those addresses. However, this causes problems when running against vehicles that follow the spec.

Observed Behavior

On a 2020 Toyota Camry, I tested Service_09::get_vin(), but it causes a timeout error. The reason is that if I set the tx_id to 0x7df, I get the first frame back from the ECU (with CAN ID 0x7e8), but the ECU pauses and waits for a FlowControl frame to be sent with CAN ID 0x7e0 (8 less than the ECU's transmit ID). The ISO-TP kernel sends flow control using the original broadcast address, 0x7df, which the ECU ignores. If I set the tx_id to 0x7e0 and request the VIN, the ECU completely ignores the request.

Other Implementations

I have a scan tool that sends the OBD messages properly, and I looked at the example code for Comma.ai's Panda, and they also send the request to 0x7df and listen on 0x7e8 (which sends the FC frame using ID 0x7e0). Their handling of UDS protocol does similar filtering to ensure the tx addr is changed from 0x7df to something in the range 0x7e0-0x7e7 (based on the first response received).

Proposed Design

The OBD code should have a single transmit socket with tx_id = 0x7df, and eight listening sockets with rx_id in the range 0x7e8 - 0x7ef (and tx_id for FC frames set to a value that is 8 less than the rx_id). This would follow the specification, allowing 8 ECUs to respond to OBD queries simultaneously. If it is a simple request, like to get the VIN, then that function can just take the first response and return it. In order for this to be possible, you will first have to implement the suggestion in Issue #11 to have a software-based ISO-TP channel. The socketcan-isotp crate definitely supports this, as demonstrated in their examples.

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.