Jump to content

CRC 8 - Issue with Identifying the Polynomial used or Understanding the CRC algorithm used


kjay

Recommended Posts

Hello,

         I'm working on a gateway application that will disengage a real ecu and simulate in the software using CAN msgs for automotive. 

Situation:

It looks like the CAN message has a count and a checksum as part of the payload, so every time I change a msg, i need to modify the counter recalculate the checksum.

Now in my msg, the checksum is at the 7th byte and the count is in the 8th byte. Ive added below some sample logs collected from the module. So I tried using an online CRC calculator to derive the Polynomial but I'm unable to arrive there. From the below logs, F9,F0,F6 and EE is the checksum. I'm trying to reverse engineer and validate what checksum method and polynomial was used, so that I can play and change the msgs. One more question I have is, while calculating the checksum (in this case), can I ignore the 7th byte(where checksum is inserted) and use the remaining 7 bytes including the count? I tried that route and used the standard CRC8,  CRC8_SAE_J1850,   CRC8_SAE_J1850_Zero but none that works.

6F 5A 6F 86 73 7C F9 70  

6F 5A 6F 83 73 7E F9 71  

6F 5D 6F 88 73 7D F0 73  

6F 5C 6F 88 73 77 F6 74  

6F 5D 6F 87 73 7E EE 75  

I'm trying to implement this in LabVIEW and im using the XNET API's. This is kind of not so important now, i need to first identify and validate the checksum, I'm pretty confident with the implementation in LabVIEW.

Any help/leads would be helpful and appreciated.

 

Thanks

Jay

Link to comment

When I'm trying to figure out checksums, I'm first trying various online tools which compute them. They often support many varieties.

Checksum byte is very rarely used for checksum. I've seen once an algorithm which used that area, assuming it is zero filled.

Count is sometimes included, sometimes not - hard to judge.

 

If a simple check with few sites/tools won't help, i'm going into REing the code. It is simpler than checking all possibilities.

Also, implementations of CRC used in various products are often incorrect, ie. incorrectly treating sign, byte order, or just having a typo. So sometimes it's not possible to figure out the algorithm without reversing the target code.

 

Link to comment
21 hours ago, kjay said:

Hello,

         I'm working on a gateway application that will disengage a real ecu and simulate in the software using CAN msgs for automotive. 

Situation:

It looks like the CAN message has a count and a checksum as part of the payload, so every time I change a msg, i need to modify the counter recalculate the checksum.

Now in my msg, the checksum is at the 7th byte and the count is in the 8th byte. Ive added below some sample logs collected from the module. So I tried using an online CRC calculator to derive the Polynomial but I'm unable to arrive there. From the below logs, F9,F0,F6 and EE is the checksum. I'm trying to reverse engineer and validate what checksum method and polynomial was used, so that I can play and change the msgs. One more question I have is, while calculating the checksum (in this case), can I ignore the 7th byte(where checksum is inserted) and use the remaining 7 bytes including the count? I tried that route and used the standard CRC8,  CRC8_SAE_J1850,   CRC8_SAE_J1850_Zero but none that works.

6F 5A 6F 86 73 7C F9 70  

6F 5A 6F 83 73 7E F9 71  

6F 5D 6F 88 73 7D F0 73  

6F 5C 6F 88 73 77 F6 74  

6F 5D 6F 87 73 7E EE 75  

I'm trying to implement this in LabVIEW and im using the XNET API's. This is kind of not so important now, i need to first identify and validate the checksum, I'm pretty confident with the implementation in LabVIEW.

Any help/leads would be helpful and appreciated.

 

Thanks

Jay

