10
May
13

BMW MRSZ “1 internal ECU error” fix

I lost almost an entire day trying to figure out what went wrong when I was playing with my E36 airbag module coding in an attempt to disable passenger seat occupancy detection.

I didn’t understand why most MRSZ settings were duplicated, such as these two:

ERKENNUNG_SITZBELEGUNG_1
	aktiv
ERKENNUNG_SITZBELEGUNG_2
	aktiv

I set only one of these to “nicht_aktiv”, after which the module threw an “internal ECU error” and the FS_LOESCHEN command returned ERROR_ECU_REJECTED. Even after I restored all coding settings back to their original values, the error remained.

As it turns out, after digging through 24KB of microcode, the reason to duplicate every setting is very simple – it is a form of EEPROM error detection. The unit periodically checks to see if every setting has the same value in both copies, and when that is not the case, a static error 195 is logged. Every error code above 100 is mapped to the “internal ECU error”, and when that happens the erase function is also blocked.

Fortunately, at the same time I also found a “secret” command to write EEPROM bytes. Not all areas can be written with that command, but at least the area where the errors are stored is writable.

Attached is an EDIABAS script that attempts to “reanimate” an MRSZ unit. Note that you need to restore the coding to a working state before running the script. NCSExpert’s SG_CODIEREN command will end with an error, that is because it tries to erase errors at the end of the process, which fails, the actual coding should in fact be OK.

MRSZ_FIX.PRG (beta)

Note – the script supports only MRSZ units (MRS v06, P/N 8374799), it does not support MRSZ2 (MRS v07, P/N 8372521), MRSZ3 or MRSZ4. The “secret” command simply does not exist in these modules. I do not know if it supports the older ZAE2 (P/N 8374798) units.

The source code of my MRSZ2 attempt can be found here. It includes working support for MRSZ.

06
Jan
12

Groovy is COOL

Of course Groovy is much more than Java, but for Java coders like myself, it can be seen as Java without its time-eating annoyances, the absolute top 3 of which, in my opinion, are:

1. Getters and setters are implicit

2. Lists, Maps and Regex are part of the syntax

3. Configuration is greatly simplified

Item 1 is self explanatory, I hope :) For the remaining two, here are some examples:

Working with collections:

def list = [5, 6, 7, 8]
for (i in list) println i
def map = [name:"Gromit", likes:"cheese", id:1234]
for (i in map) println "map[${i.key}] is ${i.value}"

Pulling Maven dependencies inline with your code, without any other configuration anywhere:

@Grab(group='mysql', module='mysql-connector-java', version='5.1.18')
driver = new com.mysql.jdbc.Driver()
Properties p = new Properties()
 p['username']='groovy-test'
 p['password']=''
conn = driver.connect('jdbc:mysql://localhost/groovy-test', p)
st = conn.createStatement()
for (i in 1..10) {
 st.executeUpdate("insert into test(name,value,version) values('name${i}','value for name${i}',0)")
}
st.close()
conn.close()

Of course Groovy is a dynamically typed language, and as such has its downsides. Since the compiler can’t type-check assignments, you get much more run-time errors like:

No signature of method: java.util.ArrayList.get() is applicable for argument types: (java.lang.String)

Or

Cannot cast object ‘x’ with class ‘java.lang.String’ to class ‘int’

Most of these errors are caught when you try out your code for the first time, though, and are easily fixable. It’s just a bit annoying at the beginning for someone used to getting these at compile time rather than at run time.

To me, Groovy is still a clear winner if you want to boost your coding productivity🙂

Oh yeah, and the performance of Groovy is not significantly worse than that of Java (if you don’t use too many dynamic features), as I confirmed in this post.

05
Jan
12

Motorola AP-7131 dependent mode?

It seems that not all AP-7131’s are the same. There are some that are meant to be used only together with a central controller like RFS4000 or RFS6000.

This is called, in Motorola terms, ‘dependent mode’, and is hard-coded into the device. The “D” in the model ID stands for “dependent”, like in this example:

Motorola AP-7131-66000-D-WR

Such a device will not enable any radio unless directed to do so by a central controller.

One of the reasons this is done is to prevent theft of access points from public locations.

05
Jan
12

Detect MIME type of most popular Internet files

This code can detect among others PDF, Microsoft Word, Excel, Powerpoint & Visio, without even knowing the file extension.

 

