Skip to content

ucrc16: provide lightweight CRC16 implementation#6112

Merged
LudwigKnuepfer merged 2 commits intoRIOT-OS:masterfrom
miri64:checksum/feat/ucrc16
Dec 27, 2016
Merged

ucrc16: provide lightweight CRC16 implementation#6112
LudwigKnuepfer merged 2 commits intoRIOT-OS:masterfrom
miri64:checksum/feat/ucrc16

Conversation

@miri64
Copy link
Copy Markdown
Member

@miri64 miri64 commented Nov 13, 2016

This is a more flexible, but lightweight (due to not using lookup-tables) alternative to crc16_ccitt. Might also be extendable for #5471.

@miri64 miri64 added the Type: new feature The issue requests / The PR implemements a new feature for RIOT label Nov 13, 2016
@miri64 miri64 added this to the Release 2017.01 milestone Nov 13, 2016
@miri64 miri64 force-pushed the checksum/feat/ucrc16 branch 2 times, most recently from 31a0166 to cc0f975 Compare November 13, 2016 02:38
@LudwigKnuepfer
Copy link
Copy Markdown
Member

LudwigKnuepfer commented Nov 13, 2016

Some thoughts:

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Nov 13, 2016

Some thoughts:

  • where is the algorithm from?

This is pretty much the standard version of the algorithm (the table version is the special optimized one ;-)), so you find it in any standard literature on the topic. In my case it's from Wikipedia, but its also e.g. written down in the reference you gave in your unittests for CRC16-CCITT. (OT: For what is that particular implementation for? The seed you used isn't mention in any spec I saw).

  • how does code size compare?

With cosy (from the unittests) on iotlab-m3:

module                                                          text    data     bss     dec     hex
------------------------------------------------------------------------------------------
[…]
.... .... _crc16_lookuptable                                     512       0       0     512     200
.... .... crc16_ccitt_update                                      36       0       0      36      24
[…]
.... .... ucrc16_calc_le                                          40       0       0      40      28
.... .... ucrc16_calc_be                                          42       0       0      42      2a
.... .... crc16_ccitt_calc                                        12       0       0      12       c

on samr21-xpro:

.... .... _crc16_lookuptable                                     512       0       0     512     200
.... .... crc16_ccitt_update                                      36       0       0      36      24
[…]
.... .... ucrc16_calc_le                                          42       0       0      42      2a
.... .... ucrc16_calc_be                                          46       0       0      46      2e
.... .... crc16_ccitt_calc                                        20       0       0      20      14

on z1:

.... .... _crc16_lookuptable                                     512       0       0     512     200
[…]
.... .... crc16_ccitt_update                                      34       0       0      34      22
[…]
.... .... ucrc16_calc_le                                          44       0       0      44      2c
.... .... ucrc16_calc_be                                          72       0       0      72      48
.... .... crc16_ccitt_calc                                        14       0       0      14       e

So the sizes of the actual code are comparable with the lookup-table being the caveat of the table version (which also grows linear if e.g. two CRC versions are present in the code).

  • how does the runtime compare (a bit more concrete would be nice ;-))?

Did not test, but since the table-version goes byte-wise, while the non-table-version goes bit-wise, it is expected, that the non-table-version is 8 times slower ;-).

  • I think it would make sense to add a ucrc16_calc that uses the hosts endianness (so that we can have platform independent code using this API)

This makes no sense at all IMHO. In most use-cases relevant for RIOT CRC is used to calculate a checksum for a packet going over the wire (mostly e.g. for PPP in big endian, for IEEE 802.15.4 in little endian).

Can do, but the simple explanation is: if you don't have memory (especially if your code demands more than one flavor of CRC16): use ucrc16. Else use crc16_ccitt (with caution).

Or to quote Wikipedia:

This [version] is usually the most compact software implementation, used in microcontrollers when space is at a premium over speed.

So exactly what most of our target platforms are ;-)

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Nov 13, 2016

