map reversing

Developer topics relating to software that provides a tuning UI to alter ECU code and data

Moderator: Freon

map reversing

Postby letsteyr » Tue Nov 13, 2007 10:29 am

hi, i would like to know who's working on map reversing so as to re-create tables? I'm working on the A8DH200Z (STI 2006 euro version) and created more than 50 new tables (3D and 2D). The only one difficulty is to find the good coefficient to give a sense to all numbers.

So can someone help me to find other tables to to explain those i found?

Did people who created tables (engenuity/ecuflash) find all of them (important one)? Are they still searching them?

Thanks.Math
letsteyr
 
Posts: 43
Joined: Wed Jan 31, 2007 4:32 am

Postby Freon » Tue Nov 13, 2007 11:58 am

Merchgod on Enguinity forums has been doing a lot of this work. Enguinity is down right now, but when it comes back up you should download the latest definitions and see what maps it supports for your ECU ID. If it is not supported, you can upload your ROM to the forum and request it be added in the next update. He's been pretty awesome keeping everything up to date.

For the 32bit ECUs, the row and columns are almost always full floating point precise and there is no coefficient to transform the floating point value to the unit of measure the ECU uses. Now, sometimes this unit of measure is not what you would want to use. I.e. air pressure is always in mmHG absolute pressure, but you might want to see it as bar or psi gauge, which would require a transform or coefficient.

The data is almost always stored in 8bit or 16bit integer, and does require a coefficient or simple transform to convert to an appropriate unit of measure. There is a coefficient and an offset (to build form y = Ax + B where A is the coefficient, x is the 8bit or 16bit integer, and B is the offset). These are defined for most maps in an area of the ECU that defines all the 2D and 3D maps in the ECU.

The form for a 3D map is like this:

0x000C - number of columns (0x0C would be 12 columns)
0x0005 - number of rows
0x000C954C - start of column headers
0x000C955C - start of row headers
0x000C958C - start of data
0x08000000 - type byte for data (defines if data is 16bit or 8bit)
0x3F800000 - Coefficient to multiply against data
0x40C00000 - Offset to add to data

I'm writing the above off the top of my head, but that should be close enough for you to get the idea. 2D maps are essentially the same, except there is no reference to rows, thus the map definition is shorter.

There are some maps that do not include a coefficient and offset. These are either not native unit of measurement maps, or they have to be figured out by disassembly.

Let's say you find what looks like a 3D map at 0x054000. You'd want to search for the actual hex 54000. You should see a form like above around it.

Remember, all the map definitions are clumped together in the ROM, so they're not hard to find.
Freon
 
Posts: 700
Joined: Thu Nov 17, 2005 5:50 pm
Location: Indianapolis, IN

Postby letsteyr » Tue Nov 13, 2007 1:42 pm

Thanks, i've got the last defs from engenuity (and ecuflash) for my rom i think (i often update them).Here are the number of maps i got:

- boost: 10 maps
- wastegate: 9 maps
- turbo dynamics: 12 maps
- fuel: 15 maps
- timing: 14 maps
- knock: 9 maps
- Maf: 5 maps
- Misc: 8 maps
- idle: 3 maps
- closed loop: 8 maps
- many DTC

but i recreated more than 50 other one whitout meaning.

So did they release complete defs for some ecus (recovering all data)? Because when i edit the .bin, a lot of data is not discovered (around 0.5% discovered via the defs)

About recreating tables, i used what you said and had no special difficulty. There are also maps which are full floating point. I just want to known if someone knew the meaning of the maps i found.

For exemple, i have maps with big numbers as data (from 10000 to 40000 or around it). I've got maps with high numbers reaching 17000........I put 2 exemples below to illustrate:

Image

what's more, i'm not sure i've very well understood were the maps are defined by the ecu: different maps are following one each other as you said but i don't see where the offset and coefficient are set for each one of them in the .bin.

Thank you freon.Math
letsteyr
 
Posts: 43
Joined: Wed Jan 31, 2007 4:32 am

Postby letsteyr » Tue Nov 13, 2007 2:19 pm