sub detectMime(\$)
{
  my ($s)=@_;
  return 'text/html' if $$s =~ /^(\xEF\xBB\xBF)*\s*<(\!--|\!?doctype|html|head|body|title|h1)/is;
  return 'text/xml' if $$s =~ /^(\xEF\xBB\xBF)*\s*<\?xml/s;
  return 'application/rtf' if $$s =~ /^\{\\rtf/s;
  my @b=unpack('C520',$$s);
  return 'image/jpeg' if $b[0]==0xFF && $b[1]==0xD8;
  return 'image/gif' if $b[0]==0x47 && $b[1]==0x49 && $b[2]==0x46;
  return 'image/png' if $b[0]==0x89 && $b[1]==0x50 && $b[2]==0x4E && $b[3]==0x47;
  return 'image/bmp' if $b[0]==0x42 && $b[1]==0x4D;
  return 'image/tiff' if $b[0]==0x49 && $b[1]==0x49 && $b[2]==0x2A;
  return 'application/pdf' if $b[0]==0x25 && $b[1]==0x50 && $b[2]==0x44 && $b[3]==0x46;
  return 'image/x-icon' if $b[0]==0 && $b[1]==0 && $b[2]==1 && $b[3]==0 && $b[4]==1;
  if ($b[0]==0xD0 && $b[1]==0xCF && $b[2]==0x11 && $b[3]==0xE0 && @b>0x200) {
    return 'application/msword' if $b[0x200]==0xEC;
    return 'application/vnd.ms-excel' if $b[0x200]==0x09;
    return 'application/vnd.ms-powerpoint' if $b[0x200]==0x40;
    return 'application/vnd.visio' if $b[0x200]==0xFD;
  }
  for (my $i=@b-1;$i>=0;$i--) { return 'application/octet-stream' if $b[$i]<32 && $b[$i]!=9 && $b[$i]!=10 && $b[$i]!=13 }
  return 'text/plain';
}
05
Jan
12

SDBM hash implementation in PHP

The SDBM hashing function is a simple and fast function that provides surprizingly uniform distributions of the hash value even when applied to a series of relatively short strings (3-7 characters). This makes it an excellent algorithm for organizing multiple files in sub-directories, for example, but the possible applications are, of course, endless.

Implementing the SDBM hashing in PHP is not an easy task, however. The SDBM hash function relies on a 32-bit overflow, which doesn’t work well in PHP due to its built-in overflow handling and automatic type conversion, which is also implemented differently on different platforms.

After much trial and error, the following cute piece of code has been found to perform correctly in PHP 5.2/5.3 on 32-bit as well as 64-bit systems.

function sdbmHash($str)
{
	$hash = 0; $n=strlen($str);
	for ($i=0; $i<$n; $i++) {
		$h1 = $hash << 6;
		if ($h1<0) $h1+=0x100000000;
		$h2 = $hash << 16;
		if ($h2<0) $h2+=0x100000000;
		$h3=($hash>=0x80000000?0x100000000-$hash:-$hash);
		$hash = (int)((int)ord($str[$i]) + $h1 + $h2 + $h3);
		if($hash<0) $hash=$hash+0x100000000;
	}
	return $hash;
}
05
Jan
12

“MySQL server has gone away”

When you try to insert a BLOB that exceeds your server’s maximum packet size, even on a local server you will see “MySQL server has gone away” on the client side, and “Error 1153 Got a packet bigger than ‘max_allowed_packet’ bytes” in the server log. To fix this you need to decide what is the size of the largest BLOB you’ll ever insert, and set max_allowed_packet in my.ini accordingly, for example:

[mysqld]
 ...
 max_allowed_packet = 200M
 ...

 

05
Jan
12

PHP vs. Ruby/JRuby on Rails vs. Grails vs. Java performance comparison

In this write-up I captured my findings about the performance of various frameworks that I was considering for my next project…

Test setup:

  • One MySQL 5.1 table consisting of an ID and 2 string columns, 1000 rows (+5 for warm-up)
  • a simple web application that:
    • reads one record from the table
    • displays record data on a web page in table form
The page is accessed sequentially 5 times to warm up the caches, then 1000 times (timed). The time is captured below.

Test subjects:

  1. PHP 5.3.3 on Apache 2.2.21
  2. Ruby 1.8.7 + Rails 3.1.3 on mongrel 1.1.5
  3. JRuby 1.6.5 (emulating Ruby 1.8.7) + Rails 3.1.3 on mongrel 1.1.5
  4. Grails 2.0.0 (Groovy 1.8.4) on Tomcat 7.0.16
  5. Java 1.7 + Spring 3 on Tomcat 7.0.23

Everything was set to ‘production mode’. Test platform: win32.

Test results:

Framework Time per request
PHP 10.6ms
Ruby/Rails 14.1ms
JRuby/Rails 16.0ms
Grails/Groovy 7.4ms
Java 6.4ms

Java seems to be a clear winner here… too bad it’s by far the slowest of the 5 to develop in! :-[]

p.s. I know my JRuby setup is awkward… I just couldn’t get any sane performance out of it on a Tomcat. The perf I got in this post is the best I could achieve.