NefMoto

Technical => Data Logging => Topic started by: Basano on April 28, 2014, 06:04:49 AM



Title: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: Basano on April 28, 2014, 06:04:49 AM
Whilst working on a ram logger for MED9.1, it struck me that it could also be useful to use VCDS to read ram locations as well. To be totally accurate, add ram locations to spare measuring blocks and then read these new measuring blocks with VCDS. I've posted some worked examples of exactly how to do this, but first a bit of background to explain.

Ram logging is my preferred option, but needs bespoke hardware and software. This alternative needs only VCDS and some changes to the MED9.1 bin. I wouldn't suggest changing every bin you work on! But it could help if you are looking at something non-standard or want a value that isn't already in the standard measuring blocks. YMMV.

You are making changes to your bin. Make sure you have a full backup (preferably BDM) before you start. Better yet, use a spare ecu. Also ensure that your flashing tool does a good job of checksums. If your ecu turns into a pumpkin, I am not responsible!

Background

In the MED9.1 bin, there are two tables relating to measuring blocks. In my flash, the first table is located at 0x001C 58C8 and consists of four columns. These are the four values you see in VCDS Measuring Blocks. The table doesn't contain actual values (it's flash after all), rather numerical pointers to a second table which has the flash memory addresses where the actual values are calculated.

The second table has just one column which contains the flash memory address of the assembly code that actually calculates the measured value. This second table is laid out in the same order as the section describing the internal ECU variables in the FR - Section 29.210.2 Testerkommunikation; Meßwerte lesen on page 4452. I've shown just the first ten entries of each table below. The full tables are in the attached spreadsheet. Also attached are a couple of pages from the FR showing what I'm talking about.

Table 1
VCDS Measuring Blocks
Table 4x255 KFMWNTK
Starts at address 0x001C 58C8


|Column|1|2|3|4|
|Start|0x001C 58C8|0x001C 5AC6|0x001C 5CC4|0x001C 5EC2|
|End|0x001C 5AC5|0x001C 5CC3|0x001C 5EC1|0x001C 60BF|
|Length|0x01FE|0x01FE|0x01FE|0x01FE|

|Measuring Block|1|2|3|4|
|0|0x0000|0x0000|0x0000|0x0000|
|1|0x0001|0x0050|0x001C|0x000D|
|2|0x0001|0x0002|0x0253|0x000A|
|3|0x0001|0x000A|0x0007|0x0009|
|4|0x0001|0x023B|0x0050|0x0055|
|5|0x0001|0x0002|0x0056|0x0057|
|6|0x0001|0x0002|0x0055|0x0044|
|7|0x0001|0x0002|0x0050|0x01F7|
|8|0x0000|0x0000|0x0000|0x0000|
|9|0x0472|0x0473|0x039A|0x0399|
|10|0x0001|0x0002|0x0007|0x0009|

Table 2
Internal ECU Variables
Table 1x2200
Starts at address 0x000A 7904


|Column|1|
|Start|0x000A 7904|
|End|0x000A 9B63|
|Length|0x2260|

|Decimal|Hex|1|
|0|0x0000|0x0003 931C|
|1|0x0001|0x0003 95B4|
|2|0x0002|0x0003 95C4|
|3|0x0003|0x0003 95D4|
|4|0x0004|0x0003 931C|
|5|0x0005|0x0003 931C|
|6|0x0006|0x0003 931C|
|7|0x0007|0x0003 95DC|
|8|0x0008|0x0003 95F8|
|9|0x0009|0x0003 9614|
|10|0x000A|0x0003 962C|

For example, let's say you read Measuring Block 3 with VCDS. From the VCDS label file 06F-907-115-AXX.lbl, you know that Measuring Block 3 contains:

003,1,Engine Speed
003,2,Intake Air Mass
003,3,Throttle Drive,Angle Sensor 1,for EPC (G187) | Display Range: 0...100 %
003,4,Ignition,Timing Angle

Looking at Table 1 in the MED9.1 bin, Measuring Block 3 looks like this:

3   0x0001   0x000A   0x0007   0x0009

This measuring block contains internal variables :

0x0001 (dec 1)
0x000A (dec 10)
0x0007 (dec 7)
0x0009 (dec 9)

Checking against the FR (Section 29.210.2 Testerkommunikation; Meßwerte lesen), you can see the correlation.

1 nmot (Motordrehzahl / Engine Speed)
10 mshfm_w (Luftmassenfluß / Air Mass Flow)
7 wdkba (Drosselklappenwinkel / Throttle Angle)
9 zwout (Zundwinkel / Firing Angle)

The second table, Table 2, points out the flash memory location of the code that calculates the internal variable:

0x0001 -> 0x0003 95B4
0x000A -> 0x0003 962C
0x0007 -> 0x0003 95DC
0x0009 -> 0x0003 9614

In the above example, Air Flow Mass 0x000A (dec 10) is calculated at 0x0003 962C:

Code:
ROM:0043962C                 lhz       r6, word_7FEE48
ROM:00439630                 cmplwi    r6, 0x3333
ROM:00439634                 bge       loc_439640
ROM:00439638                 mulli     r6, r6, 5
ROM:0043963C                 b         loc_439648
ROM:00439640 # ---------------------------------------------------------------------------
ROM:00439640
ROM:00439640 loc_439640:                             # CODE XREF: ROM:00439634j
ROM:00439640                 lis       r6, 0 # 0xFFFF
ROM:00439644                 ori       r6, r6, 0xFFFF # 0xFFFF
ROM:00439648
ROM:00439648 loc_439648:                             # CODE XREF: ROM:0043963Cj
ROM:00439648                 sth       r6, word_7FCD6E
ROM:0043964C                 extrwi    r5, r6, 8,16
ROM:00439650                 addi      r4, r6, 0
ROM:00439654                 li        r3, 0x19
ROM:00439658                 b         sub_43930C

The codes of interest for us are the first and last lines (lhz and b). The code starts by loading ram location 0x7FEE48. This is the actual ram location that contains the Air Mass Flow. The last line jumps back to the main code where the measuring blocks are processed by the various functions that output the Measuring Blocks when requested by VCDS.

You may have spotted that the flash memory location is 0x0003 962C, but the snippet from IDA starts at 0x0043 962C. That's just the way my IDA is configured and won't make a difference. All the address jumps are relative anyway.

IDA Settings
ROM @ 40 0000 size 20 0000
RAM @ 60 0000 size 30 0000
File at 40 0000 size 20 0000
TOC at 0x5C9FF0
SDA (r13) @ 0x7FFFF0


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: Basano on April 28, 2014, 06:06:14 AM
To make our own measuring blocks for ram locations we need a few things.

1) An unused entry in Table 1 to point to Table 2
2) An unused entry in Table 2 that can point to a flash memory location
3) A block of unused flash memory that can contain some assembly code
4) Some assembly code to pass the ram location we want to log to the various functions that handle the measuring blocks

Example 1 - Logging lambts_w (LambdaPartProtection) and lamfa_w (TargetAFRDriverRequest)
We've already worked out the ram locations of the above variables. I'm going to assume you can work this out yourself :)

lambts_w 0x802BFC
lamfa_w  0x802F7C

1) VCDS is already logging the Actual (lamsoni_w) and Specified (lamsbg_w) Lambda. In the VCDS label file, this is in Measuring Block 31 - Entries 1 and 2. Conveniently the 3rd and 4th entries are free, so we'll use these for our values.

031,1,Lambda Sensor,Current Value
031,2,Lambda Sensor,Specified Value

2) Look up this Measuring Block 31 in Table 1

31   0x002D   0x002B   0x0000   0x0000

3) Find some free entries in Table 2. Actual Lambda (lamsoni_w - 0x002D/45dec) and Specified Lambda (lamsbg_w - 0x002B/43dec) are in Table 2 already, so I picked some free pointers around that area. Free pointers is anything that points to flash memory location 0x0003 931C (the assembly at this location 0x0003 931C just sends 25 00 00 back to VCDS which means 'not used'). It's also handy to check against the FR to see that the pointers are not mentioned in the FR either. It doesn't matter, but it keeps it neat.

I've picked 36 and 37 in Table 2. The FR steps over these as well

34 fra2_w Lambda-Adaption fra (Bank 2)[0.5 ... 1.5] % 20 50 -50 ... <50 %
SY_STERVK=1
39 ushk_w Sondenspannung 1 hinter Kat Volt 66 10 0 ... 3.98 V

36   0x0024   0x0003 931C
37   0x0025   0x0003 931C

3) Find a free part of the flash. Free flash is normally a big block of FF FF FF FF FF FF FF FF ... In my flash, I've got unused space at 0x0007 C650. You could also check in IDA that there is no code or cross references in the area you think is free.

4) Now in this case I'm going to copy the assembly that's already used for Specified Lambda (lamsbg_w) since that will have the right scaling etc. So we just need to locate that assembly. Specified Lambda (lamsbg_w) is the second entry in Measuring Block 31 (0x002B/43dec). Looking up this entry (0x002B/43dec) in Table 2 gives me the flash memory location of the assembly code:
43   0x002B   0x0003 9A48

5) The assembly code at 0x0003 9A48:

