Skip to content

Commit 6d3b1f6

Browse files
committed
Revise MbedCRC template
* Use compile-time detection of hardware CRC capability, so unneeded code and tables do not go into the image. * Add global JSON config option to allow choice between no tables, 16-entry tables or 256-entry tables for software CRC. Default set to 16-entry, reducing ROM size from previous 256-entry. * Allow manual override in template parameter to force software or bitwise CRC for a particular instance. * Micro-optimisations, particularly use of `RBIT` instruction and optimising bitwise computation using inline assembler. Incompatible changes: * Remove special-case "POLY_32BIT_REV_ANSI" - users can use standard POLY_32BIT_ANSI, which now uses the same 16-entry tables by default, or can use hardware acceleration, which was disabled for POLY_32BIT_REV_ANSI. MbedCRC<POLY_32BIT_ANSI, 32, CrcMode::TABLE> can be used to force software like POLY_32BIT_REV_ANSI. * The precomputed table for POLY_16BIT_IBM had errors - this has been corrected, but software CRC results will be different from the previous software calculation. * < 8-bit CRC results are no longer are shifted up in the output value, but placed in the lowest bits, like other sizes. This means that code performing the SD command CRC will now need to use `(crc << 1) | 1`, rather than `crc | 1`.
1 parent 8f173db commit 6d3b1f6

File tree

7 files changed

+697
-499
lines changed

7 files changed

+697
-499
lines changed

TESTS/mbed_drivers/crc/main.cpp

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,62 @@ using namespace utest::v1;
2525

2626
void test_supported_polynomials()
2727
{
28-
char test[] = "123456789";
28+
const char test[] = "123456789";
2929
uint32_t crc;
3030

3131
{
3232
MbedCRC<POLY_7BIT_SD, 7> ct;
33-
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
34-
TEST_ASSERT_EQUAL(0xEA, crc);
33+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
34+
TEST_ASSERT_EQUAL(0x75, crc);
35+
}
36+
{
37+
MbedCRC<POLY_7BIT_SD, 7> ct(0x7F, 0, false, false);
38+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
39+
TEST_ASSERT_EQUAL(0x50, crc);
40+
}
41+
{
42+
MbedCRC<POLY_7BIT_SD, 7> ct(0x2B, 0, false, false);
43+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
44+
TEST_ASSERT_EQUAL(0x3A, crc);
45+
}
46+
{
47+
MbedCRC<POLY_7BIT_SD, 7> ct(0, 0x7F, false, false);
48+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
49+
TEST_ASSERT_EQUAL(0x0A, crc);
50+
}
51+
{
52+
MbedCRC<POLY_7BIT_SD, 7> ct(0, 0x2B, false, false);
53+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
54+
TEST_ASSERT_EQUAL(0x5E, crc);
55+
}
56+
{
57+
MbedCRC<POLY_7BIT_SD, 7> ct(0, 0, true, false);
58+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
59+
TEST_ASSERT_EQUAL(0x52, crc);
60+
}
61+
{
62+
MbedCRC<POLY_7BIT_SD, 7> ct(0, 0, false, true);
63+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
64+
TEST_ASSERT_EQUAL(0x57, crc);
3565
}
3666
{
3767
MbedCRC<POLY_8BIT_CCITT, 8> ct;
38-
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
68+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
3969
TEST_ASSERT_EQUAL(0xF4, crc);
4070
}
4171
{
4272
MbedCRC<POLY_16BIT_CCITT, 16> ct;
43-
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
73+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
4474
TEST_ASSERT_EQUAL(0x29B1, crc);
4575
}
4676
{
4777
MbedCRC<POLY_16BIT_IBM, 16> ct;
48-
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
78+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
4979
TEST_ASSERT_EQUAL(0xBB3D, crc);
5080
}
5181
{
5282
MbedCRC<POLY_32BIT_ANSI, 32> ct;
53-
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
83+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
5484
TEST_ASSERT_EQUAL(0xCBF43926, crc);
5585
}
5686
}
@@ -62,8 +92,8 @@ void test_partial_crc()
6292
{
6393
MbedCRC<POLY_16BIT_CCITT, 16> ct;
6494
TEST_ASSERT_EQUAL(0, ct.compute_partial_start(&crc));
65-
TEST_ASSERT_EQUAL(0, ct.compute_partial((void *)&test, 4, &crc));
66-
TEST_ASSERT_EQUAL(0, ct.compute_partial((void *)&test[4], 5, &crc));
95+
TEST_ASSERT_EQUAL(0, ct.compute_partial(test, 4, &crc));
96+
TEST_ASSERT_EQUAL(0, ct.compute_partial(&test[4], 5, &crc));
6797
TEST_ASSERT_EQUAL(0, ct.compute_partial_stop(&crc));
6898

6999
TEST_ASSERT_EQUAL(0x29B1, crc);
@@ -81,31 +111,31 @@ void test_sd_crc()
81111
test[2] = 0x00;
82112
test[3] = 0x00;
83113
test[4] = 0x00;
84-
TEST_ASSERT_EQUAL(0, crc7.compute((void *)test, 5, &crc));
85-
crc = (crc | 0x1) & 0xFF;
114+
TEST_ASSERT_EQUAL(0, crc7.compute(test, 5, &crc));
115+
crc = (crc << 1) | 0x1;
86116
TEST_ASSERT_EQUAL(0x95, crc);
87117

88118
test[0] = 0x48;
89119
test[1] = 0x00;
90120
test[2] = 0x00;
91121
test[3] = 0x01;
92122
test[4] = 0xAA;
93-
TEST_ASSERT_EQUAL(0, crc7.compute((void *)test, 5, &crc));
94-
crc = (crc | 0x1) & 0xFF;
123+
TEST_ASSERT_EQUAL(0, crc7.compute(test, 5, &crc));
124+
crc = (crc << 1) | 0x1;
95125
TEST_ASSERT_EQUAL(0x87, crc);
96126

97127
test[0] = 0x51;
98128
test[1] = 0x00;
99129
test[2] = 0x00;
100130
test[3] = 0x00;
101131
test[4] = 0x00;
102-
TEST_ASSERT_EQUAL(0, crc7.compute((void *)test, 5, &crc));
103-
crc = (crc | 0x1) & 0xFF;
132+
TEST_ASSERT_EQUAL(0, crc7.compute(test, 5, &crc));
133+
crc = (crc << 1) | 0x1;
104134
TEST_ASSERT_EQUAL(0x55, crc);
105135

106136
MbedCRC<POLY_16BIT_CCITT, 16> crc16(0, 0, false, false);
107137
memset(test, 0xFF, 512);
108-
TEST_ASSERT_EQUAL(0, crc16.compute((void *)test, 512, &crc));
138+
TEST_ASSERT_EQUAL(0, crc16.compute(test, 512, &crc));
109139
TEST_ASSERT_EQUAL(0x7FA1, crc);
110140
}
111141

@@ -115,12 +145,12 @@ void test_any_polynomial()
115145
uint32_t crc;
116146
{
117147
MbedCRC<0x3D65, 16> ct(0x0, 0xFFFF, 0, 0);
118-
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
148+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
119149
TEST_ASSERT_EQUAL(0xC2B7, crc);
120150
}
121151
{
122152
MbedCRC<0x1EDC6F41, 32> ct(0xFFFFFFFF, 0xFFFFFFFF, 1, 1);
123-
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
153+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
124154
TEST_ASSERT_EQUAL(0xE3069283, crc);
125155
}
126156
}
@@ -130,7 +160,7 @@ void test_thread(void)
130160
char test[] = "123456789";
131161
uint32_t crc;
132162
MbedCRC<POLY_32BIT_ANSI, 32> ct;
133-
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
163+
TEST_ASSERT_EQUAL(0, ct.compute(test, strlen(test), &crc));
134164
TEST_ASSERT_EQUAL(0xCBF43926, crc);
135165
}
136166

@@ -143,11 +173,11 @@ void test_thread_safety()
143173
MbedCRC<POLY_16BIT_IBM, 16> ct;
144174

145175
TEST_ASSERT_EQUAL(0, ct.compute_partial_start(&crc));
146-
TEST_ASSERT_EQUAL(0, ct.compute_partial((void *)&test, 4, &crc));
176+
TEST_ASSERT_EQUAL(0, ct.compute_partial(test, 4, &crc));
147177

148178
Thread t1(osPriorityNormal1, 380);
149179
t1.start(callback(test_thread));
150-
TEST_ASSERT_EQUAL(0, ct.compute_partial((void *)&test[4], 5, &crc));
180+
TEST_ASSERT_EQUAL(0, ct.compute_partial(&test[4], 5, &crc));
151181
TEST_ASSERT_EQUAL(0, ct.compute_partial_stop(&crc));
152182
TEST_ASSERT_EQUAL(0xBB3D, crc);
153183

UNITTESTS/target_h/cmsis.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,19 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17+
18+
#ifndef MBED_CMSIS_H
19+
#define MBED_CMSIS_H
20+
21+
#include <stdint.h>
22+
static inline uint32_t __RBIT(uint32_t x)
23+
{
24+
x = ((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1);
25+
x = ((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2);
26+
x = ((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4);
27+
x = ((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8);
28+
x = (x >> 16) | (x << 16);
29+
return x;
30+
}
31+
32+
#endif

0 commit comments

Comments
 (0)