Something is surely off here: You say that the checksum is in the 7th byte and the count in the 8th. But aside that it is pretty stupid to add the count of the message at the end (very hard to parse a binary message if you don't know the length, but you only know that length if you read exactly the right amount of data), those 70 71, 73 and so on bytes definitely have nothing to do with the count of bytes in your message.

Besides what checksum are you really dealing with? A typical CAN frame uses a 15 bit CRC checksum. This is what the SAE_J1850 fills in on its own and you can't even modify when using that chip. It would seem that what you are dealing with is a very device specific encoding. There could be a CRC in there of course, but that is totally independent of the normal CAN CRC. As far as the pure CAN protocol is concerned, your 8 bytes of the message are the pure data load, and there is some extra CAN framing around those 8 bytes, that you usually never will see on the application level. As such adding an 8 bit CRC to the data message is likely a misjudgement from the device manufacturer. It adds basically nothing to the already performed 15 bit CRC checking that the CAN protocol does itself one protocol layer lower.

  • Thanks 1
Link to comment

Yeah what Rolf said.  I've seen several CAN payloads with a message counter, and CRC, and never has there been any meaningful data after the CRC.  I have seen times when it is an 8 byte payload, and the 7th byte is the CRC.  But in this case the 8th byte wasn't used in the CRC calculation.  You can find the typical J1850 CRC calculation online here just set the Predefined to CRC8_SAE_J1850.  After playing around for a little while I couldn't get the CRC byte you provided to match.

If you do ever figure out the algorithm, there are a couple of options on how to do this in XNet.  Obviously every frame will have a different counter value, and different CRC, so you can't use a single point session. 

You can make a loop waiting for some amount of time to go by, and then send a single frame, then wait more time and then single frame again.  This is going to be software timed and the jitter will likely be large, and depending on the amount of frames this can put extra work on the CPU just waiting and sending single frames as fast as possible.  In XNet this will be the Frame Out Stream session type.

An alternative to this is the Frame Out Queued session type which allows you to pile up frames to go out one at a time, using the timing from a database.  Here I called this the bucket filling technique since you need to make sure the queue doesn't go empty.

And lastly, NI does offer to load up some very basic C code on the XNet hardware, which allows for modifying the frame's data before being sent out.  This is undocumented, experimental, and only useful if you actually are using a standard CRC.  Otherwise you'll need to write your own C code, and that gets even more difficult.  I'm only mentioning this feature to be complete, and am not actually advocating you use it.

Link to comment

Hoovah thanks for your response. I actually read a lot from your blog (Part 9 where you spoke about the CAN CRC and bucket filling technique). Could you help me precisely on the below 2 questions, I'm trying to find the checksum using the calculator and prove but it doesn't work (like you mentioned).

1.I tried creating  a checksum using the CRC calculator (from the payload I sent, I ignored the 7th byte and used the remaining 7 bytes and found a checksum value). I put the checksum on the 7th byte and sent it. I even decoded by finding the checksum (with all the 8 bytes per the J1850), and XORed with FF which yields the C4 value. However when I send tis packet in the bus, I get a DTC on the module for checksum error. Is this the right way? Can I just use the 7 bytes and insert the identified checksum in the 7th byte later?

2. Is it even possible to backtrack and find the checksum from a system generated log? I'm assuming there would be permutation and a number of 8 bit CRC  could be possible for the same log? Is this assumption correct and valid?

I'll continue to update this thread based on my finding.

Thanks all for the response and support.

Regards

Jay

Link to comment

If you are just trying to replay the message you already have from a valid log you can do that and see if the ECU is happy.  Was it possible that it was setting DTCs when the log was recorded?  If you want to change any bit inside the payload you'll need to figure out the algorithm used.  As we said it clearly isn't the standard one used for CAN.  Other than just guessing a bunch of things I don't think you'll be able to get past this issue.  That is again unless all you want to do is replay a already recorded log.

Also here's a random thought.  Are you sure that byte is a CRC at all?  I mean the values you gave in your example all were 0xF_ or 0xE_.  Do you have the DBC that these messages belong to?  It doesn't match the standard CRC, and there is a counter after the CRC which I've also never heard of.  If it is a CRC I'd expect it to have a somewhat normal distribution among the 256 possible values.  Does the rest of the log reflect this?

EDIT: I'm convinced that is not a CRC.  You have two frames each with 0xF9 but the payload is different.  Statistically that isn't likely to happen often.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.