MUT/RAM logging
I was looking for code to watch RAM contents on an evo9 to help with understanding the disassembly. I found this post which talks about a DMA logging feature built into the stock ROM: https://www.evolutionm.net/forums/ec...live-tune.html
After looking through the dissambly I was able to find the DMA code. Looks like there are a few state machines watching for either a 5 baud init (0x00, 0x33, 0x10?, 0x89?) or a DMA logging command to decide how to use the k-line. For DMA logging you just connect at full speed and write a 0x33 byte (for 24x logging) control message. The ECU then continuously dumps data on the serial port with the current values using a 0x33 byte response. There are commands from 0x81 to 0x89. I've only tried the 24x2B format which uses command 0x81. Other commands are for 24x1B, 5x2B, 6x1B + 2x2B, and also support for special RAM accesses. The lower address values map directly to MUT. For example, 0x17 reads the TPS value. It's also possible to read RAM in the 0x6000-0xDFFF address range. I hacked together a c# app to try it out which you can see in the gif below. There's a counter value incrementing in RAM and I also pressed the throttle so the TPS (0x17) value changes. Ignore the slow updates - I think that's due to the widgets the c# app uses and the speed of the animated gif. I haven't figured out the right way to disconnect which doesn't require power cycling the ECU and openport. EvoScan can usually reset the port by connecting and trying a 5 baud init, but a 5baud init PassThru command hangs for me. I also set a bit in the ROM header which I think enables some of the DMA modes and need to verify if it's necessary. This post is mainly to illustrate how the stock ECU logging feature works. I doubt I'll make a logging app, but maybe someone else may find this info useful. 24x2B Request 0x33 Bytes: <CMD 0x81> <2B address in little endian> ... <0x30 Bytes of address> <1B CheckSum> <Trailer=0x0D> 24x2B Responses 0x33 Bytes: <CMD 0x01> <2B data in little endian> ... <0x30 Bytes of data> <1B CheckSum> <Trailer=0x0D> https://cimg3.ibsrv.net/gimg/www.evo...0501908618.gif Code:
NOTE: Sorry for the c# syntax. I don't have a lot of experience coding. |
The low sample rate was caused by dropped samples. Looks like it combines responses into a single message if multiple are waiting and the code was only looking at the first. I decoupled the processing of the data and reading the port in separate threads and increased the sample rate. It's still dropping some samples, though. Also haven't figured out how to reset the DMA engine properly without causing the openport to hang which makes testing harder.
In the animated gif below you can see the throttle varying. The other graphs aren't very interesting with the engine off: ECT, RPM, battery voltage, spark advance. https://cimg3.ibsrv.net/gimg/www.evo...3bf38b0160.gif |
I added some stuff to test out data logging. The first pic is cold start. The second is after it idled for a few minutes and I tap the throttle. The car is pretty much stock and I don't have the tephra 1B Load value in the ROM to log, but the load is low enough to show what's happening. The highlighted cells are a bit off from the actual RPM and Load due to a bug.
Disconnects are still broken which I need to figure out next. There's also too much c# code running now and it can't process the samples fast enough so the logging is a bit delayed. That also needs to be fixed. https://cimg7.ibsrv.net/gimg/www.evo...126917d97c.gif https://cimg5.ibsrv.net/gimg/www.evo...00f679c39e.gif |
I also looked through the commands more:
81: 24x2B logging 82: 24x1B? logging 83: 5x2B logging 84: 24x2B + live tuning using last 4B? 85: 2x6B 6x1B + live tuning using last 4B? 86: 5x2B + live tuning using last 4B? 87: copy to/from 0x400 scratch in RAM. can't see any use of this scratch in the unmodified ROM, though 89: some live tuning options controlled by f33, f34, f39 in the header? The disconnect is some problem I'm having with sending a write through the openport2. If I send the message with a timeout it hangs. Without a timeout (=0) it succeeds but then hangs on the disconnect. |
Great stuff. You have an Evo IX ECU, right?
I patched my ROM with @jcsbanks 's DMA logging code long ago ( https://www.evolutionm.net/forums/ec...ode-works.html ) but I'll have to go back and look for this built-in DMA code again. I'm surprised none of the original ECU disassemblers found this (or at least no one mentioned it publicly). |
Ya, I have a 9 with the 1860A465 ECU. Would love to get a cheap spare for a bench setup, but they are hard to find. I've been looking through the 88590015 ROM. There's a lot of code and indirection (table lookups for function call pointers, etc) associated with the feature. I'll share my source and a binary as soon as I figure out how to keep the OP2 from hanging on the DMA logging cancel write message. Also accidentally deleted the source last night so it's going to take a few days to rewrite :crap:
Here are a few of the function calls associated with DMA logging (88590015): 0x00026468 - Setup and handle DMA operations on timer (CAS?) interrupt. Handles subset of DMA operations 0x00026104 - Handle DMA operations in main loop. Handles other set of DMA operations 0x00009206 - RX (input) buffer message checks and decode. This is run on the RX buffer once for the logging command types. 0x000096BC - 24x2B and 24x1B (and 5x2B?) TX buffer fill code based on ADEC table 0xADD8 has 5 function pointers for RX DMA setup, TX DMA setup, error/DMA cancel checks, idle checks, etc 0xADEC is a table of of 6B structures that <2B resp rate ctr compare?> <1B resp msg header> <1B params per resp> <1B size of each param> <FF?> Here's an example where RX (input) buffer is decoded. The online disassembler treats the values as signed but you can see the 0x81 (#-127), 0x82, ... comparison logic. Code:
.data:00009306 ea 81 mov #-127,r10 |
Found a fix for the disconnect issue. It takes ~10s but works most of the time. I didn't understand the bus timing parameters before and the logging mode doesn't work with the default values when trying to disconnect. It also seems to require a 5baud init to kick the DMA logging out of its state machine after the "stop" write message is sent and remaining log data is drained.
The source is here: https://github.com/nanner55/mscan The latest binary is here: https://github.com/nanner55/mscan/re...t_build_v1.zip If you want to give it a try download the zip and copy your ROM into the unzipped directory. Maybe in the future parts of the ROM can be read over OBD rather than requiring a local copy. Keep in mind that the program isn't very tested and can (will) crash. The ECU will continue to log until power is cut by the relay. From what I've seen, the car still functions fine while logging, but I've only idled it and haven't had a chance to drive, yet. You will need to modify your evo8/evo9 ROM to set bit 0 in 0xF30 (2->3) and flash it. This enables support for the type of DMA logging used by default. Before connecting, load an EvoScan style parameter file with the LoadParam button. It must have a EFI section with MUT (or RAM address) request IDs. A sample one that works with an evo IX is included and named param.xml. If you want to view tables, copy your ROM into the same directory as the binary press the LoadROM button. Some temporary XML files are included from EcuFlash. If the XML files don't support your ROM ID it will throw an exception and show a message. You can try copying your EcuFlash XML into the metadata subdirectory. The ROM/XML parsing is a hack so don't be surprised if it doesn't work. It's had some basic testing on an evo IX using a tactrix openport 2.0. The tactrix will glow red when the logging is enabled signifying lots of message data waiting in its receive buffer. If you try to disconnect and it remains red the logging is still enabled and the disconnect was unsuccessful. Typically the mscan program hangs when this happens. You will need to cycle the ECU power (Ignition -> ACC) for a few seconds until you hear the relay click and the tactrix stops glowing red. You can also try reloading mscan and doing a connect and then disconnect. Sometimes that works, too. |
I looked through the 0x87 DMA command that supports read (1) and write (0) of 0xFFFF9C00-0xFFFF9FFF. I couldn't find any use of that memory region anywhere else so 2 new commands were added to support reading any memory location (5) and writing anything in the FFFFxxxx range (4). The additions fit within the existing code without branching out. The ROM Id can now be read out of flash over serial and used to calculate table addresses to read. It's really slow, though, since it seems like the ECU will only buffer 1 command at a time and the data size is fixed at 0x2C. I'll check if it's easy to take a length and have the ECU push all the data at once.
The weird CTR param incrementing pattern in the previous versions was caused by the thread timers only going down to ~15ms of precision. It's using a different set of timers now with more precision. Hoping Tactrix can help me figure out a way to keep the OP2 from buffering 0xFE0 worth of data before responding back with a message. That adds ~1s of latency. Would be nice if that was closer to 100ms-200ms. Picked up a 2006 Lancer AT bench ECU so no more debugging inside the car. It doesn't have any sensors hooked up so I just connected the 5V supply pin to TPS a few times. https://cimg8.ibsrv.net/gimg/www.evo...e7c386e5d3.gif |
nice, look my code.. https://github.com/DowJhob/Evo-live-map
|
Thanks for the link. It looks like it uses the E1-E4 MUT changes to do the reads and writes? I haven't read through those ASM changes. If I decide to add live maps I may take a look at your code to see how it works. Right now the existing Mitsubishi DMA code is interesting to look through and change.
I fixed performance of the new DMA read and write by adding a count field to the existing packet. For reads it's in terms of 0x2C byte data packets for up to 0x2C00 worth of data and for writes its in terms of bytes. Reads are significantly faster now and writes don't require a read-modify-write which isn't atomic. |
in my opinion, you are working incorrectly with reading, you do not need two timers and even super-accurate ones, look at the example in the tactrix driver, reading in an infinite loop in a separate thread, and all your problems with timeouts will disappear. I gave a link to show that pure c is much faster than c#, but if you really want c# then look at the tephra livemap client for evo10
and of course use unsafe code for native work with j2534 messages, ideally you need to write a module that will work with unsafe inside this man --> https://github.com/RcusStackwalker at one time found a stock DMA and was going to write a client, but then he abandoned it here it was discussed http://airtrek-turbo.ru/viewtopic.php?f=17&t=26 |
imho you wrong interpret SCONFIG parameter
http://embeddedsystem.ru/index.php?p...standarta-obd2 see fig.5 this parameters control by ECU you must set adequte parameter in your j2534 adapter, its not timeout |
class enum direction:WORD
{ write, }read, info, //wtf??? addedWrite, addedRead struct _0x87mode { byte modeId = 0x87; }direction directionId; WORD offset; byte data[0x2C] // 44 bytes. byte checkSumm; byte endOfStruct = 0x0D; you change to class enum direction:byte { write, }read, info, //wtf??? addedWrite, addedRead struct _0x87mode { byte modeId = 0x87; }direction directionId; byte packetCount; DWORD addr; byte data[0x2A] // 42 bytes!. byte checkSumm; byte endOfStruct = 0x0D; while maintaining the total length of the packet right? but your LOG_DAT_SIZE = 0x2C, for example line 591.. what's the point in this packet counter? |
The read and write packets have 2 new formats. This was done to make only a small amount of inline changes to the ECU code to support the new formats and still keep the existing functions. The packetCount field in the read allows multiple 0x2C responses to be sent by the ECU which is much faster than reading 0x2C at a time. The byteCount was added to the write so someone isn't forced to write 0x2C bytes all the time. If you only want to write 1 byte it doesn't require a read of the other 0x2B bytes of data that may be changed by the ECU.
EDIT: I should clarify that these are request packet formats. The read response format is still the same with read mode 1 and 5: <0x05> <0x00> <0x01> <offset2B/upperAddr2B> <0x2C of Data> <CSUM1B> <0x0D> Code:
class enum direction:byte |
that is, for each request with packetCount = 0x00, I will receive a response from six messages
struct _0x87response { byte typeId; }WORD sudType; WORD offset; byte data[0x2C]; byte chckSmm; byte endOFstruct; ? |
All times are GMT -7. The time now is 10:57 AM. |
© 2024 MH Sub I, LLC dba Internet Brands