Oh yes, i've found in the .bin where the map defines some of the tables.Thanks, i can go on looking for them now.
letsteyr
 
Posts: 43
Joined: Wed Jan 31, 2007 4:32 am

Postby letsteyr » Tue Nov 13, 2007 4:02 pm

could you tell me the type of data for float/16bit/8bit data?

cause i've found 0800 0000, 0400 0000? Is 0000 0000 32bit?

Thanks
letsteyr
 
Posts: 43
Joined: Wed Jan 31, 2007 4:32 am

Postby letsteyr » Wed Nov 21, 2007 11:51 am

ok so 8000000 is for 16bit and 40000000 for 8bit. However, I found all the maps i think but the most difficult remains to guess their meaning. Did some of you try to reverse all the code which means not only the maps but everything?
letsteyr
 
Posts: 43
Joined: Wed Jan 31, 2007 4:32 am

Postby Freon » Thu Nov 22, 2007 2:05 pm

There are a handful of people who actively disassemble the code. Obviously, a lot more can be learned by doing that. It is very time consuming since any knowledge has to be gleamed by looking at the raw, uncommented assembly.
Freon
 
Posts: 700
Joined: Thu Nov 17, 2005 5:50 pm
Location: Indianapolis, IN

Postby letsteyr » Sun Nov 25, 2007 3:44 pm

Yes i suppose it's very very long, a very hard work. And do you know if other ecu (8bit or else on other cars) have other specific methods to define MAPS (another method different of the one you described)?

Cause i'm trying to find maps in this kind of code (8bit decimal here)


Image

apparently, a map sounds like:

- it starts with "155"
- then there's the number of colomn
- then there are "N°col-1" values
- then 131 or 96
- then 160 or 166
- then there's the number of rows
- then there are "N°row-1" values
- then 251 or 116
- then the data

but i don't guess more. Thanks for your ideas
letsteyr
 
Posts: 43
Joined: Wed Jan 31, 2007 4:32 am

Postby Freon » Sun Nov 25, 2007 7:09 pm

The map data (the column header) will almost always start at a longword boundary. For example 0x0C00 and 0x0C04 are ok, but 0x0C01 or 0x0C02 are not valid starting locations for map data. Sometimes there is a pad at the end of the maps before the next map begins to make sure this happens. It will always be h'FF, all bits set high.

From there, it's pretty much always

column header
row header
data

for 3D maps

or

row header
data

for 2D maps

There is nothing between the three elements. It's straight up data. The definitions are always elsewhere in the ROM. I don't think there are ever pads between the three elements of map data. Especially with the 32bit ECU, the row and column headers are 4byte floating point anyway, so they wouldn't end on "odd" boundaries.

I'm not 100% sure if the 16bit HC16 ECU follows longword or just word boundaries. Either way, this has to do with how fast the CPU can address the ROM, so in general they follow the

Since you can see the data, you can infer how many elements there will be in the column and row headers. That map looks like 14 columns by 12 rows. The 12 elements immediately before the data could be 1, 2, or 4 byte (floating point), then the 14 before that would be the column header.

I can't say I immediately recognize the headers in the screenshot you posted.

I really don't know about other ECUs... It's probably going to vary some. What ROM is that? Is that a Subaru? HC16 or SH2?

I really recommend you download the software manual and datasheet for the CPU you are working on. They're generally available online.

I have the SH-2 manuals here:
http://freon.shackspace.com/car/ecu%20a ... %20manuals
There is a software manual with the instruction set, and two hardware manuals. 7055 and 7058 are largely the same besides the 7058 having slightly more RAM and double the flash ROM capacity (1MB vs. 512kB)

I really only have been concentrating on the SH-2 models.
Freon
 
Posts: 700
Joined: Thu Nov 17, 2005 5:50 pm
Location: Indianapolis, IN

Postby letsteyr » Mon Nov 26, 2007 1:14 pm

i've found the method, that's ok, it's a bosch description. for exemple, there's:

155/14/4/2/15/15/13/7/13/12/10/10/10/10/10/20/96