Code:
ROM:00439A48 # ---------------------------------------------------------------------------
ROM:00439A48                 lhz       r5, word_7FCFE6
ROM:00439A4C                 srawi     r11, r5, 5
ROM:00439A50                 cmplwi    r11, 0xFF
ROM:00439A54                 bge       loc_439A60
ROM:00439A58                 srawi     r5, r5, 5
ROM:00439A5C                 b         loc_439A64
ROM:00439A60 # ---------------------------------------------------------------------------
ROM:00439A60
ROM:00439A60 loc_439A60:                             # CODE XREF: ROM:00439A54j
ROM:00439A60                 li        r5, 0xFF
ROM:00439A64
ROM:00439A64 loc_439A64:                             # CODE XREF: ROM:00439A5Cj
ROM:00439A64                 stb       r5, byte_7FC42F
ROM:00439A68                 li        r3, 0x1F
ROM:00439A6C                 li        r4, 0x14
ROM:00439A70                 b         sub_43930C

We'll copy this twice (once for lambts_w and again for lamfa_w) and substitute our own ram locations. Luckily we don't need to modify all this assembly! We're just interested in the first and last lines. The first line loads the ram variable and the last line jumps back to the main program that takes care of outputting the values to VCDS.

First line: lhz r5, word_7FCFE6
Last line: b sub_43930C

lhz
All the lhz references are relative to the SDA (r13) address (0x7FFFF0). You either add an offset for ram entries bigger than 0x7FFFF0 or subtract an offset for ram entries smaller than 0x7FFFF0. Negative numbers use two’s complement. Fortunately our two ram locations are both bigger than 0x7FFFF0 so we can just worry about positive numbers

lambts_w 0x802BFC
lamfa_w  0x802F7C

0x7FFFF0 + 0x2C0C = 0x802BFC
0x7FFFF0 + 0x2F8C = 0x802F7C

This works out to be
lhz r5, word_802BFC
A0 AD 2C 0C

and
lhz r5, word_802F7C
A0 AD 2F 8C

To get these opcodes (A0 AD 2C 0C and A0 AD 2F 8C), look at the attached MPCxxx Instruction Set. Look up the LHZ instruction. The last 16 bits are the offset (0x2C0C and 0x2F8C for our two variables respectively)

b
We need to branch back to 43930C, since that's where the main program is. However, all the branch instructions are relevant to our current address. Now that we've copied our code to 47C678/47C6A4, our current address where we jump back from will be different and we need to recalculate the branch instruction accordingly.

Current address 0x47C678/0x47C6A4 and we need to jump back to 0x43930C.
We need to subtract an offset from our current address. Two complement binary maths actually means we don't subtract, instead we add a negative number...

0x47C678 - 0x4336C = 0x43930C
0x47C678 + (-0x4336C) = 0x43930C
0x47C678 + 0xFFFBCC94 = 0x43930C

0x47C6A4 - 0x43398 = 0x43930C
0x47C6A4 + (-0x43398) = 0x43930C
0x47C6A4 + 0xFFFBCC68 = 0x43930C

This works out to be
b sub_43930C
4B FB CC 94
010010 111111101111001100100101 00

and
b sub_43930C
4B FB CC 68
010010 111111101111001100011010 00

To get these opcodes (4B FB CC 94 and 4B FB CC 68), look at the attached MPCxxx Instruction Set. Look up the B instruction. Bit 6 - 29 are the offset (0xFFFBCC94 and 0xFFFBCC68 for our two variables respectively).

I'm now going to work in hex since I found this easier. I'm sure there are other ways to go about this, this is just the approach I took.

Code we are going to copy:

Address        Opcode
0x00439A48 A0 AD CF F6
0x00439A4C 7C AB 2E 70
0x00439A50 28 0B 00 FF
0x00439A54 40 80 00 0C
0x00439A58 7C A5 2E 70
0x00439A5C 48 00 00 08
0x00439A60 38 A0 00 FF
0x00439A64 98 AD C4 3F
0x00439A68 38 60 00 1F
0x00439A6C 38 80 00 14
0x00439A70 4B FF F8 9C

Paste the copied code twice (x1 for lambts_w, x1 for lamfa_w) at the free space and modify the first and last lines of each copy

Address        Opcode
0x0047C650 A0 AD CF F6 first line A0 AD 2C 0C
0x0047C654 7C AB 2E 70
0x0047C658 28 0B 00 FF
0x0047C65C 40 80 00 0C
0x0047C660 7C A5 2E 70
0x0047C664 48 00 00 08
0x0047C668 38 A0 00 FF
0x0047C66C 98 AD C4 3F
0x0047C670 38 60 00 1F
0x0047C674 38 80 00 14
0x0047C678 4B FF F8 9C last line 4B FB CC 94
0x0047C67C A0 AD CF F6 first line A0 AD 2F 8C
0x0047C680 7C AB 2E 70
0x0047C684 28 0B 00 FF
0x0047C688 40 80 00 0C
0x0047C68C 7C A5 2E 70
0x0047C690 48 00 00 08
0x0047C694 38 A0 00 FF
0x0047C698 98 AD C4 3F
0x0047C69C 38 60 00 1F
0x0047C6A0 38 80 00 14
0x0047C6A4 4B FF F8 9C last line 4B FB CC 68

