X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=libs%2Fisotp-c%2FREADME.mkd;fp=libs%2Fisotp-c%2FREADME.mkd;h=98030483dd1726915255e8ee24230a868bb575bb;hb=32e25cbca210a359b09768537b6f443fe90a3070;hp=0000000000000000000000000000000000000000;hpb=76c43dec62b2e21cd6446360c00d4fe6b437533f;p=apps%2Flow-level-can-service.git diff --git a/libs/isotp-c/README.mkd b/libs/isotp-c/README.mkd new file mode 100644 index 0000000..9803048 --- /dev/null +++ b/libs/isotp-c/README.mkd @@ -0,0 +1,142 @@ +ISO-TP (ISO 15765-2) Support Library in C +================================ + +This is a platform agnostic C library that implements the ISO 15765-2 (also +known as ISO-TP) protocol, which runs over a CAN bus. Quoting Wikipedia: + +>ISO 15765-2, or ISO-TP, is an international standard for sending data packets +>over a CAN-Bus. The protocol allows for the transport of messages that exceed +>the eight byte maximum payload of CAN frames. ISO-TP segments longer messages +>into multiple frames, adding metadata that allows the interpretation of +>individual frames and reassembly into a complete message packet by the +>recipient. It can carry up to 4095 bytes of payload per message packet. + +This library doesn't assume anything about the source of the ISO-TP messages or +the underlying interface to CAN. It uses dependency injection to give you +complete control. + +The current version supports *only single frame ISO-TP messages*. This is fine +for OBD-II diagnostic messages, for example, but this library needs some +additional work before it can support sending larger messages. + +## 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. + void send_can(const uint16_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 an IsoTpShims object to pass them around: + + IsoTpShims shims = isotp_init_shims(debug, send_can, set_timer); + +### API + +With your shims in hand, send an ISO-TP message: + + // Optional: This is your callback that will be called when the message is + // completely sent. If it was single frame (the only type supported right + // now), this will be called immediately. + void message_sent(const IsoTpMessage* message, const bool success) { + // You received the message! Do something with it. + } + + IsoTpSendHandle handle = isotp_send(&shims, 0x100, NULL, 0, message_sent); + + if(handle.completed) { + if(!handle.success) { + // something happened and it already failed - possibly we aren't able to + // send CAN messages + return; + } else { + // If the message fit in a single frame, it's already been sent + // and you're done + } + } else { + while(true) { + // Continue to read from CAN, passing off each message to the handle + // this will return true when the message is completely sent (which + // may take more than one call if it was multi frame and we're waiting + // on flow control responses from the receiver) + bool complete = isotp_continue_send(&shims, &handle, 0x100, data, size); + + if(complete && handle.completed) { + if(handle.success) { + // All frames of the message have now been sent, following + // whatever flow control feedback it got from the receiver + } else { + // the message was unable to be sent and we bailed - fatal + // error! + } + } + } + } + +Finally, receive an ISO-TP message: + + // Optional: This is your callback for when a complete ISO-TP message is + // received at the arbitration ID you specify. The completed message is + // also returned by isotp_continue_receive, which can sometimes be more + // useful since you have more context. + void message_received(const IsoTpMessage* message) { + } + + IsoTpReceiveHandle handle = isotp_receive(&shims, 0x100, message_received); + if(!handle.success) { + // something happened and it already failed - possibly we aren't able to + // send CAN messages + } else { + while(true) { + // Continue to read from CAN, passing off each message to the handle + IsoTpMessage message = isotp_continue_receive(&shims, &handle, 0x100, data, size); + + if(message.completed && handle.completed) { + if(handle.success) { + // A message has been received successfully + } else { + // Fatal error - we weren't able to receive a message and + // gave up trying. A message using flow control may have + // timed out. + } + } + } + } + +## 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 + +## Authors + +* Chris Peplin cpeplin@ford.com +* David Boll dboll2@ford.com (the inspiration for the library's API is from David) + +## License + +Copyright (c) 2013 Ford Motor Company + +Licensed under the BSD license.