155 says at the ecu the kind of information it is
14 says the n° of colomns
4/2/15/15/13/7/13/12/10/10/10/10/10/20/96 are the colomns values


to find colmns values:
col 14 = 256 - 96 = 160
col 13 = col14 - 20 = 140
col 12 = col13 - 10 = 130
col 11 = col10 - 10 = 120
......
col 2 = col3 - 2 = 23
col 1 = col2 - 4 = 19

it'was hard !!! i hope it will help other people.


freon, thank you for your help, you got a lot of knwoledge. thanks for sharing it. I have other question (interesting). i would like to know the links beeteween the parameters and physical values.........for example:

- AFR:
for subarus, AFR = 14.7/ (1+ value)*.0078125
why 0.0078125 ? what are the orginal values (unit) we got in afr tables? It's an enrechiment comparing to 14.7? (0 for 14.7)?

- advance:
for subarus we got advance = ([value]*.3515625)-20
why 20 and 0.3515625? what's the original unit of mesure? What do we physically get?

- RPM:
what's the link beeteween the number of teeth of the flywheel and the rpm we get? With what unit does the ecu work?

thanks.Math
letsteyr
 
Posts: 43
Joined: Wed Jan 31, 2007 4:32 am

Postby Freon » Tue Nov 27, 2007 9:22 am

letsteyr wrote:- AFR:
for subarus, AFR = 14.7/ (1+ value)*.0078125
why 0.0078125 ? what are the orginal values (unit) we got in afr tables? It's an enrechiment comparing to 14.7? (0 for 14.7)?

The 0.078125 is because the value is stored as a single byte, 8bit integer. So the values for X are 0, 1, 2... 254, 255. 127 would be 1.0 Lambda, or no enrichment. A value of 191 would be an enrichment factory of 1.5, or 9.8 AFR. Basically, the conversion equation you see in the def is converting the integer value stored by the ECU back into what we guess (or imply, or know from other disassembly of how the value is actually used later) the actual unit of measure is meant to be. Realistically, everything in the ECU is actually in lambda, not AFR. "14.7" is pretty much nowhere in the ECU at all, but "0.0078125" certainly is.

Same goes for the logger. When the logger asks the ECU for the O2 sensor reading and it sends back the integer value 127 (or 0x7F in hex), your logger will show you 14.7 due to this conversion equation. These conversion equations vary.
- advance:
for subarus we got advance = ([value]*.3515625)-20
why 20 and 0.3515625? what's the original unit of mesure? What do we physically get?

Same deal here. It is the conversion factory for how the ignition timing is converted to be stored into a single byte, 8bit integer value. So with valid values for [value] from 0 to 255, you can set from -20 to +69 (BTDC) with a precision of 0.3515625. Ignition timing is always degrees before top dead center (*BTDC).

I know that internally, some of the ECUs actually only allow -20 to +60. But, at least that equation would technically allow +69 even if it is clipped to +60 later in the code. In the DBW ECU, the map is read, it is clipped from -20 to +60, compensations are applied, then it is clipped from -20 to +60 AGAIN, more compensations are applied, it gets clipped again... Don't ask me why, but really, you won't need to go further than 0 to +50 anyway.
- RPM:
what's the link beeteween the number of teeth of the flywheel and the rpm we get? With what unit does the ecu work?

The ECU uses RPM for almost everything. It is easily the most common parameter used throughout the ECU. It must derive this from the crank position sensor somehow. I have never spent too much time looking into this, but there has to be some input pin on the ECU getting the signal and counting teeth and dividing by time. You'd have to look at your crank position sensor and wheel to determine this. I know on Subaru's it is an odd sort of spacing for the teeth on the crank position wheel. I'd guess the teeth literally trigger a hardware interrupt in the ECU, or possibly there are other electronics on the mainboard to handle this. Again, just guesses, as I don't have any real reason to spend time researching exactly how it is handled.

I can say it seems the ECU gets a value in the unit of meaure of RPM and uses that throughout the code. Your Bosch may be different, but at least the HC16 and SH-2 do this.
Freon
 