Now we need to apply all this to our bin. We need to change it in several places

1) The modified entries in Table 1
original
31   0x002D   0x002B   0x0000   0x0000
new
31   0x002D   0x002B   0x0024   0x0025
0x00 at 0x1C5D02
0x24 at 0x1C5D03
0x00 at 0x1C5F00
0x25 at 0x1C5F01

2) The modified entries in Table 2
original
36   0x0024   0x0003 931C
37   0x0025   0x0003 931C
new
36   0x0024   0x0007 C650
37   0x0025   0x0007 C678
0x00 at 0xA7994
0x07 at 0xA7995
0xC6 at 0xA7996
0x50 at 0xA7997
0x00 at 0xA7998
0x07 at 0xA7999
0xC6 at 0xA799A
0x78 at 0xA799B

3) The extra hex code at the free space 0x0007 C650
original
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
new
A0 AD 2F 8C 7C AB 2E 70 28 0B 00 FF 40 80 00 0C 7C A5 2E 70 48 00 00 08 38 A0 00 FF 98 AD C4 3F 38 60 00 1F 38 80 00 14 4B FB CC 94 A0 AD 2C 0C 7C AB 2E 70 28 0B 00 FF 40 80 00 0C 7C A5 2E 70 48 00 00 08 38 A0 00 FF 98 AD C4 3F 38 60 00 1F 38 80 00 14 4B FB CC 68

Then use a hex editor to paste this new hex into your bin.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: Basano on April 28, 2014, 06:07:28 AM
I recommend that you load this patched binary in IDA again and disassemble. Double-check that the new assembly jumps back to the correct place. You must get the branch back to the main program correct! If you get it wrong and it jumps back randomly, some very funny things could happen. You have been warned

Here I've loaded my modified bin back into IDA and disassembled again. Looks OK and the first and last lines are as I'd calculated.

Code:
ROM:0047C650 # ---------------------------------------------------------------------------
ROM:0047C650                 lhz       r5, word_802F7C
ROM:0047C654                 srawi     r11, r5, 5
ROM:0047C658                 cmplwi    r11, 0xFF
ROM:0047C65C                 bge       loc_47C668
ROM:0047C660                 srawi     r5, r5, 5
ROM:0047C664                 b         loc_47C66C
ROM:0047C668 # ---------------------------------------------------------------------------
ROM:0047C668
ROM:0047C668 loc_47C668:                             # CODE XREF: ROM:0047C65Cj
ROM:0047C668                 li        r5, 0xFF
ROM:0047C66C
ROM:0047C66C loc_47C66C:                             # CODE XREF: ROM:0047C664j
ROM:0047C66C                 stb       r5, byte_7FC42F
ROM:0047C670                 li        r3, 0x1F
ROM:0047C674                 li        r4, 0x14
ROM:0047C678                 b         sub_43930C
ROM:0047C67C # ---------------------------------------------------------------------------
ROM:0047C67C                 lhz       r5, word_802BFC
ROM:0047C680                 srawi     r11, r5, 5
ROM:0047C684                 cmplwi    r11, 0xFF
ROM:0047C688                 bge       loc_47C694
ROM:0047C68C                 srawi     r5, r5, 5
ROM:0047C690                 b         loc_47C698
ROM:0047C694 # ---------------------------------------------------------------------------
ROM:0047C694
ROM:0047C694 loc_47C694:                             # CODE XREF: ROM:0047C688j
ROM:0047C694                 li        r5, 0xFF
ROM:0047C698
ROM:0047C698 loc_47C698:                             # CODE XREF: ROM:0047C690j
ROM:0047C698                 stb       r5, byte_7FC42F
ROM:0047C69C                 li        r3, 0x1F
ROM:0047C6A0                 li        r4, 0x14
ROM:0047C6A4                 b         sub_43930C

The final thing we need to do is update the VCDS label file to add an entry for these new values. Open up the label file 06F-907-115-AXX.lbl and edit it to include the following.

031,0,Lambda Regulation (Constant Operation of Lambda Probes)
031,1,Lambda Sensor,Current Value
031,2,Lambda Sensor,Specified Value
031,3,TargetAFRDriverRequest
031,4,LambdaPartProtection

