Skip to content

Commit 0bc91f8

Browse files
Duy Vothenguyenyf
authored andcommitted
tests: drivers: crc: add ztests for CRC driver
Add ztests for CRC driver Signed-off-by: Duy Vo <duy.vo.xc@bp.renesas.com>
1 parent 1ade790 commit 0bc91f8

File tree

4 files changed

+345
-0
lines changed

4 files changed

+345
-0
lines changed

tests/drivers/crc/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
cmake_minimum_required(VERSION 3.20.0)
2+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
3+
4+
project(drivers_crc_test)
5+
6+
target_sources(app PRIVATE src/main.c)

tests/drivers/crc/prj.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CONFIG_ZTEST=y
2+
CONFIG_CRC_NEW=y
3+
CONFIG_CRC_LOG_LEVEL_INF=y

tests/drivers/crc/src/main.c

Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
/*
2+
* Copyright (c) 2025 Renesas Electronics Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/drivers/crc.h>
8+
9+
#include <zephyr/device.h>
10+
#include <zephyr/ztest.h>
11+
#include <zephyr/logging/log.h>
12+
13+
#define WAIT_THREAD_STACK_SIZE 1024
14+
#define WAIT_THREAD_PRIO -10
15+
16+
static void wait_thread_entry(void *a, void *b, void *c);
17+
18+
K_THREAD_STACK_DEFINE(wait_thread_stack_area, WAIT_THREAD_STACK_SIZE);
19+
struct k_thread wait_thread_data;
20+
21+
/* Define result of CRC computation */
22+
#define RESULT_CRC_16_THREADSAFE 0xD543
23+
24+
/**
25+
* 1) Take the semaphore
26+
* 2) Sleep for 50 ms (to allow ztest main thread to attempt to acquire semaphore)
27+
* 3) Give the semaphore
28+
*/
29+
static void wait_thread_entry(void *a, void *b, void *c)
30+
{
31+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
32+
33+
uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4};
34+
35+
struct crc_ctx ctx = {
36+
.type = CRC16,
37+
.polynomial = CRC16_POLY,
38+
.seed = CRC16_INIT_VAL,
39+
.reversed = CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT,
40+
};
41+
42+
crc_begin(dev, &ctx);
43+
44+
k_sleep(K_MSEC(50));
45+
46+
crc_update(dev, &ctx, data, sizeof(data));
47+
crc_finish(dev, &ctx);
48+
zassert_equal(crc_verify(&ctx, RESULT_CRC_16_THREADSAFE), 0);
49+
}
50+
51+
/* Define result of CRC computation */
52+
#define RESULT_CRC_8 0xB2
53+
54+
/**
55+
* @brief Test that crc8 works
56+
*/
57+
ZTEST(crc, test_crc_8)
58+
{
59+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
60+
61+
uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4};
62+
63+
struct crc_ctx ctx = {
64+
.type = CRC8,
65+
.polynomial = CRC8_POLY,
66+
.seed = CRC8_INIT_VAL,
67+
.reversed = CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT,
68+
};
69+
70+
crc_begin(dev, &ctx);
71+
72+
k_sleep(K_MSEC(50));
73+
74+
crc_update(dev, &ctx, data, sizeof(data));
75+
crc_finish(dev, &ctx);
76+
zassert_equal(crc_verify(&ctx, RESULT_CRC_8), 0);
77+
}
78+
79+
/* Define result of CRC computation */
80+
#define RESULT_CRC_16 0xD543
81+
82+
/**
83+
* @brief Test that crc16 works
84+
*/
85+
ZTEST(crc, test_crc_16)
86+
{
87+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
88+
89+
uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4};
90+
91+
struct crc_ctx ctx = {
92+
.type = CRC16,
93+
.polynomial = CRC16_POLY,
94+
.seed = CRC16_INIT_VAL,
95+
.reversed = CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT,
96+
};
97+
98+
zassert_equal(crc_begin(dev, &ctx), 0);
99+
zassert_equal(crc_update(dev, &ctx, data, sizeof(data)), 0);
100+
zassert_equal(crc_finish(dev, &ctx), 0);
101+
102+
zassert_equal(crc_verify(&ctx, RESULT_CRC_16), 0);
103+
}
104+
105+
/* Define result of CRC computation */
106+
#define RESULT_CRC_CCITT 0x445C
107+
108+
/**
109+
* @brief Test that crc_16_ccitt works
110+
*/
111+
ZTEST(crc, test_crc_16_ccitt)
112+
{
113+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
114+
115+
uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4};
116+
117+
struct crc_ctx ctx = {
118+
.type = CRC16_CCITT,
119+
.polynomial = CRC16_CCITT_POLY,
120+
.seed = CRC16_CCITT_INIT_VAL,
121+
.reversed = CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT,
122+
};
123+
124+
zassert_equal(crc_begin(dev, &ctx), 0);
125+
zassert_equal(crc_update(dev, &ctx, data, sizeof(data)), 0);
126+
zassert_equal(crc_finish(dev, &ctx), 0);
127+
128+
zassert_equal(crc_verify(&ctx, RESULT_CRC_CCITT), 0);
129+
}
130+
131+
/* Define result of CRC computation */
132+
#define RESULT_CRC_32_C 0xBB19ECB2
133+
134+
/**
135+
* @brief Test that crc_32_c works
136+
*/
137+
ZTEST(crc, test_crc_32_c)
138+
{
139+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
140+
141+
uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4};
142+
143+
struct crc_ctx ctx = {
144+
.type = CRC32_C,
145+
.polynomial = CRC32C_POLY,
146+
.seed = CRC32_C_INIT_VAL,
147+
.reversed = CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT,
148+
};
149+
150+
zassert_equal(crc_begin(dev, &ctx), 0);
151+
zassert_equal(crc_update(dev, &ctx, data, sizeof(data)), 0);
152+
zassert_equal(crc_finish(dev, &ctx), 0);
153+
154+
zassert_equal(crc_verify(&ctx, RESULT_CRC_32_C), 0);
155+
}
156+
157+
/* Define result of CRC computation */
158+
#define RESULT_CRC_32_IEEE 0xCEA4A6C2
159+
160+
/**
161+
* @brief Test that crc_32_ieee works
162+
*/
163+
ZTEST(crc, test_crc_32_ieee)
164+
{
165+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
166+
167+
uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4};
168+
struct crc_ctx ctx = {
169+
.type = CRC32_IEEE,
170+
.polynomial = CRC32_IEEE_POLY,
171+
.seed = CRC32_IEEE_INIT_VAL,
172+
.reversed = CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT,
173+
};
174+
175+
zassert_equal(crc_begin(dev, &ctx), 0);
176+
zassert_equal(crc_update(dev, &ctx, data, sizeof(data)), 0);
177+
zassert_equal(crc_finish(dev, &ctx), 0);
178+
zassert_equal(crc_verify(&ctx, RESULT_CRC_32_IEEE), 0);
179+
}
180+
181+
/* Define result of CRC computation */
182+
#define RESULT_CRC_8_REMAIN_3 0xBB
183+
184+
/**
185+
* @brief Test that crc_8_remain_3 works
186+
*/
187+
ZTEST(crc, test_crc_8_remain_3)
188+
{
189+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
190+
191+
uint8_t data[11] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4, 0x3D, 0x4D, 0x51};
192+
193+
struct crc_ctx ctx = {
194+
.type = CRC8,
195+
.polynomial = CRC8_POLY,
196+
.seed = CRC8_INIT_VAL,
197+
.reversed = CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT,
198+
};
199+
200+
zassert_equal(crc_begin(dev, &ctx), 0);
201+
zassert_equal(crc_update(dev, &ctx, data, sizeof(data)), 0);
202+
zassert_equal(crc_finish(dev, &ctx), 0);
203+
zassert_equal(crc_verify(&ctx, RESULT_CRC_8_REMAIN_3), 0);
204+
}
205+
206+
/* Define result of CRC computation */
207+
#define RESULT_CRC_16_REMAIN_1 0x2055
208+
209+
/**
210+
* @brief Test that crc_16_remain_1 works
211+
*/
212+
ZTEST(crc, test_crc_16_remain_1)
213+
{
214+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
215+
216+
uint8_t data[9] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4, 0x3D};
217+
218+
struct crc_ctx ctx = {
219+
.type = CRC16,
220+
.polynomial = CRC16_POLY,
221+
.seed = CRC16_INIT_VAL,
222+
.reversed = CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT,
223+
};
224+
225+
zassert_equal(crc_begin(dev, &ctx), 0);
226+
zassert_equal(crc_update(dev, &ctx, data, sizeof(data)), 0);
227+
zassert_equal(crc_finish(dev, &ctx), 0);
228+
229+
zassert_equal(crc_verify(&ctx, RESULT_CRC_16_REMAIN_1), 0);
230+
}
231+
232+
/* Define result of CRC computation */
233+
#define RESULT_CRC_CCITT_REMAIN_2 0x24BD
234+
235+
/**
236+
* @brief Test that crc_16_ccitt works
237+
*/
238+
ZTEST(crc, test_crc_16_ccitt_remain_2)
239+
{
240+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
241+
242+
uint8_t data[10] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4, 0xFF, 0xA0};
243+
244+
struct crc_ctx ctx = {
245+
.type = CRC16_CCITT,
246+
.polynomial = CRC16_CCITT_POLY,
247+
.seed = CRC16_CCITT_INIT_VAL,
248+
.reversed = CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT,
249+
};
250+
251+
zassert_equal(crc_begin(dev, &ctx), 0);
252+
zassert_equal(crc_update(dev, &ctx, data, sizeof(data)), 0);
253+
zassert_equal(crc_finish(dev, &ctx), 0);
254+
255+
zassert_equal(crc_verify(&ctx, RESULT_CRC_CCITT_REMAIN_2), 0);
256+
}
257+
258+
/* Define result of CRC computation */
259+
#define RESULT_DISCONTINUOUS_BUFFER 0x75
260+
261+
/**
262+
* @brief Test CRC calculation with discontinuous buffers.
263+
*/
264+
ZTEST(crc, test_discontinuous_buf)
265+
{
266+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
267+
268+
uint8_t data1[5] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E};
269+
uint8_t data2[5] = {0x49, 0x00, 0xC4, 0x3B, 0x78};
270+
271+
struct crc_ctx ctx = {
272+
.type = CRC8,
273+
.polynomial = CRC8_POLY,
274+
.seed = CRC8_INIT_VAL,
275+
.reversed = CRC_FLAG_REVERSE_INPUT | CRC_FLAG_REVERSE_OUTPUT,
276+
};
277+
278+
zassert_equal(crc_begin(dev, &ctx), 0);
279+
zassert_equal(crc_update(dev, &ctx, data1, sizeof(data1)), 0);
280+
zassert_equal(crc_update(dev, &ctx, data2, sizeof(data2)), 0);
281+
zassert_equal(crc_finish(dev, &ctx), 0);
282+
zassert_equal(crc_verify(&ctx, RESULT_DISCONTINUOUS_BUFFER), 0);
283+
}
284+
285+
/* Define result of CRC computation */
286+
#define RESULT_CRC_8_REMAIN_3_THREADSAFE 0xBB
287+
288+
/**
289+
* @brief Test CRC function semaphore wait for thread safety
290+
*
291+
* Verifies that CRC operations are blocked until a semaphore is released. A new thread
292+
* acquires the semaphore, and the main thread's CRC operations wait until it is released.
293+
*/
294+
ZTEST(crc, test_crc_threadsafe)
295+
{
296+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
297+
298+
uint8_t data[11] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4, 0x3D, 0x4D, 0x51};
299+
300+
struct crc_ctx ctx = {
301+
.type = CRC8,
302+
.polynomial = CRC8_POLY,
303+
.seed = CRC8_INIT_VAL,
304+
.reversed = CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT,
305+
};
306+
307+
/**
308+
* Create new thread that will immediately take the semaphore
309+
*/
310+
k_thread_create(&wait_thread_data, wait_thread_stack_area,
311+
K_THREAD_STACK_SIZEOF(wait_thread_stack_area), wait_thread_entry, NULL,
312+
NULL, NULL, WAIT_THREAD_PRIO, 0, K_NO_WAIT);
313+
314+
/**
315+
* Sleep for 10 ms to ensure that new thread has taken lock
316+
*/
317+
k_sleep(K_MSEC(10));
318+
319+
/**
320+
* Attempt to take semaphore, this should wait for the new thread to give the semaphore
321+
* before executing
322+
*/
323+
crc_begin(dev, &ctx);
324+
crc_update(dev, &ctx, data, sizeof(data));
325+
crc_finish(dev, &ctx);
326+
zassert_equal(crc_verify(&ctx, RESULT_CRC_8_REMAIN_3_THREADSAFE), 0);
327+
}
328+
329+
ZTEST_SUITE(crc, NULL, NULL, NULL, NULL, NULL);

tests/drivers/crc/testcase.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
tests:
2+
drivers.crc:
3+
depends_on: crc
4+
tags:
5+
- drivers
6+
- crc
7+
harness: ztest

0 commit comments

Comments
 (0)