Posts: 700
Joined: Thu Nov 17, 2005 5:50 pm
Location: Indianapolis, IN

Postby Jon [in CT] » Wed Nov 28, 2007 5:47 pm

Freon wrote:
letsteyr wrote:- AFR:
for subarus, AFR = 14.7/ (1+ value)*.0078125
why 0.0078125 ? what are the orginal values (unit) we got in afr tables? It's an enrechiment comparing to 14.7? (0 for 14.7)?

The 0.078125 is because the value is stored as a single byte, 8bit integer. So the values for X are 0, 1, 2... 254, 255. 127 would be 1.0 Lambda, or no enrichment. A value of 191 would be an enrichment factory of 1.5, or 9.8 AFR. Basically, the conversion equation you see in the def is converting the integer value stored by the ECU back into what we guess (or imply, or know from other disassembly of how the value is actually used later) the actual unit of measure is meant to be. Realistically, everything in the ECU is actually in lambda, not AFR. "14.7" is pretty much nowhere in the ECU at all, but "0.0078125" certainly is.

First, letsteyr's statement of the AFR conversion is incorrect. It should be: AFR = 14.7/ (1+ (value*.0078125)). Second, Freon's interpretation of the values stored in open loop fuel enrichment tables is wrong, too.

The first step to understanding where the multiplier "0.0078125" comes from is to recognize that it is equivalent to dividing by 128. This division can be accomplished very efficiently, even by a processor which doesn't support a 'divide' instruction, by means of a shift instruction which sends the seven least significant binary digits to the bit bucket.

Now, let's suppose the raw value in an open loop fuel enrichment table is 32. Multiplying it by 0.0078125 yields a decimal value of 0.25, which implies that 25% more fuel than stoichiometric should be injected. If one adds 0.25 to 1.0 then the result is a fuel/air equivalence ratio (aka, excess fuel factor), which is the inverse of an air/fuel equivalence ratio (aka, lambda).
Freon wrote:
letsteyr wrote:- advance:
for subarus we got advance = ([value]*.3515625)-20
why 20 and 0.3515625? what's the original unit of mesure? What do we physically get?

Same deal here. It is the conversion factory for how the ignition timing is converted to be stored into a single byte, 8bit integer value. So with valid values for [value] from 0 to 255, you can set from -20 to +69 (BTDC) with a precision of 0.3515625. Ignition timing is always degrees before top dead center (*BTDC).
To address the question, "Why 0.3515625?", imagine that the arc of a complete circle is divided into 1024 equal segments instead of the "normal" 360 one-degree segments. To convert that unit into degrees, one would divide by 1024 and then multiply by 360. It turns out that 360/1024 = 0.3515625. To address the question "Why -20?", I have no idea and am very suspicious about this value. It implies that the base ignition advance table values are all relative to 20 degrees After Top Dead Center (ATDC). This makes no sense for a production car ECU. Why would FHI engineers wish to allow the spark to fire AFTER top dead center?

BTW. does anyone else have the impression that the XML scaling values, wherever possible, were selected to obfuscate, rather than illuminate, the underlying units? I see no other reason and I feel this "strategy" is the diametric opposite of what one would hope for in an open ECU project.
Jon [in CT]
 
Posts: 352
Joined: Sat Jan 01, 2005 10:23 am

Postby letsteyr » Thu Nov 29, 2007 2:17 am

oh yes sorry, sorry for the mistake in the conversion of the afr. I have understood the afr now.

And then, how does the ecu converts AFR to injector pulse?

It knows the flows of air entering in the inlet pipe.......with the fuel table it knows what has to be the flow of fuel (using scaling injector too).......but many cylinders may have inlet valves opened in same time no? So what's the accurate conversion? I ask that because other manufacturers use injection timing in their fuel table.



I got another question too. Some cars don't use a MAF. For subarus the load = (RPM/MAf)/4 in g/rev
But for other cars, fuel tables have the throttle position as a scaling? How can it be accurate cause depending on the gear engaged, the load won't be the same!! there are many working with the TPS. Sometimes some of them only have as a scaling the inlet pressure !!! how do they do to be as accurate as subaru does?

