Code Monkey home page Code Monkey logo

uds-c's Introduction

Unified Diagnostic Services (UDS) Support Library in C

This is a platform agnostic C library that implements the Unified Diagnostics Services protocol for automotive electronics. UDS is documented in ISO 14229 and is the underpinning for the more well-known On-board Diagnostics (OBD) standard. The library currently supports UDS running over CAN (ISO 15765-4), which uses the ISO-TP (ISO 15765-2) protocol for message framing.

This library doesn't assume anything about the source of your diagnostic message requests or underlying interface to the CAN bus. It uses dependency injection to give you complete control.

Usage

First, create some shim functions to let this library use your lower level system:

// required, this must send a single CAN message with the given arbitration
// ID (i.e. the CAN message ID) and data. The size will never be more than 8
// bytes.
bool send_can(const uint32_t arbitration_id, const uint8_t* data,
        const uint8_t size) {
    ...
}

// optional, provide to receive debugging log messages
void debug(const char* format, ...) {
    ...
}


// not used in the current version
void set_timer(uint16_t time_ms, void (*callback)) {
    ...
}

With your shims in place, create a DiagnosticShims object to pass them around:

DiagnosticShims shims = diagnostic_init_shims(debug, send_can, set_timer);

With your shims in hand, send a simple PID request to the standard broadcast address, 0x7df (we use the constant OBD2_FUNCTIONAL_BROADCAST_ID here):

// Optional: This is your callback that will be called the response to your
// diagnostic request is received.
void response_received_handler(const DiagnosticResponse* response) {
    // You received a response! Do something with it.
}

DiagnosticRequestHandle handle = diagnostic_request_pid(&shims,
        DIAGNOSTIC_STANDARD_PID, // this is a standard PID request, not an extended or enhanced one
        OBD2_FUNCTIONAL_BROADCAST_ID, // the request is going out to the broadcast arbitration ID
        0x2, // we want PID 0x2
        response_received_handler); // our callback (optional, use NULL if you don't have one)

if(handle.completed) {
    if(!handle.success) {
        // something happened and it already failed - possibly we aren't
        // able to send CAN messages
        return;
    } else {
        // this should never occur right away - you need to receive a fresh
        // CAN message first
    }
} else {
    while(true) {
        // Continue to read from CAN, passing off each message to the handle.
        // This will return a 'completed' DiagnosticResponse when the when
        // the request is completely sent and the response is received
        // (which may take more than 1 CAN frames)
        DiagnosticResponse response = diagnostic_receive_can_frame(&shims,
            &handle, can_message_id, can_data, sizeof(can_data));

        if(response.completed && handle.completed) {
            if(handle.success) {
              if(response.success) {
                  // The request was sent successfully, the response was
                  // received successfully, and it was a positive response - we
                  // got back some data!
              } else {
                  // The request was sent successfully, the response was
                  // received successfully, BUT it was a negative response
                  // from the other node.
                  printf("This is the error code: %d", response.negative_response_code);
              }
            } else {
                // Some other fatal error ocurred - we weren't able to send
                // the request or receive the response. The CAN connection
                // may be down.
            }
        }
    }
}

Requests for other modes

If you want to do more besides PID requests on mode 0x1 and 0x22, there's a lower level API you can use. Here's how to make a mode 3 request to get DTCs.

DiagnosticRequest request = {
    arbitration_id: OBD2_FUNCTIONAL_BROADCAST_ID,
    mode: OBD2_MODE_EMISSIONS_DTC_REQUEST
};
DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request, NULL);

if(handle.completed) {
    if(!handle.success) {
        // something happened and it already failed - possibly we aren't
        // able to send CAN messages
        return;
    } else {
        // this should never occur right away - you need to receive a fresh
        // CAN message first
    }
} else {
    while(true) {
        // Continue to read from CAN, passing off each message to the handle.
        // This will return a 'completed' DiagnosticResponse when the when
        // the request is completely sent and the response is received
        // (which may take more than 1 CAN frames)
        DiagnosticResponse response = diagnostic_receive_can_frame(&shims,
            &handle, can_message_id, can_data, sizeof(can_data));

        if(response.completed && handle.completed) {
            if(handle.success) {
              if(response.success) {
                  // The request was sent successfully, the response was
                  // received successfully, and it was a positive response - we
                  // got back some data!
                  printf("The DTCs are: ");
                  for(int i = 0; i < response.payload_length; i++) {
                    printf("0x%x ", response.payload[i]);
                  }
              } else {
                  // The request was sent successfully, the response was
                  // received successfully, BUT it was a negative response
                  // from the other node.
                  printf("This is the error code: %d", response.negative_response_code);
              }
            } else {
                // Some other fatal error ocurred - we weren't able to send
                // the request or receive the response. The CAN connection
                // may be down.
            }
        }
    }
}

Dependencies

This library requires 2 dependencies:

Testing

The library includes a test suite that uses the check C unit test library.

$ make test

You can also see the test coverage if you have lcov installed and the BROWSER environment variable set to your choice of web browsers:

$ BROWSER=google-chrome-stable make coverage

OBD-II Basics

TODO diagram out a request, response and error response

  • store the request arb id, mode, pid, and payload locally
  • send a can message
  • get all new can messages passed to it
  • Check the incoming can message to see if it matches one of the standard ECU response IDs, or our arb ID + 0x8
  • if it matches, parse the diagnostic response and call the callback

Future Notes

you're going to request a few PIDs over and over again at some frequency you're going to request DTCs once and read the response you're going to clear DTCs once

we need another layer on top of that to handle the repeated requests.

Authors

Chris Peplin [email protected]

License

Copyright (c) 2013 Ford Motor Company

Licensed under the BSD license.

uds-c's People

Contributors

andrerh avatar emarsman avatar genojaford avatar jstoke53 avatar mstocke avatar peplin avatar pjt0620 avatar ppraka30 avatar vinodsama 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  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

uds-c's Issues

it feels like impossible to merge

I am trying to merge master branch with openxc/uds-c I keep on getting conflict error

both modified: deps/isotp-c

I do not understand how to resolve this. how do you update your sources?

slave functionality.

Hi,

I am trying to use this library on a slave device(MCU) to receive request from a master device(my computer).
Is it possible to use this library to receive request from a master device? I am asking because i can't seem to find any test code for a slave device. Is this library for master?

Exapmle:
A Client device waits for uds request, processes it and send the response in uds form. The issue is
which funtion will it use to create a uds response and send it to the master and wait again for another request.

Thanks for support.

Rename library to uds-c

This library is really more general than just OBD-II - I think the description of the parent protocol, the Unified Diagnostics Service, is more appropriate.

UDS or OBDII protocol

Hi All

Hope you are doing well and congrats for supporting automotive protocols.

My question is the following:

There is a clear difference between what is UDS and OBDII protocols as is pointed in the following article https://incardoc.com/en-us/article/the-difference-between-uds-and-obd-protocols/

If I am not wrong your implementation only support OBD messages. is this true?
if so how can I send standard UDS messages? do you have any example?
if not how can adapt your implementation for that? there is a easy way to do it.

hope you can respond soon.

Cheers,

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.