SSM2 Benchmark – Serial vs. CAN

Purpose

Measuring maximum sampling speed.

SSM2 Request Content

SSM2 Address(es) Name
0x000008 Coolant Temperature
0x00000D Manifold Absolute Pressure
0x00000E
0x00000F
Engine Speed
0x000010 Vehicle Speed

→ 4 paramaters, 5 data bytes to request in total

Test conditions

  • Reading above five SSM2 addresses using a single ‘A8’ request message in a tight loop.
  • There’s no result data processing at all, except response packet validation (header and checksum). Of course this is unrealistic but this is meant for measuring maximum possible sampling speed.
  • Messages are being created on the fly by the (rather efficient) library code so they’re not being cached. Not caching the send-message should have negligible effect. Very likely native well optimized C++ code probably won’t be noticeably faster, especially on the slow serial protocol.
  • The benchmark program is a console application, preventing any GUI overhead. No progress output or anything within the loop.
  • Languages used were both F# and C# running on Linux (Mono 2.8.0) and Windows (Microsoft.NET 4.0)
  • Benchmark runtime: 60 seconds for each mode.
  • Car engine not running.
  • SSM2 via Serial: standard 4800 baud. Request message: 80 10 F0 11 A8 00 00 00 08 00 00 0D 00 00 0E 00 00 0F 00 00 10 7B
  • SSM2 via CAN (ISO 15765) : 500 kbit. Request message: 00 00 07 E0 A8 00 00 00 08 00 00 0D 00 00 0E 00 00 0F 00 00 10

Results

Tests were performed on a 2009 Forester 2.0 Turbo Diesel.
OBD-II interface used was Tactrix Openport 2.0 with latest firmware.

Protocol Response messages within 60 seconds runtime Samplerate [samples/second]
SSM2 via Serial 313 5.22
SSM2 via CAN 5991 99.85

→ CAN speed improvement = 5991/313 = 19.14 times faster.

Benchmarks written in C# vs. F# and running these on Linux vs. Windows did not make any performance difference which is good. Laptop (medium speed, dual core) never had maximum CPU utilization.
All response messages were valid, there haven’t been any errors as usual.

Benchmark Code F# Version

This is the non-optimized F# version. Results compared to well coded C# showed no performance differences.
Used libraries will be open-sourced in the future. Public APIs need improvement, for F# use cases in particular, we’re just lacking developers to get everything done.


#light

open System
open System.Collections.Generic
open Subaru
open Subaru.SSM2

type Benchmark (ipt : J2534.IPassThruV0404, device : Device) =

  member b.Run(mode : ConnectionMode, secondsToRun : int) =
    printfn "Benchmark ConnectionMode = %s | secondsToRun = %d" (mode.ToString()) secondsToRun  
    if secondsToRun < 0 || secondsToRun > 3600 then
      failwith "secondsToRun out of range"

    let mutable count = 0    
    use conn = Ssm2Connection.Create(ipt, mode, device)
    if not (conn.Open()) then
      failwith "Could not open connection!"
    else
      let addresses = [|0x8; 0xD; 0xE; 0xF; 0x10 |]        // int[] array
      
      let millisecondsToRun = int64(1000 * secondsToRun)
      let sw = System.Diagnostics.Stopwatch.StartNew()
      while sw.ElapsedMilliseconds < millisecondsToRun do
        addresses |> conn.ReadAddresses |> ignore
        count <- count + 1         
      sw.Stop()
    
      let sampleRate = float count / (0.001 * float sw.ElapsedMilliseconds)    
      printfn "Elapsed = %s | Count = %d | Samplerate = %f" (sw.Elapsed.ToString()) count sampleRate
    count

do
  Console.WriteLine("SSM2 Benchmark in F#")  
  let seconds = 60

  use passThruDevice = new J2534.Device.OpenPort20Dll()  
  let bm = new Benchmark(passThruDevice, Device.EngineControlUnit)
    // run shortly to JIT (just-in-time) compile any required code
  bm.Run(ConnectionMode.SSM2viaSerial, 1) |> ignore
  bm.Run(ConnectionMode.SSM2viaCAN, 1) |> ignore
    // now the real tests
  let countSerial = bm.Run(ConnectionMode.SSM2viaSerial, seconds)
  let countCan = bm.Run(ConnectionMode.SSM2viaCAN, seconds)
  
  let factor = float countCan / float countSerial
  printfn "CAN/Serial speed factor = %f" factor
  ()

Advertisements

4 responses to “SSM2 Benchmark – Serial vs. CAN

  1. Under
    Test conditions

    SSM2 via Serial: standard 4800 baud. Request message: 80 10 F0 11 A8 00 00 00 08 00 00 0D 00 00 0E 00 00 0F 00 00 10 7B

    Try changing byte 6 to 01 then re-evaluate logging speed.

    Like

    • Big thanks for this hint! That push mode is working on Euro4 diesels, too.

      With OP2.0 device, J2534 CONFIG P1_MAX up to 10 (5 ms) is giving me proper incoming msgs, does not work with default 40 (20 ms).

      No benchmark yet due to required coding. Oscilloscope log would be perfect to confirm timings…

      How about your experiences?

      I’ll be coding SSM2viaCAN-enable-RAM-logging patch soon, can’t look at EcuFlash’s to avoid any Cpyright.

      Still, better serial perf should be very useful for many users.

      Like

  2. SSM2 via CAN (ISO 15765) : 500 kbit. Request message: 00 00 07 E0 A8 00 00 00 08 00 00 0D 00 00 0E 00 00 0F 00 00 10 ????

    The request message have more than 8 data bytes , so ECU support multiframe ? or other proprietary data format ? this request message should be splitted into 2 differents CAN Frames with same ID Can addreess , can someone explain me ?

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s