I try to calc CRC for P1 message. CRC is calculate The CRC for P1 runs from the "\" to the "!" (inclusive). CRC16 uses no XOR in, no XOR out and is computed with least significant bit first.
P1 message:
/ISk5\2MT382-1000
1-3:0.2.8(50)
0-0:1.0.0(101209113020W)
0-0:96.1.1(4B384547303034303436333935353037)
1-0:1.8.1(123456.789*kWh)
1-0:1.8.2(123456.789*kWh)
1-0:2.8.1(123456.789*kWh)
1-0:2.8.2(123456.789*kWh)
0-0:96.14.0(0002)
1-0:1.7.0(01.193*kW)
1-0:2.7.0(00.000*kW)
0-0:96.7.21(00004)
0-0:96.7.9(00002)
1-0:99.97.0(2)(0-0:96.7.19)(101208152415W)(0000000240*s)(101208151004W)(0000000301*s)
1-0:32.32.0(00002)
1-0:52.32.0(00001)
1-0:72.32.0(00000)
1-0:32.36.0(00000)
1-0:52.36.0(00003)
1-0:72.36.0(00000)
0-0:96.13.0(303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F)
1-0:32.7.0(220.1*V)
1-0:52.7.0(220.2*V)
1-0:72.7.0(220.3*V)
1-0:31.7.0(001*A)
1-0:51.7.0(002*A)
1-0:71.7.0(003*A)
1-0:21.7.0(01.111*kW)
1-0:41.7.0(02.222*kW)
1-0:61.7.0(03.333*kW)
1-0:22.7.0(04.444*kW)
1-0:42.7.0(05.555*kW)
1-0:62.7.0(06.666*kW)
0-1:24.1.0(003)
0-1:96.1.0(3232323241424344313233343536373839)
0-1:24.2.1(101209112500W)(12785.123*m3)
!EF2F
For calc CRC I used this func;
uint16_t crc16 (const uint8_t *data, unsigned int length)
{
uint8_t x;
uint16_t crc = 0;
while (length--) {
int i;
crc ^= *data++;
for (i = 0 ; i < 8 ; ++i) {
if (crc & 1)
crc = (crc >> 1) ^ 0xa001;
else
crc = (crc >> 1);
}
}
return crc;
}
Unfortunately it doesn't get crc = 0xEF2F.
Can anyone help me where the problem may be ?
UPDATE
I checked the crc from this example - https://www.netbeheernederland.nl/_upload/Files/Slimme_meter_15_32ffe3cc38.pdf and it also doesn't match. Does anyone have any idea what could be wrong ?
Related
I was looking around in the zephyr implementations and found this method for computing a crc16 checksum:
u16_t crc16(const u8_t *src, size_t len, u16_t polynomial,
u16_t initial_value, bool pad)
{
u16_t crc = initial_value;
size_t padding = pad ? sizeof(crc) : 0;
size_t i, b;
/* src length + padding (if required) */
for (i = 0; i < len + padding; i++) {
for (b = 0; b < 8; b++) {
u16_t divide = crc & 0x8000UL;
crc = (crc << 1U);
/* choose input bytes or implicit trailing zeros */
if (i < len) {
crc |= !!(src[i] & (0x80U >> b));
}
if (divide != 0U) {
crc = crc ^ polynomial;
}
}
}
return crc;
}
And I tripped over this line here:
crc |= !!(src[i] & (0x80U >> b));
I do not understand why they are using a boolean operator (!!) in this line. From my understanding this is what it does:
It basically does an implicit "casting" where it considers its operand on the right to be a boolean and negates it twice, which does not do anything besides making the output a 0 or a 1 depending on if the expression (src[i] & (0x80U >> b)) was bigger then 0 to start with.
Is this correct? Why are they using the operator in this way?
It is inserting bit 7-b from src[i] into the low bit of crc. If that bit is a 1, which will be somewhere in the result of the &, the !! turns it into a 1 in the low bit, which is then or'ed into crc.
This is truly painful to look at. A better and cleaner way to do it is crc |= (src[i] >> b) & 1;, where b counts down instead of up. E.g. int b = 8; do { b--; ... } while (b);. Better still would be to just exclusive-or the byte after the loop, which does the same thing:
/* src length + padding (if required) */
for (i = 0; i < len + padding; i++) {
for (b = 0; b < 8; b++)
crc = crc & 0x8000 ? (crc << 1) ^ polynomial : crc << 1;
if (i < len)
crc ^= src[i];
}
An optimizing compiler will unroll the b loop.
I have the following CRC function:
#define CRC8INIT 0x00
#define CRC8POLY 0x18 //0X18 = X^8+X^5+X^4+X^0
// ----------------------------------------------------------------------------
uint8_t crc8 (uint8_t *data, uint16_t number_of_bytes_in_data)
{
uint8_t crc;
uint16_t loop_count;
uint8_t bit_counter;
uint8_t b;
uint8_t feedback_bit;
crc = CRC8INIT;
for (loop_count = 0; loop_count != number_of_bytes_in_data; loop_count++) {
b = data[loop_count];
bit_counter = 8;
do {
feedback_bit = (crc ^ b) & 0x01;
if (feedback_bit == 0x01) {
crc = crc ^ CRC8POLY;
}
crc = (crc >> 1) & 0x7F;
if (feedback_bit == 0x01) {
crc = crc | 0x80;
}
b = b >> 1;
bit_counter--;
} while (bit_counter > 0);
}
return crc;
}
How does 0x18 relate to the polynomial X^8+X^5+X^4+X^0?
X^8+X^5+X^4+X^0 = 100110001
0x18 = 00011000
What if I define CRC8POLY as 0xEA instead (I have seen this), what polynomial would that represent?
How does 0x18 relate to the polynomial X^8+X^5+X^4+X^0?
Since the code is a right shifting CRC, the "most significant bit" of each byte is bit 0 instead of bit 7. The poly needs to be reversed from 100110001 to 100011001, which is 0x119, after the right shift, bit 0 of 0x119 is shifted off, so 0x118 can be used instead. The code uses a second if statement to or in (0x100) >> 1 == 0x80 if the feedback bit is 1. As an alternative, since feedback_bit is 0 or 1, then (0-feeback_bit) can be used as a mask (assuming two's complement math) for the poly instead of using an if statement.
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
#define CRC8INIT 0x00
#define CRC8POLY 0x8c // 0x119 >> 1
uint8_t crc8 (uint8_t *data, uint16_t number_of_bytes_in_data)
{
uint8_t crc;
uint16_t loop_count;
uint8_t bit_counter;
uint8_t b;
uint8_t feedback_bit;
crc = CRC8INIT;
for (loop_count = 0; loop_count != number_of_bytes_in_data; loop_count++) {
b = data[loop_count];
bit_counter = 8;
do {
feedback_bit = (crc ^ b) & 0x01;
crc = (crc >> 1) ^ ((0-feedback_bit) & CRC8POLY);
b = b >> 1;
bit_counter--;
} while (bit_counter > 0);
}
return crc;
}
That CRC code is written rather oddly, where the polynomial is applied in two different places, breaking up the bits. That is, at crc = crc ^ CRCPOLY and conditionally crc = crc | 0x80. It would normally be written more like this:
unsigned crc8(unsigned char const *dat, size_t len) {
unsigned crc = 0;
for (size_t i = 0; i < len; i++) {
crc ^= dat[i];
for (int k = 0; k < 8; k++)
crc = crc & 1 ? (crc >> 1) ^ 0x8c : crc >> 1;
}
return crc;
}
where 0x8c is that polynomial reversed, without the x8 term.
Referring to Wiki article on CRC , it's crc8 realization as used in Dallas 1-wire chips. Note, that polinomial can be represented in Normal, Reversed, Reciprocal and Reversed reciprocal representations (see also Polynomial representations). Seems, that it is Reversed reciprocal representation with highest bit omitted.
I found a file to check crc of an incoming application via some interface and the program is as follows:
#define CRC16POLY 0x1021
#define PKTLEN_128 128
typedef struct Crc16Data {
uint16_t currentCrc; //!< Current CRC value.
} crc16_data_t;
void crc16_init(crc16_data_t * crc16Config)
{
// initialize running crc and byte count
crc16Config->currentCrc = 0;
}
void crc16_update(crc16_data_t * crc16Config, const uint8_t * src, uint32_t lengthInBytes)
{
uint32_t crc = crc16Config->currentCrc;
uint32_t j;
for (j=0; j < lengthInBytes; ++j)
{
uint32_t i;
uint32_t byte = src[j];
crc ^= byte << 8;
for (i = 0; i < 8; ++i)
{
uint32_t temp = crc << 1;
if (crc & 0x8000)
{
temp ^= 0x1021;
}
crc = temp;
}
}
crc16Config->currentCrc = crc;
}
void crc16_finalize(crc16_data_t * crc16Config, uint16_t * hash)
{
*hash = crc16Config->currentCrc;
}
I understood that it is simple crc software logic that doesnot involve any hardware generated crc mechanism to calculate crc of an incoming application and it is just counting the bytes of the application and adding them and placing them right? Can anyone explain what is happening inside void crc16_update(crc16_data_t * crc16Config, const uint8_t * src, uint32_t lengthInBytes) function?
And in one of the files crc16update(....) function is called as follows:
crc16_update(&crcInfo,buffer,PKTLEN_128);
where in another functions crcInfo,buffer information is found from
static void read_bytes(uint8_t * buffer, uint32_t byteCount)
{
uint32_t currentBytesRead = 0;
while(currentBytesRead != byteCount)
{
if (readOffset != writeOffset)
{
buffer[currentBytesRead++] = callback_buffer[readOffset++];
readOffset &= XMODEM_BUFLEN - 1;
}
}
}
static int read_packet(uint8_t *buffer, uint8_t idx)
{
uint8_t seq[2],crc1,crc2;
uint16_t crc16, verify16;
crc16_data_t crcInfo;
read_bytes(seq,2);
read_bytes(buffer,PKTLEN_128);
crc16_init(&crcInfo);
crc16_update(&crcInfo,buffer,PKTLEN_128);
crc16_finalize(&crcInfo,&verify16);
read_bytes(&crc1,1);
read_bytes(&crc2,1);
crc16 = ((uint16_t)crc1 << 8)|crc2;
if ((crc16 != verify16) || (seq[0] != idx) || (seq[1] != (uint8_t) ((~(uint32_t)idx)&0xff)))
return(-1);
return(0);
}
What is happening inside the function void crc16_update(crc16_data_t * crc16Config, const uint8_t * src, uint32_t lengthInBytes) ? Thanks in advance.
This code:
crc ^= byte << 8;
for (i = 0; i < 8; ++i)
{
uint32_t temp = crc << 1;
if (crc & 0x8000)
{
temp ^= 0x1021;
}
crc = temp;
}
updates the CRC with the byte. It simulates running a linear feedback shift register, whose state is the value of crc. That could can be written more compactly possibly making it easier to see what's going on:
crc ^= byte << 8;
for (int i = 0; i < 8; i++)
crc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1;
The high bit of crc determines whether or not to exclusive-or the polynomial 0x1021 with the register, after the register is shifted up one bit, with that high bit dropping off the end.
To learn more about how this implementation is arrived at, you should read Ross William's CRC tutorial.
Can somebody help me in this calculation of 32 bit CRC.
This is the peice of code I used for 32 bit CRC calculation.
static unsigned int crc32_table[256];
void make_crc_table()
{
int j;
unsigned int crc,byte, mask;
/* Set up the table, if necessary. */
if (crc32_table[1] == 0)
{
for (byte = 0; byte <= 255; byte++)
{
crc = byte;
for (j = 7; j >= 0; j--) // Do eight times
{
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
crc32_table[byte] = crc;
}
}
for (j=0;j<10;j++)
printf("crc32_table[%d] = %x\n",j,crc32_table[j]);
}
unsigned int crc32cx(unsigned int crc,unsigned char *message,int len)
{
unsigned int word;
do
{
if((word = *(unsigned int *)message) & 0xFF)
{
crc = crc ^ word;
crc = (crc >> 8) ^ crc32_table[crc & 0xFF];
crc = (crc >> 8) ^ crc32_table[crc & 0xFF];
crc = (crc >> 8) ^ crc32_table[crc & 0xFF];
crc = (crc >> 8) ^ crc32_table[crc & 0xFF];
message = message + 4;
len--;
}
}while(len == 0);
return ~crc;
}
main()
{
unsigned int crc = 0xFFFFFFFF;
unsigned char buff[100] = ABCDEFGH;
int len; // lenght in bytes
len = (((strlen(buff)%8)==0) ? (strlen(buff)/8) : ((strlen(buff)/8)+1));
printf("lenght in bytes %d\n",len);
make_crc_table();
printf("crc = %x\n",crc32cx(crc,buff,len));
}
Can somebody help me why this is not matching with online 32 bit CRC calculator. Link given below
http://www.tahapaksu.com/crc/
For input buff=12345678, my CRC is getting matched with the online one.
For other values like buff = ABCD1234, the output is not matching.
Thanks.
The problem here is the way the code is written; let me explain:
unsigned int crc32cx(unsigned int crc,unsigned char *message,int len)
{
unsigned int word;
do
{
if((word = *(unsigned int *)message) & 0xFF)
{
crc = crc ^ word;
crc = (crc >> 8) ^ crc32_table[crc & 0xFF];
crc = (crc >> 8) ^ crc32_table[crc & 0xFF];
crc = (crc >> 8) ^ crc32_table[crc & 0xFF];
crc = (crc >> 8) ^ crc32_table[crc & 0xFF];
message = message + 4;
len--;
}
}while(len == 0);
return ~crc;
}
What this function does is to read 4 chars at a time and them compute the CRC (XOR operation); Wikipedia explains the math behind it.
But you do this operation len times
unsigned char buff[100] = ABCDEFGH;
int len; // lenght in bytes
printf("crc = %x\n",crc32cx(crc,buff,4));
So in your case, you will read 4x4 bytes; And your buffer will contain:
buff = ['A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' '\n' 'trash' 'trash'.... ]
You have 8 bytes of information, followed by a '\n' since you are assigning the buffer a string, than trash, since the buffer is allocated on the stack. And you are reading 16 bytes.
I'm sure you can spot the problem by now, but just in case, I think that crc32cx(crc,buff,2) should solve your issue.
Your CRC code is very nonstandard. When doing a table method you are suppose to input the data byte by byte, not 4 byte chunk by chunk which is definitely causing some input and logic issues. The biggest one being this line if(word = *(unsigned int *)message) & 0xFF) which is completely unnecessary and will ignore valid incoming data in some scenarios.
A nice, simple, and clean crc32 C implementation can be seen here. After looking at it and yours and making a few tweaks it worked.
In your function you would change the loop and your variable to:
unsigned char word;
do
{
word = *message;
crc = crc ^ word;
crc = (crc >> 8) ^ crc32_table[crc & 0xFF];
message++;
len--;
}while(len > 0);
And now in your main you can find the length of your input data just using len = strlen(buff).
I implemented a CRC32 algorithm in C but after hours of looking around and trying to fix it, it still doesn't work. It compiles but the checksum is not the same as in several online CRC calculators. I suspect the error to be in the line "if (0 != (character & j))" but don't understand it, since it is even mainly the same as the code on wikipedia.
wikipedia
int CRC32_C(char *message){
int length, i, j;
unsigned long p,g;
char character;
p = 0x00000000;
g = 0x04C11DB7;
length = strlen(message);
for (i = 0; i < length; i++){
character=*message;
//iterieren durch die bits jedes zeichens
for (j= 0x80; j != 0; j >>= 1){
//(p & 0x80000000)? 1 : 0)
if (0 != (character & j))
p = (p << 1) ^ g;
else
p <<=1;
}
message++;
}
return p;
}
//sample main
int main(char ** argv, int argc){
char *msg;
int p;
msg = "HALLO";
p = CRC32_C(msg);
printf("p ist 0x%x \n", p);
return 0;
}
Sample input: "HALLO"
Expected result: 0x4E26F361 (according to this page, which uses the same generator polynomial, as seen at the bottom of the page)
Actual result: 0xc25a747d
#chux: I tried removing the "0 !=" in the if clause, but it didn't change the result.
CRC32_C simply stands for "Implemented in C". As the Generator polynomial suggests, it is standard Ethernet.
Thanks for your help
The CRC may be msb to lsb or lsb to msb, and the generator polynomial may be different in the online examples. CRC32_F is msb to lsb, CRC32_R is lsb to msb (with the polynomial reversed). If you can find an online CRC calculator that takes hex, try using hex 01 to test for msb to lsb, or hex 80 to test for lsb to msb. Other variations initialize the crc to 0xffffffff and/or invert (not) the crc after calculating the crc. Looking at a description of ethernet crc, try using CRC32_R, but change the initialization of crc to crc = 0xfffffffful; .
unsigned long CRC32_F(unsigned char *message, size_t length){
size_t i, j;
unsigned long crc,gnp;
crc = 0x00000000ul;
gnp = 0x04C11DB7ul;
for (i = 0; i < length; i++){
crc ^= ((unsigned long)*message)<<24;
for (j = 0; j < 8; j++){
if (crc & 0x80000000ul)
crc = (crc << 1) ^ gnp;
else
crc = (crc << 1);
}
message++;
}
return crc;
}
unsigned long CRC32_R(unsigned char *message, size_t length){
size_t i, j;
unsigned long crc,gnp;
crc = 0x00000000ul;
gnp = 0xEDB88320ul;
for (i = 0; i < length; i++){
crc ^= ((unsigned long)*message)<<0;
for (j = 0; j < 8; j++){
if (crc & 0x00000001ul)
crc = (crc >> 1) ^ gnp;
else
crc = (crc >> 1);
}
message++;
}
return crc;
}
This will generate the CRC 0x4E26F361 from HALLO:
#include <stddef.h>
#include <stdint.h>
/* CRC-32 (Ethernet, ZIP, etc.) polynomial in reversed bit order. */
#define POLY 0xedb88320
/* Compute CRC of buf[0..len-1] with initial CRC of crc. Start
with crc == 0. */
uint32_t crc32c(uint32_t crc, const unsigned char *buf, size_t len)
{
int k;
crc = ~crc;
while (len--) {
crc ^= *buf++;
for (k = 0; k < 8; k++)
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
}
return ~crc;
}
The above computes the CRC bit-by-bit, where there are faster approaches. That happens to be CRC in common use, so you can find a fast implementation in zlib, called crc32(), which is already available as an installed library in most systems.