imagine that the arc of a complete circle is divided into 1024 equal segments instead of the "normal" 360 one-degree segments


why 1024? The ignition is defined on 8bit so FF no.......so 256 values? that would means that a quarter of the position of the flywheel is defined? And why from -20 to 69°......because the ecu needs other positions for ignition/fueling timing no?


Thanks for you help,math
letsteyr
 
Posts: 43
Joined: Wed Jan 31, 2007 4:32 am

Postby Jon [in CT] » Thu Nov 29, 2007 9:33 am

letsteyr wrote:oh yes sorry, sorry for the mistake in the conversion of the afr. I have understood the afr now.

And then, how does the ecu converts AFR to injector pulse?

It knows the flows of air entering in the inlet pipe.......with the fuel table it knows what has to be the flow of fuel (using scaling injector too).......but many cylinders may have inlet valves opened in same time no? So what's the accurate conversion? I ask that because other manufacturers use injection timing in their fuel table.
First, observe that the load reference for Subarus is grams of intake air per engine revolution, or g/rev. Let's work an example where the current load is 2 g/rev, and open loop fuel control is in effect, and the raw desired enrichment value for the current RPM and 2 g/sec load is 32. The value 32, as explained in my previous post above, means that the desired enrichment is 25% richer than stoichiometric.

But first, there is a value in ROM which represents injector size. Its raw value represents the number of microseconds that each injector must flow fuel in order to achieve a stoichiometric AFR when load is 1 g/rev. The larger the injector, the smaller the raw injector value, since larger injectors don't need as much time to flow a particular amount of fuel. Note that our tuning software displays this injector time value as a cc/min volume flow, because tuners are more familiar with that measure of injector size.

So, back to our example. Conceptually, the calculation to determine injector pulse width is very simple and efficient. First, the load, in our case 2 g/rev, is multiplied by the injector size value in order to obtain the basic injector pulse width, in microseconds, necessary to achieve a stoichiometric AFR. Then that stoichiometric pulse width is multiplied by the AFR table enrichment value, in our case 1.25, to obtain the basic pulse width necessary to achieve the desired enrichment. And that's it, except for applying adjustments like long term fuel trim, injector delay based on voltage, etc..
letsteyr wrote:I got another question too. Some cars don't use a MAF. For subarus the load = (RPM/MAf)/4 in g/rev
But for other cars, fuel tables have the throttle position as a scaling? How can it be accurate cause depending on the gear engaged, the load won't be the same!! there are many working with the TPS. Sometimes some of them only have as a scaling the inlet pressure !!! how do they do to be as accurate as subaru does?
If MAF is mass air flow in grams per second (g/sec), then Subaru's load, in g/rev, is MAF*60/RPM. Load at WOT for a particular RPM frequently does increase with a higher gear. That's why most tables support multiple load values for any particular RPM. Also, Subaru ECUs do make some adjustments in response to a throttle tip-in.
letsteyr wrote:
imagine that the arc of a complete circle is divided into 1024 equal segments instead of the "normal" 360 one-degree segments


why 1024? The ignition is defined on 8bit so FF no.......so 256 values? that would means that a quarter of the position of the flywheel is defined? And why from -20 to 69°......because the ecu needs other positions for ignition/fueling timing no?
Yes, but a range of only 90 degrees is quite sufficient to specify any realistic spark advance in terms of degrees BTDC. The ECU maintains the current absolute crank angle position at a much higher two-byte precision.
Jon [in CT]
 
Posts: 352
Joined: Sat Jan 01, 2005 10:23 am

Postby letsteyr » Sat Dec 01, 2007 3:16 am

ok, i see.Thank you, i'll use this post to ask further question of this kind. :) :)
letsteyr
 
Posts: 43
Joined: Wed Jan 31, 2007 4:32 am

Next

Return to Tuning Software

Who is online

Users browsing this forum: No registered users and 9 guests