Fastest way to compare specific bytes in Packet for validation - Page 1
Forum section: electronics / general

author: sangar
author_rank: Regular Contributor
timestamp: June 05, 2017, 10:43:59 am
content: Hello All,I am working on a wireless project. In this, Receiver receives packets which have payload size of 80 bytes from multiple transmitters. Before transmit these packets to PC, Receiver has to validate each packets because there is the chance for Packet corruption. I am using 7 bytes of Last 10 bytes in the 80 bytes to see if packet is corrupted. Receiver has to check this 7 bytes. It will only sent if 7 byte match occurs.My last 10 bytes are FF FF FF FF 01 00 00 FF FF FFIn this first four bytes and Last 3 bytes are fixed (FF bytes) and in between 3 bytes have time infromation.Bytes to be compared is First 4 bytes and Last 3 bytes.This comparison code should be fast as the inetrval between packets to be received very small.Anyone can suggest C code for this?Thanks,Muthu

author: Rerouter
author_rank: Super Contributor
timestamp: June 05, 2017, 11:54:19 am
content: Your probably going to need to give us some more insight into your current receiving code,But at a guess, have a byte value acting as a bytes recieved since packet start character, it gets incremented every time you read in a byte,When you get to the right number of bytes, compare the current byte with 0xFF and increment a pass counter that gets reset each new packet,something like If(bytecount > 69) { If(bytecount < 74 || bytecount > 76) { If(0xFF == currentbyte) {Correct ++}}}If(Correct == 7) {Pass}This is just sudocode, you will need to format in nicer for it to work, but in this case you loose a cycle or 2 to increment the bytecount each byte, you loose a cycle or 2 for the first if statement result each byte recieved, its only when you get to the part you actually want to check that it burns through a few more cycles.I'm using an "OR'd " if statement just to wrap both ranges into 1, this should pass through to checking only for those bytes,

author: AndyC_772
author_rank: Super Contributor
timestamp: June 05, 2017, 12:24:51 pm
content: How does this check that the useful data hasn't been corrupted? Is there an underlying CRC or other check being done in hardware first?

author: sokoloff
author_rank: Super Contributor
timestamp: June 05, 2017, 12:39:42 pm
content: Quote from: AndyC_772 on June 05, 2017, 12:24:51 pmAgreed. If you control both ends, I'd look into a CRC to do a deeper "this packet wasn't  corrupted". Those can be done quickly with just simple integer math. Look at XModem protocol as one simple example.You could keep some "hard coded" framing indicators and add CRC, keeping the overall packet length the same.None of these inline algorithms are likely to run slower than the radio transmission.

author: Buriedcode
author_rank: Super Contributor
timestamp: June 05, 2017, 12:47:56 pm
content: Fastest way I can think of is the most obvious: You have a table of your hard-coded values, and the last packet received. A simple loop that compares the two, and a break if there isn't a match.Generally compilers are pretty good at optimising, but back in the day when I used assembly with AVR's and PIC's, the fastest way to compare two bytes was to XOR them, and check for 0.

author: brucehoult
author_rank: Super Contributor
timestamp: June 05, 2017, 12:49:49 pm
content: You don't say what CPU you're using, and whether it is 8, 16, 32 or 64 bits or whatever. rerouter gives some good ideas.Probably it doesn't matter how you do it, CPUs are so fast.If you're going to use a series of tests, as rerouter suggests, then if possible put the ones most likely to fail first. Tests and branches on microcontrollers are often slow, especially taken ones.Code:for (int count=1; count<=80; ++count){byte b = readbyte();//...if (b != 255) continue;if (count < 70) continue;if (count > 73 && count < 77) continue;++correct;}if (correct != 7) error();But probably it's faster to do it without branches:Code:short mask = 0;for (int count=1; count<=80; ++count){byte b = readbyte();mask <<= 1;if (b == 255) mask |= 1;}short check = 0b1111000111; // GNU extension, otherwise 0x3C7if ((mask & check) != check) error();If your CPU has predication (e.g. ARM/Thumb2), conditional select ARM64, conditional move (X86), or conditional set (x86, MIPS, ARM64, RISC-V) then updating mask inside the loop doesn't need any branches and should be really fast.But the whole idea seems kinda dumb to me. Why not do a simple checksum over the entire packet? That won't need any branches inside the loop either.

author: sangar
author_rank: Regular Contributor
timestamp: June 08, 2017, 04:20:25 am
content: Hello All,I forgot to enable CRC checking in the wireless stack. After enabling this, I haven't seen any packet corruption yet. Thanks all for your inputs.Thanks,Muthu