Skip to content

Commit 7106ea3

Browse files
author
Zoe Kaute
committed
tests: drivers: crc: Add test suite for hardware-based CRC API
Add a test suite to validate the hardware-based CRC API. Signed-off-by: Zoe Kaute <zoe.kaute@brillpower.com>
1 parent d99de4a commit 7106ea3

File tree

4 files changed

+233
-0
lines changed

4 files changed

+233
-0
lines changed

tests/drivers/crc/CMakeLists.txt

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

tests/drivers/crc/prj.conf

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

tests/drivers/crc/src/main.c

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
/*
2+
* Copyright (c) 2024 Brill Power Ltd.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/drivers/crc.h>
8+
#include <zephyr/device.h>
9+
#include <zephyr/kernel.h>
10+
#include <zephyr/ztest.h>
11+
12+
#define WAIT_THREAD_STACK_SIZE 1024
13+
#define WAIT_THREAD_PRIO -10
14+
15+
static void wait_thread_entry(void *a, void *b, void *c);
16+
17+
K_THREAD_STACK_DEFINE(wait_thread_stack_area, WAIT_THREAD_STACK_SIZE);
18+
struct k_thread wait_thread_data;
19+
20+
/**
21+
* 1) Take the semaphore
22+
* 2) Sleep for 50 ms (to allow ztest main thread to attempt to acquire semaphore)
23+
* 3) Give the semaphore
24+
*/
25+
static void wait_thread_entry(void *a, void *b, void *c)
26+
{
27+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
28+
29+
uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4};
30+
31+
struct crc_ctx ctx = {.type = CRC8_CCITT_HW,
32+
.flags = 0,
33+
.polynomial = CRC8_CCITT_POLY,
34+
.initial_value = CRC8_CCITT_INIT_VAL};
35+
36+
crc_begin(dev, &ctx);
37+
38+
k_sleep(K_MSEC(50));
39+
40+
crc_update(dev, &ctx, data, sizeof(data));
41+
crc_finish(dev, &ctx);
42+
zassert_equal(crc_verify(&ctx, 0x4D), 0);
43+
}
44+
45+
/**
46+
* @brief Test that crc_8_ccitt works
47+
*/
48+
ZTEST(crc, test_crc_8_ccitt)
49+
{
50+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
51+
52+
uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4};
53+
54+
struct crc_ctx ctx = {.type = CRC8_CCITT_HW,
55+
.flags = 0,
56+
.polynomial = CRC8_CCITT_POLY,
57+
.initial_value = CRC8_CCITT_INIT_VAL};
58+
59+
zassert_equal(crc_begin(dev, &ctx), 0);
60+
zassert_equal(crc_update(dev, &ctx, data, sizeof(data)), 0);
61+
zassert_equal(crc_finish(dev, &ctx), 0);
62+
zassert_equal(crc_verify(&ctx, 0x4D), 0);
63+
}
64+
65+
/**
66+
* @brief Test that crc_32_ieee works
67+
*/
68+
ZTEST(crc, test_crc_32_ieee_remain_0)
69+
{
70+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
71+
uint32_t flags = CRC_FLAG_REVERSE_INPUT | CRC_FLAG_REVERSE_OUTPUT;
72+
73+
uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4};
74+
75+
struct crc_ctx ctx = {.type = CRC32_IEEE_HW,
76+
.flags = flags,
77+
.polynomial = CRC32_IEEE_POLY,
78+
.initial_value = CRC32_IEEE_INIT_VAL};
79+
80+
zassert_equal(crc_begin(dev, &ctx), 0);
81+
zassert_equal(crc_update(dev, &ctx, data, sizeof(data)), 0);
82+
zassert_equal(crc_finish(dev, &ctx), 0);
83+
zassert_equal(crc_verify(&ctx, 0xCEA4A6C2), 0);
84+
}
85+
86+
/**
87+
* @brief Test that crc_32_ieee works with a single byte
88+
* remaining after the main process loop
89+
*/
90+
ZTEST(crc, test_crc_32_ieee_remain_1)
91+
{
92+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
93+
uint32_t flags = CRC_FLAG_REVERSE_INPUT | CRC_FLAG_REVERSE_OUTPUT;
94+
95+
uint8_t data[9] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4, 0x3B};
96+
97+
struct crc_ctx ctx = {.type = CRC32_IEEE_HW,
98+
.flags = flags,
99+
.polynomial = CRC32_IEEE_POLY,
100+
.initial_value = CRC32_IEEE_INIT_VAL};
101+
102+
zassert_equal(crc_begin(dev, &ctx), 0);
103+
zassert_equal(crc_update(dev, &ctx, data, sizeof(data)), 0);
104+
zassert_equal(crc_finish(dev, &ctx), 0);
105+
zassert_equal(crc_verify(&ctx, 0x16AD0193), 0);
106+
}
107+
108+
/**
109+
* @brief Test that crc_32_ieee works with two bytes
110+
* remaining after the main process loop
111+
*/
112+
ZTEST(crc, test_crc_32_ieee_remain_2)
113+
{
114+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
115+
uint32_t flags = CRC_FLAG_REVERSE_INPUT | CRC_FLAG_REVERSE_OUTPUT;
116+
117+
uint8_t data[10] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4, 0x3B, 0x78};
118+
119+
struct crc_ctx ctx = {.type = CRC32_IEEE_HW,
120+
.flags = flags,
121+
.polynomial = CRC32_IEEE_POLY,
122+
.initial_value = CRC32_IEEE_INIT_VAL};
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+
zassert_equal(crc_verify(&ctx, 0xE5CC797C), 0);
128+
}
129+
130+
/**
131+
* @brief Test that crc_32_ieee works with three bytes
132+
* remaining after the main process loop
133+
*/
134+
ZTEST(crc, test_crc_32_ieee_remain_3)
135+
{
136+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
137+
uint32_t flags = CRC_FLAG_REVERSE_INPUT | CRC_FLAG_REVERSE_OUTPUT;
138+
139+
uint8_t data[11] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4, 0x3B, 0x78, 0xB6};
140+
141+
struct crc_ctx ctx = {.type = CRC32_IEEE_HW,
142+
.flags = flags,
143+
.polynomial = CRC32_IEEE_POLY,
144+
.initial_value = CRC32_IEEE_INIT_VAL};
145+
146+
zassert_equal(crc_begin(dev, &ctx), 0);
147+
zassert_equal(crc_update(dev, &ctx, data, sizeof(data)), 0);
148+
zassert_equal(crc_finish(dev, &ctx), 0);
149+
zassert_equal(crc_verify(&ctx, 0xA956085A), 0);
150+
}
151+
152+
/**
153+
* @brief Test CRC calculation with discontinuous buffers.
154+
*/
155+
ZTEST(crc, test_discontinuous_buf)
156+
{
157+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
158+
uint32_t flags = CRC_FLAG_REVERSE_INPUT | CRC_FLAG_REVERSE_OUTPUT;
159+
uint8_t data1[5] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E};
160+
uint8_t data2[5] = {0x49, 0x00, 0xC4, 0x3B, 0x78};
161+
162+
struct crc_ctx ctx = {.type = CRC32_IEEE_HW,
163+
.flags = flags,
164+
.polynomial = CRC32_IEEE_POLY,
165+
.initial_value = CRC32_IEEE_INIT_VAL};
166+
167+
zassert_equal(crc_begin(dev, &ctx), 0);
168+
zassert_equal(crc_update(dev, &ctx, data1, sizeof(data1)), 0);
169+
zassert_equal(crc_update(dev, &ctx, data2, sizeof(data2)), 0);
170+
zassert_equal(crc_finish(dev, &ctx), 0);
171+
zassert_equal(crc_verify(&ctx, 0xE5CC797C), 0);
172+
}
173+
174+
/**
175+
* @brief Test CRC function semaphore wait for thread safety
176+
*
177+
* Verifies that CRC operations are blocked until a semaphore is released. A new thread
178+
* acquires the semaphore, and the main thread's CRC operations wait until it is released.
179+
*/
180+
ZTEST(crc, test_crc_threadsafe)
181+
{
182+
static const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(crc));
183+
184+
uint8_t data[11] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4, 0x3B, 0x78, 0xB6};
185+
uint32_t flags = CRC_FLAG_REVERSE_INPUT | CRC_FLAG_REVERSE_OUTPUT;
186+
struct crc_ctx ctx = {.type = CRC32_IEEE_HW,
187+
.flags = flags,
188+
.polynomial = CRC32_IEEE_POLY,
189+
.initial_value = CRC32_IEEE_INIT_VAL};
190+
191+
/**
192+
* Create new thread that will immediately take the semaphore
193+
*/
194+
k_thread_create(&wait_thread_data, wait_thread_stack_area,
195+
K_THREAD_STACK_SIZEOF(wait_thread_stack_area), wait_thread_entry, NULL,
196+
NULL, NULL, WAIT_THREAD_PRIO, 0, K_NO_WAIT);
197+
198+
/**
199+
* Sleep for 10 ms to ensure that new thread has taken lock
200+
*/
201+
k_sleep(K_MSEC(10));
202+
203+
/**
204+
* Attempt to take semaphore, this should wait for the new thread to give the semaphore
205+
* before executing
206+
*/
207+
crc_begin(dev, &ctx);
208+
crc_update(dev, &ctx, data, sizeof(data));
209+
crc_finish(dev, &ctx);
210+
zassert_equal(crc_verify(&ctx, 0xA956085A), 0);
211+
}
212+
213+
ZTEST_SUITE(crc, NULL, NULL, NULL, NULL, NULL);

tests/drivers/crc/testcase.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
tests:
4+
drivers.crc:
5+
depends_on: crc
6+
tags:
7+
- drivers
8+
- crc

0 commit comments

Comments
 (0)