Here's what it looks like when you read the Measuring Block. You can see the new values that you have created (TargetAFRDriverRequest and LambdaPartProtection).

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=5941.0;attach=9182;image)

I've included a log where you can see the Lambda values. The Specified Lambda starts by following the Driver Requested Lambda and then changing to follow LamdaPartProtection.

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=5941.0;attach=9184;image)


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: Basano on April 28, 2014, 06:10:28 AM
Example 2 - Logging rl_w

What if you can't find a similarly scaled measuring block or you want the raw value? In this case, there's a useful item in the Measuring Blocks called 'count'. It's simply (a*256 +b). So if you want to monitor a 16 bit value, you can use this assembly:

Code:
ROM:00442AF0 # ---------------------------------------------------------------------------
ROM:00442AF0                 lhz       r5, word_80299C
ROM:00442AF4                 li        r3, 0x36
ROM:00442AF8                 srawi     r4, r5, 8
ROM:00442AFC                 b         sub_43930C

How did I derive this?

1) Look in the VCDS label file for anything called 'count'. For example:

085,4,Ignition Cycle,Counter

2) Find this entry in Table 1 (it's the 4th column - 0x05F0)

85   0x05ED   0x05EE   0x05EF   0x05F0

3) Look up this pointer (0x05F0) in Table 2. This gives me the flash memory location (0x0004 2AF0)

1520   0x05F0   0x0004 2AF0

4) We know that this assembly is just going to do this (a*256 +b) and send it out. So we'll be able to copy / paste the assembly at 0x0004 2AF0 into an unused part of the flash and modify it to read the ram location you are interested in.

In this example I'm going to log rl_w. I know it's a 16 bit value, but I can't really spot an existing similar measuring block that would already have the correct scaling. I'm going to output the raw value and process it later in Excel. This is straightforward since the scaling values are already present in WinOLS. Find a map with load (e.g. KFMIRL), right click to look at the properties and the scaling is right there (0.023438).

Just like in the first example, I've already looked up the ram location containing rl_w (0x7FEE58)

1) Find a free measuring block entry in Table 1. In this case, it looks like the whole of Measuring Block 8 is free, so we'll use the first entry in that.

8   0x0000   0x0000   0x0000   0x0000

2) Pick an unused pointer from Table 2. Unused is anything pointing to 0x0003 931C (the assembly at this location 0x0003 931C just sends 25 00 00 back to VCDS which means 'not used'). I've decide to use 11 since it is free in both Table 2 and also the FR. The FR steps right over it:

10 mshfm_w Luftmassenfluß SY_HFM>0 g/s 25 var 0 ... 364 g/s
13 XXXXXXXX Flagregister: Bits 16 FFh

11   0x000B   0x0003 931C

3) Find a free part of the flash. Free flash is normally FF FF FF FF FF FF FF FF ...In my flash, I've got unused space at 0x0007 C6A8. You could also check in IDA that there is no code or cross references in the area you think is free.

4) As explained before, I'll copy the assembly used for the 'count' function and modify it to use my ram location of rl_w (0x7FEE58)

Code:
ROM:00442AF0 # ---------------------------------------------------------------------------
ROM:00442AF0                 lhz       r5, word_80299C
ROM:00442AF4                 li        r3, 0x36
ROM:00442AF8                 srawi     r4, r5, 8
ROM:00442AFC                 b         sub_43930C

Same as before, we'll need to modify the first and last lines.

First line: lhz r5, r5, word_80299C
Last line: b sub_43930C

lhz
All the lhz references are relative to the SDA (r13) address (0x7FFFF0). You either add an offset for ram entries bigger than 0x7FFFF0 or subtract an offset for ram entries smaller than 0x7FFFF0. This time we are subtracting so we'll need to calculate the two's complement value

rl_w 0x7FEE58

0x7FFFF0  - 0x1198 = 0x7FEE58
0x7FFFF0  + (-0x1198) = 0x7FEE58
0x7FFFF0  + 0xFFFFEE68 = 0x7FEE58

This works out to be
lhz r5, word_7FEE58
A0 AD EE 68

To get this opcode (A0 AD EE 68), look at the attached MPCxxx Instruction Set. Look up the LHZ instruction. The last 16 bits are the offset (0xFFFFEE68 for our variable)

b
We need to branch back to 43930C, since that's where the main program is. However, all the branch instructions are relevant to our current address. Now that we've copied our code to 47C6B4, our current address where we jump back from will be different and we need to recalculate the branch instruction accordingly.

Current address 0x47C6B4 and we need to jump back to 0x43930C.
We need to subtract an offset from our current address. Two complement binary maths actually means we don't subtract, instead we add a negative number...