Can do, but the simple explanation is: if you don't have memory (especially if your code demands more than one flavor of CRC16): use ucrc16. Else use crc16_ccitt (with caution).

Done

@LudwigKnuepfer
Copy link
Copy Markdown
Member

  • I think it would make sense to add a ucrc16_calc that uses the hosts endianness (so that we can have platform independent code using this API)

This makes no sense at all IMHO. In most use-cases relevant for RIOT CRC is used to calculate a checksum for a packet going over the wire (mostly e.g. for PPP in big endian, for IEEE 802.15.4 in little endian).

CRCs are also used for integrity checks on (RAM, ROM, flash etc.) memory. So IMHO this is a relevant use-case. There is just no code in RIOT yet that does this ;)

@LudwigKnuepfer
Copy link
Copy Markdown
Member

(OT: For what is that particular implementation for? The seed you used isn't mention in any spec I saw).

I can not answer your question anymore and don't have time to re-research but googling around a bit you will find some indication that it actually exists outside RIOT..

@miri64 miri64 added the Community: Hack'n'ACK candidate This PR is a candidate for review and discussion during one of RIOT's monthly Hack'n'ACK parties label Nov 29, 2016
@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Nov 29, 2016

CRCs are also used for integrity checks on (RAM, ROM, flash etc.) memory. So IMHO this is a relevant use-case. There is just no code in RIOT yet that does this ;)

True, but then it really doesn't matter what byteorder you choose as long as you use the same function for calculating and checking the checksum. => The default could always be _be (or _le) since it is only used locally (if not you need to decide on a byte-order again).

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Nov 29, 2016

Anyway, would be happy to see this (and maybe #6121?) merged at today's Hack'n"ACK

@miri64 miri64 added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Nov 29, 2016
@LudwigKnuepfer
Copy link
Copy Markdown
Member

CRCs are also used for integrity checks on (RAM, ROM, flash etc.) memory. So IMHO this is a relevant use-case. There is just no code in RIOT yet that does this ;)

True, but then it really doesn't matter what byteorder you choose as long as you use the same function for calculating and checking the checksum. => The default could always be _be (or _le) since it is only used locally (if not you need to decide on a byte-order again).

I am still not convinced, but if you don't want to do it at this point that's fine with me.

@miri64 miri64 force-pushed the checksum/feat/ucrc16 branch from 17d6420 to 56f33b5 Compare December 3, 2016 13:28
@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Dec 3, 2016

Squashed

@miri64 miri64 force-pushed the checksum/feat/ucrc16 branch from 56f33b5 to f80615d Compare December 5, 2016 10:47
@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Dec 5, 2016

Excluded more boards from linking the unittests and squashed immediately.

* flavor of CRC16 (polynomial @$ x^{16} + x^{12} + x^{5} + 1 @$) for big-endian
* numbers with starting seed `0x1d0f` (though others can be provided), while
* @ref sys_checksum_ucrc16 is more generalized, since it takes the
* hexadecimal representation as a parameter and provides functions and
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reading this again after a while I think it makes sense to specify: the hex representation of what?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@LudwigKnuepfer
Copy link
Copy Markdown
Member

@miri64 this PR needs love

@OlegHahm
Copy link
Copy Markdown
Member

And would be a better time of the year for that? ;-)

@miri64 miri64 force-pushed the checksum/feat/ucrc16 branch from 4d8e0de to d9dafeb Compare December 26, 2016 23:58
@miri64 miri64 force-pushed the checksum/feat/ucrc16 branch from d9dafeb to 71f778a Compare December 26, 2016 23:58
@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Dec 26, 2016

PR loved ;-)

@LudwigKnuepfer LudwigKnuepfer merged commit ff2d23b into RIOT-OS:master Dec 27, 2016
@miri64 miri64 deleted the checksum/feat/ucrc16 branch December 27, 2016 10:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Community: Hack'n'ACK candidate This PR is a candidate for review and discussion during one of RIOT's monthly Hack'n'ACK parties Type: new feature The issue requests / The PR implemements a new feature for RIOT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants