Can anyone out there explain how to calculate the 15 bit CRC field for a Controller Area Network message (specifically the extended frame format)? I don't understand the code given in the Bosch specification (not even sure which language it's written in) and the only other example I found was very obfuscated C code. Any takers?
What is your problem with the formula given there for the coefficients of the generator-polynomial?
X15 + X14 + X10 + X8 + X7 + X4 + X3 + 1.
that is what I would call a mathematical description. The other code given there I know under the name of pseudo code. If that is something like the names of Bohemian villages for you, please search for "CRC calculation". Most literature you will find can explain it better than I can.
The CAN specification already explains it. And unless you're out to implement your own CAN controller (why?), there's hardly a point digging any deeper --- just use an off-the-shelf CAN controller, it knows how to do this.
I do not understand what "X" is in this case. Is it just a concatenation of all the bits in the SOF, Arbitration, Control and Data fields? If yes, then the resulting number would be much larger than 15 bits. Hence my confusion. The term "generator-polynomial" is also unfamiliar to me. I have searched extensively for CRC calculation and all the articles I have found to date say it is really nice thing to have, talk about the format in very vague and hand wavy terms that I guess they assume everyone already knows (like "generator- polynomial"!!!) and usually wind up saying that there are many different ways to derive one. Great. _WHICH_ method is the one used for CAN messages specifically?? As mentioned, only the Bosch specification and a really incomprehensible C code actually refer to CAN by name.
I am very familiar with pseudo code > The CAN specification already explains it. And unless you're out to
I am trying to write a simulator (in Java as it happens) that will show me what the picture on the oscilloscope should look like for an arbitrary CAN message. That way I can troubleshoot my hardware and firmware to figure out whether I am sending the message that I think I should be sending or if bugs are creeping in along the way. Everything is written and working except the CRC part. Right now I'm just setting all the bits to "1" but that winds up screwing with my bit stuffing.
its a mathematical way of describing something that boils down to shiftregisters and xor gates in short X is the shift register, the numbers are bit positions.
though I can't really get the numbers and the 0x4599 in the code to match up
looks a bit weird, helps if you know verilog or vhdl I guess.
the pseudo in c would be something like this: (untestet, inefficient, written in 30 seconds ...)
unsigned short CRC(unsigned short input) // input only one bit !!! { static unsigned short crc_rg; // shiftregister crc_rg = crc_rg >14)&1)) { crc_rg = crc_rg ^ 0x4599; } crc_rg = crc_rg & 0x7fff; // only 15 bits
Ah!!! This I can understand. Thank you very much. Unfortunately, when I run the above code I get a different CRC result than the one that shows up on the o-scope from my hardware :( Anyone know what I'm doing wrong? For what it's worth I also tried the inversion value to 0x4599 of 0x4CD1 as listed on the Wikipedia page for Cyclic_redundancy_check and it didn't work either. ???
-Will
CAN Message as it appears on o-scope:
00010000010001100000110000010010000010000011000001001100101010011001101111111 bit stuffing removed:
00010000000011000001000000010000000000100000001100101010011001101111111 separated into fields: SOF IDT[28:18] SRR IDE IDT[17:0] RTR r1 r0 DLC Data(1 byte) CRC CRC_del. ACK ACK_del. EOF
0 00100000000 1 1 000001000000010000 0 0 0 0001 00000001
100101010011001 1 0 1 111111
so the hardware CRC for the above message is 100101010011001 or 19,097
All of my bits on the software (after stuffing) match the o-scope picture until the CRC, which does not match
Well, the number 0x4599 seems to be popping up in a lot of the CAN examples, and 0xC599 is 16 bits, not 15 so I don't know how that would change anything since the results are always truncated to 15 bits. : ( Anyone?? Is there a bug in the example code that Lasse provided?
Anyone know why the example code provided by Lasse does not match the CRC generated by the hardware I'm using? If it matters (shouldn't) I'm using an Atmel AT90CAN128 chip. But any CAN controller should generate the same bit patterns unless I am wildly mistaken, which does happen sometimes...
As someone pointed out the polynomial for the CAN CRC is apparently: x^15 + x^14 + x^10 + x^8 + x^7 + x^4 + x^3 + 1
This polynomial can be represented as 0x4599 (x^0 maps to LSB, x^15 is implied 1). Knowing this my utility can then be invoked like this: universal_crc --bits=3D15 --poly=3D0x4599
This will produce ANSI C code for calculating the CRC and print it to stdout. The utility has various other options that you might need depending on how the CAN CRC is defined (initial value of the CRC register, final XOR, reversed mode, etc.). There are also different CRC algorithms to choose from that have various performance characteristics.
On Apr 16, 12:49=A0am, Lasse Langwadt Christensen wrote: [...]
Hi,
This code is buggy I think. The input message bit should be XORed to bit 14 of the CRC register *before* it is shifted (so >>14 should be changed to >>15).
Anyway, here is code that updates the CRC register for a whole input byte at once:
static inline uint16_t crc_next(uint16_t crc, uint8_t data) { uint16_t eor; unsigned int i =3D 8;
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.