0x47C6B4 - 0x433A8 = 0x43930C
0x47C6B4 + (-0x433A8) = 0x43930C
0x47C6B4 + 0xFFFBCC58= 0x43930C

This works out to be
b sub_43930C
4B FB CC 58
010010 111111101111001100010110 00

To get this opcode (4B FB CC 58), look at the attached MPCxxx Instruction Set. Look up the B instruction. Bit 6 - 29 the offset (0xFFFBCC58 for our variable)

Code we are going to copy:

Address        Opcode
00442AF0 A0 AD 29 AC
00442AF4 38 60 00 36
00442AF8 7C A4 46 70
00442AFC 4B FF 68 10

Paste the copied code at the free space and modify the first and last lines

Address        Opcode
0x0047C6A8 A0 AD 29 AC first line A0 AD EE 68
0x0047C6AC 38 60 00 36
0x0047C6B0 7C A4 46 70
0x0047C6B4 4B FF 68 10 last line 4B FB CC 58

Now we need to apply all this to our bin. We need to change it in several places

1) The modified entries in Table 1
original
8   0x0000   0x0000   0x0000   0x0000
new
8   0x000B   0x0000   0x0000   0x0000
0x00 at 0x1C58D8
0x0B at 0x1C58D9

2) The modified entries in Table 2
original
11   0x000B   0x0003 931C
new
11   0x000B   0x0007 C6A8
0x00 at 0xA7930
0x07 at 0xA7931
0xC6 at 0xA7932
0xA8 at 0xA7933

3) The extra hex code at the free space 0x0007 C6A8
original
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
new
A0 AD EE 68 38 60 00 36 7C A4 46 70 4B FB CC 58

Then use a hex editor to paste this new hex into your bin.

I recommend that you load this patched binary in IDA again and disassemble. Double-check that the new assembly jumps back to the correct place. You must get the branch back to the main program correct! If you get it wrong and it jumps back randomly, some very funny things could happen. You have been warned

Here I've loaded my modified bin back into IDA and disassembled again. Looks OK and the first and last lines are as I'd calculated.

Code:
ROM:0047C6A8 # ---------------------------------------------------------------------------
ROM:0047C6A8                 lhz       r5, word_7FEE58
ROM:0047C6AC                 li        r3, 0x36
ROM:0047C6B0                 srawi     r4, r5, 8
ROM:0047C6B4                 b         sub_43930C

Again, the final thing we need to do is update the VCDS label file to add an entry for these new values. Open up the label file 06F-907-115-AXX.lbl and edit it to include the following.

008,1,Engine Load (rl_w)

Here's what it looks like when you read the Measuring Block. You can see the new values that you have created (Engine Load (rl_w)).

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=5941.0;attach=9186)

I've also included a log where you can see the standard Engine Load entry that is capped at 191.7%. Our new Engine Load entry that we have created now passes this ceiling and gives us the actual load (just remember to scale it by 0.023438).

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=5941.0;attach=9188)


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: ddillenger on April 28, 2014, 09:14:34 AM
This is excellent.

Would you be willing to share your IDA project? Feel free to say no. No pressure here.


Title: Re: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: technic on April 28, 2014, 09:18:58 AM
Although I haven't digged in to it yet, I can just say : Wow! Amazing writeup.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: Beaviz on April 28, 2014, 09:24:52 AM
Amazing writeup! Will definitely be looking more into the details the next couple of days.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: TCSTigersClaw on April 28, 2014, 10:05:53 AM
Applaud ! Great work ! thank you  :)


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: prj on April 28, 2014, 01:28:10 PM
I love it. Give you a little bone and lots of good things come out of it.
Well done, very well done indeed! Keep it up!


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: Basano on April 29, 2014, 06:11:51 AM
Would you be willing to share your IDA project? Feel free to say no. No pressure here.

Yes, of course! I've attached the IDB files to the first post.

All, thank you for your encouraging words :) Hopefully this can be of use for all (make it a sticky if you think it's worthy)


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: BenR on May 19, 2014, 06:04:28 AM
This is amazing work! Well done, absolutely excellent!


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: Nottingham on July 07, 2014, 03:22:26 AM
Super job here Basano, however regarding your share .idb projects...
Could you please check the version as it appears to be blacklisted and therefore your projects cannot be opened.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: dream3R on July 07, 2014, 04:59:49 AM
Keep up the good work, very interesting reading :)

The file you asked for was found on this forum when I searched (someone sent me it though)

http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=1085.0;attach=2764

HTH


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: Basano on July 07, 2014, 07:22:09 AM
Super job here Basano, however regarding your share .idb projects...
Could you please check the version as it appears to be blacklisted and therefore your projects cannot be opened.
I had a look at the IDA version - it's 6.1

I run it in it's own little vitual machine (using Oracle VM Virtual Box).

If necessary, I can always post up the bin plus my IDA settings (SDA, TOC, ROM and RAM) and if you disassemble in another version it should come out the same.

Keep up the good work, very interesting reading :)

The file you asked for was found on this forum when I searched (someone sent me it though)

http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=1085.0;attach=2764

HTH
Thanks  ;D


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: de_Fre on October 26, 2014, 01:53:48 AM
Putting my first steps in Assembly / Disassembly.

I used the steps provided by Basano, above, to find the raw variable for engine load. Then I made a little function that scales the Engine Load. It is pretty accurate, and allows to log above 191,7%

This was made for software version 1K0907115K , 0261S02332 , 386821

7FEDE9 is the raw variable for Engine Load in my software version, and the free space i used was at position 0x7c710

ROM:0047C710                 lhz       r5, word_7FEDE9
ROM:0047C714                 srawi     r5, r5, 5
ROM:0047C718                 srawi     r4, r5, 1
ROM:0047C71C                 add       r5, r5, r4
ROM:0047C720                 srawi     r5, r5, 1
ROM:0047C724                 li        r3, 0x36 # '6'
ROM:0047C728                 srawi     r4, r5, 8
ROM:0047C72C                 b         sub_43930C

Code in Hex

A0AD   EDF9   7CA5   2E70   7CA4   0E70   7CA5   2214   7CA5   0E70   3860   0036   7CA4   4670   4BFB   CBE0


Thx Basano for the good info on here.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: Tatan974 on September 22, 2015, 08:36:39 AM
.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: AleS3 on May 02, 2016, 11:16:15 AM
Hi guys,
thanks to Basano that made wonderful guides about MED9 disassembling i started playing with IDA and managed to add measuring blocks with VCDS....BUT i can't log and see then cause i have the encrypted .CLB label file and i don't manage to read and update the label file....
How can i sort it out??...i tried to convert the file with SVCdec.exe but it doesn't work :(
I attach the label file, the car is an S3 with CDLA engine...


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: AleS3 on May 02, 2016, 01:01:13 PM
Solved with converted file...


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: dream3R on May 02, 2016, 06:12:20 PM
how did you convert it?  You're generally expected to share here matey :)   

edit: Ah it's me7 from the code lol


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: AleS3 on May 02, 2016, 11:29:02 PM
how did you convert it?  You're generally expected to share here matey :)  

edit: Ah it's me7 from the code lol
You are right mate, i thought nobody care about it.
I found a lbl converted file database on web, i deleted the old .clb from label folder and replaced with the edited .lbl and it works well!
Next step will be try to switch map without reflashing..


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: dream3R on May 03, 2016, 12:16:07 AM
least the set of labels on UDS cars are given if asked LOL


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: przemek4net on January 19, 2018, 05:08:42 AM
Hi,
I start to play with IDA and I get such problem.
As pattern I used “procedure” for RPM reading (in my case variable in the 2nd table “1” / 2nd position in this table)
This “procedure” reads RPM, store in R5, call “43960” (which store r3, r4, r5 in some place in memory – probably used in communication ECU -> OBD -> VCDS)
So I wanted to make some “counter” based on some place in memory like:
-   Read memory to the register r5
-   Add +1 (delta)
-   Store r5 in the memory
Like 0,1,2…. 245, 255, 0,1…255 (*40 factor)
That is my code
(https://images82.fotosik.pl/969/8bb9ef35c5690709med.jpg) (https://www.fotosik.pl/zdjecie/8bb9ef35c5690709)
But… when I use this code (also with delta 0!) – I get “error group not available”
When I change instruction stb to lbz (instead of write - read again – just to keep order/addresses of instructions and avoid playing with offset for b instruction)… it works fine (value in memory 129 => 5180 rpm; 130 -> 5200 rpm – factor seems to be 40)
2nd problem: in Winols my memory cell is at 1C708 … that is the beginning of bin /probably some code :D/… I would like to have it for example at 1CC708 – could y help me with calculation “offset” for b instruction?
(https://images82.fotosik.pl/969/fe1b6593ee4bfe03med.jpg) (https://www.fotosik.pl/zdjecie/fe1b6593ee4bfe03)

Why it crash when I process stb (with the same value as original – in r3 is 0)  - because it is logical part ROM and processor protect writing of this part of memory???
Soft 8E0907115C
0261S02145
387403
Ecu without the car (vcds connected on bench)... I suppose it is 2.0tfsi (bought for playing)


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: jezTT on March 23, 2018, 10:49:04 AM
I created a spreadsheet that allows custom tables of measuring blocks specific from a binary, and thought I'd share it as a small thanks for the information in this thread.

I spent many hours going about things the wrong way to try and define my measuring blocks, and made this spreadsheet after I figured out an accurate way to go about it. Hopefully others will get some use out of it and it saves some headaches  :D

It's for Med9 but is fully editable, so may be able to be adapted for use with other ecus.

v1.1 - Tidied sheets up, clarified instructions.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: heromanni on October 07, 2020, 01:20:47 AM
Hello, are people using this method to tune med9 ecus?

Just wondering, Is there now in 2020 any alternative methods for med9 logging affordable for a hobbyist?



Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: prj on October 07, 2020, 12:52:42 PM
You can use this method and then generate (or make by hand) a label file for VCDS.
Like that you can log 12 ram cells at a time.

That's the best you are gonna get as a "hobbyist".


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: aef on October 08, 2020, 03:04:37 AM
Hello, are people using this method to tune med9 ecus?

Just wondering, Is there now in 2020 any alternative methods for med9 logging affordable for a hobbyist?



http://nefariousmotorsports.com/forum/index.php?action=profile;u=8081

he sells a logger


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: eliotroyano on November 30, 2020, 04:16:57 PM
Hi friends, sorry about my dumb question? what fields of the measuring blocks should I add to log the ram variable of clutch pedal and brake pedal "flags"? I have look at 193 and 720 according to FR but it does match ram variable tables I have seen. If someone can enlight me I will appreciate it.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: prj on February 17, 2021, 01:58:52 PM
Don't want to do shameless promotion, but I am releasing MED9 full ram logging next week, which will make all of this somewhat obsolete... well of course this is free, and my logger isn't :)

EDIT: URL, because i've been asked
https://docs.vehical.net/logger/help (https://docs.vehical.net/logger/help)


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: Dmitrii-VR6T on March 19, 2021, 11:36:09 PM
Don't want to do shameless promotion, but I am releasing MED9 full ram logging next week, which will make all of this somewhat obsolete... well of course this is free, and my logger isn't :)

EDIT: URL, because i've been asked
https://docs.vehical.net/logger/help (https://docs.vehical.net/logger/help)

Does this tool support only MED17 ecu? I don't see MED9 ecu in the supported ecu list.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: prj on March 20, 2021, 11:35:37 AM
Does this tool support only MED17 ecu? I don't see MED9 ecu in the supported ecu list.
Works just fine with MED9, I forgot to add to the list on the website.
I edited it now.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: Markus01 on April 15, 2023, 02:20:48 PM
Hello,

this is a great guide. Thank you for this. I need it for Med9.1.2 from Audi RS3. Can you help me with this? Thank you very much. reagards Markus


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: prj on April 22, 2023, 02:15:47 AM
Hello,

this is a great guide. Thank you for this. I need it for Med9.1.2 from Audi RS3. Can you help me with this? Thank you very much. reagards Markus
The first post contains all the info needed to do it. This is a DIY forum, nobody is going anything for you.
If you can't do it based on what is listed in the first post, pay the 100 EUR and use my logger instead: https://docs.vehical.net/logger_getting_started (https://docs.vehical.net/logger_getting_started).


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: elias on April 23, 2023, 08:19:58 AM
You could use my tool to read Ram of a MED9.1, which basically contains the values:
https://github.com/EliasKotlyar/MED9RamReader

It should also work for other ECU like 9.1.1 with slight modifications(SA2 Challenge), however i havent tested it



Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: prj on April 23, 2023, 09:53:16 AM
Seed-key is not needed to read memory on MED9.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: lgtmelo on February 27, 2024, 07:07:58 AM
if i want to log something thats already in the FR, such as misol_w (number 22), do i need to do something on table 2? or just insert 22 dec in a blank space in table 1?

thanks :)


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: prj on February 27, 2024, 10:59:46 AM
Putting it there is enough, I recommend using my logger though.
Or if you have the a2l and like hacking python, then you can use what is posted by elias here.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: lgtmelo on February 27, 2024, 11:38:27 AM
i got your log this week, it didnt have the patch ready and asked me to mail the output, which pointed to an A2L D91157_51C3. i just didnt do it yet :D


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: prj on February 27, 2024, 12:12:46 PM
There's no patch, most likely no def on server and full read needed to add it.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: lgtmelo on February 27, 2024, 12:44:47 PM
There's no patch, most likely no def on server and full read needed to add it.

all i got is the mpps read.


Title: Re: MED9.1 Create your own Measuring Blocks and log RAM locations with VCDS
Post by: prj on February 27, 2024, 12:48:41 PM
all i got is the mpps read.
Your ECU is 2.5mb so that's useless as MPPS only reads the flash.
This is also why you can't load your binary into Ghidra btw. You're missing almost all the code.

The full file can be converted from sgo or read out via bench or BDM.