Skip to content

Commit 26e95fa

Browse files
henrikbrixandersencarlescufi
authored andcommitted
tests: drivers: can: timing: convert to the new ztest framework
Convert the CAN timing test to the new ztest framework. Restructure the tests a bit to improve code readability and add doxygen documentation. Signed-off-by: Henrik Brix Andersen <[email protected]>
1 parent 8ef4832 commit 26e95fa

File tree

2 files changed

+166
-83
lines changed

2 files changed

+166
-83
lines changed

tests/drivers/can/timing/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
CONFIG_CAN=y
22
CONFIG_ZTEST=y
3+
CONFIG_ZTEST_NEW_API=y
Lines changed: 165 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,212 @@
11
/*
2+
* Copyright (c) 2022 Vestas Wind Systems A/S
23
* Copyright (c) 2019 Alexander Wachter
34
*
45
* SPDX-License-Identifier: Apache-2.0
56
*/
7+
68
#include <drivers/can.h>
79
#include <ztest.h>
810
#include <strings.h>
911

10-
/*
11-
* @addtogroup t_can_driver
12+
/**
13+
* @addtogroup t_driver_can
1214
* @{
13-
* @defgroup t_can_timing test_basic_can_timing
14-
* @brief TestPurpose: verify timing algorithm
15-
* @details
16-
* - Test Steps
17-
* -# Calculate timing for a sample
18-
* -# Verify sample point
19-
* -# verify bitrate
20-
* - Expected Results
21-
* -# All tests MUST pass
15+
* @defgroup t_can_timing test_can_timing
2216
* @}
2317
*/
2418

25-
const struct device *can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
19+
/**
20+
* @brief Allowed sample point calculation margin in permille.
21+
*/
22+
#define SAMPLE_POINT_MARGIN 100
2623

27-
struct timing_samples {
24+
/**
25+
* @brief Defines a set of CAN timing test values
26+
*/
27+
struct can_timing_test {
28+
/** Desired bitrate in bits/s */
2829
uint32_t bitrate;
30+
/** Desired sample point in permille */
2931
uint16_t sp;
30-
bool inval;
32+
/** Do these values represent an invalid CAN timing? */
33+
bool invalid;
3134
};
3235

33-
const struct timing_samples samples[] = {
34-
{125000, 875, false},
35-
{500000, 875, false},
36-
{1000000, 875, false},
37-
{125000, 900, false},
38-
{125000, 800, false},
36+
/**
37+
* @brief List of CAN timing values to test.
38+
*/
39+
static const struct can_timing_test can_timing_tests[] = {
40+
/** Standard bitrates. */
41+
{ 125000, 875, false },
42+
{ 500000, 875, false },
43+
{ 1000000, 875, false },
44+
/** Additional, valid sample points. */
45+
{ 125000, 900, false },
46+
{ 125000, 800, false },
47+
/** Valid bitrate, invalid sample point. */
48+
{ 125000, 1000, true },
3949
#ifdef CONFIG_CAN_FD_MODE
40-
{1000000 + 1, 875, true},
41-
#else
42-
{8000000 + 1, 875, true},
43-
#endif
44-
{125000, 1000, true},
50+
/** Invalid CAN-FD bitrate, valid sample point. */
51+
{ 8000000 + 1, 875, true },
52+
#else /* CONFIG_CAN_FD_MODE */
53+
/** Invalid classical bitrate, valid sample point. */
54+
{ 1000000 + 1, 875, true },
55+
#endif /* CONFIG_CAN_FD_MODE */
4556
};
4657

47-
/*
48-
* Bitrate must match exactly
58+
/**
59+
* @brief CAN timing test fixture
60+
*/
61+
struct can_timing_tests_fixture {
62+
/** CAN device. */
63+
const struct device *dev;
64+
/** List of CAN timing test values. */
65+
const struct can_timing_test *tests;
66+
/** Number of CAN timing test list entries. */
67+
const size_t test_count;
68+
};
69+
70+
/**
71+
* @brief CAN timing test fixture instance common to all test cases
72+
*/
73+
static struct can_timing_tests_fixture test_fixture = {
74+
.dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus)),
75+
.tests = can_timing_tests,
76+
.test_count = ARRAY_SIZE(can_timing_tests),
77+
};
78+
79+
/**
80+
* @brief CAN timing test setup function
81+
*
82+
* Asserts that the CAN device is ready before starting tests.
83+
*
84+
* @return Pointer to CAN timing test fixture instance
85+
*/
86+
static void *can_timing_test_setup(void)
87+
{
88+
zassert_true(device_is_ready(test_fixture.dev), "CAN device not ready");
89+
printk("testing on device %s\n", test_fixture.dev->name);
90+
91+
return &test_fixture;
92+
}
93+
94+
ZTEST_SUITE(can_timing_tests, NULL, can_timing_test_setup, NULL, NULL, NULL);
95+
96+
/**
97+
* @brief Assert that a CAN timing struct matches the specified bitrate
98+
*
99+
* Assert that the values of a CAN timing struct matches the specified bitrate
100+
* for a given CAN controller device instance.
101+
*
102+
* @param dev pointer to the device structure for the driver instance
103+
* @param timing pointer to the CAN timing struct
104+
* @param bitrate the CAN bitrate in bits/s
49105
*/
50-
static void verify_bitrate(struct can_timing *timing, uint32_t bitrate)
106+
static void assert_bitrate_correct(const struct device *dev, struct can_timing *timing,
107+
uint32_t bitrate)
51108
{
52-
const uint32_t ts = 1 + timing->prop_seg + timing->phase_seg1 +
53-
timing->phase_seg2;
109+
const uint32_t ts = 1 + timing->prop_seg + timing->phase_seg1 + timing->phase_seg2;
54110
uint32_t core_clock;
55111
uint32_t bitrate_calc;
56-
int ret;
112+
int err;
57113

58-
zassert_not_equal(timing->prescaler, 0, "Prescaler is zero");
114+
zassert_not_equal(timing->prescaler, 0, "prescaler is zero");
59115

60-
ret = can_get_core_clock(can_dev, &core_clock);
61-
zassert_equal(ret, 0, "Unable to get core clock");
116+
err = can_get_core_clock(dev, &core_clock);
117+
zassert_equal(err, 0, "failed to get core CAN clock");
62118

63119
bitrate_calc = core_clock / timing->prescaler / ts;
64-
zassert_equal(bitrate, bitrate_calc, "Bitrate missmatch");
120+
zassert_equal(bitrate, bitrate_calc, "bitrate mismatch");
65121
}
66122

67-
/*
68-
* SP must be withing the margin and in bound of the limits
123+
/**
124+
* @brief Assert that a CAN timing struct is within the bounds
125+
*
126+
* Assert that the values of a CAN timing struct are within the bounds for a
127+
* given CAN controller device instance.
128+
*
129+
* @param dev pointer to the device structure for the driver instance
130+
* @param timing pointer to the CAN timing struct
69131
*/
70-
static void verify_sp(struct can_timing *timing, uint16_t sp,
71-
uint16_t sp_margin)
132+
static void assert_timing_within_bounds(const struct device *dev, struct can_timing *timing)
72133
{
73-
const struct can_driver_api *api =
74-
(const struct can_driver_api *)can_dev->api;
134+
const struct can_driver_api *api = (const struct can_driver_api *)dev->api;
75135
const struct can_timing *max = &api->timing_max;
76136
const struct can_timing *min = &api->timing_min;
77-
uint32_t ts = 1 + timing->prop_seg + timing->phase_seg1 +
78-
timing->phase_seg2;
79-
uint16_t sp_calc =
80-
((1 + timing->prop_seg + timing->phase_seg1) * 1000) / ts;
81137

82138
zassert_true(timing->prop_seg <= max->prop_seg, "prop_seg exceeds max");
83-
zassert_true(timing->phase_seg1 <= max->phase_seg1,
84-
"phase_seg1 exceeds max");
85-
zassert_true(timing->phase_seg2 <= max->phase_seg2,
86-
"phase_seg2 exceeds max");
87-
zassert_true(timing->prop_seg >= min->prop_seg,
88-
"prop_seg lower than min");
89-
zassert_true(timing->phase_seg1 >= min->phase_seg1,
90-
"phase_seg1 lower than min");
91-
zassert_true(timing->phase_seg2 >= min->phase_seg2,
92-
"phase_seg2 lower than min");
93-
94-
zassert_within(sp, sp_calc, sp_margin, "SP error %d [%d] not within %d",
95-
sp_calc, sp, sp_margin);
139+
zassert_true(timing->phase_seg1 <= max->phase_seg1, "phase_seg1 exceeds max");
140+
zassert_true(timing->phase_seg2 <= max->phase_seg2, "phase_seg2 exceeds max");
141+
142+
zassert_true(timing->prop_seg >= min->prop_seg, "prop_seg lower than min");
143+
zassert_true(timing->phase_seg1 >= min->phase_seg1, "phase_seg1 lower than min");
144+
zassert_true(timing->phase_seg2 >= min->phase_seg2, "phase_seg2 lower than min");
96145
}
97146

98-
/*
99-
* Verify the result of the algorithm
147+
/**
148+
* @brief Assert that a sample point is within a specified margin
149+
*
150+
* Assert that values of a CAN timing struct results in a specified sample point
151+
* within a given margin.
152+
*
153+
* @param timing pointer to the CAN timing struct
154+
* @param sp sample point in permille
155+
* @param sp_margin sample point margin in permille
100156
*/
101-
static void test_verify_algo(void)
157+
static void assert_sp_within_margin(struct can_timing *timing, uint16_t sp, uint16_t sp_margin)
102158
{
103-
struct can_timing timing = {0};
104-
int ret;
105-
106-
for (int i = 0; i < ARRAY_SIZE(samples); ++i) {
107-
ret = can_calc_timing(can_dev, &timing, samples[i].bitrate,
108-
samples[i].sp);
109-
if (samples[i].inval) {
110-
zassert_equal(ret, -EINVAL,
111-
"ret value %d not -EINVAL", ret);
112-
continue;
113-
}
114-
115-
zassert_true(ret >= 0, "Unknown error %d", ret);
116-
/* For the given values, we expect a sp error < 10% */
117-
zassert_true(ret < 100, "Huge sample point error %d", ret);
118-
verify_sp(&timing, samples[i].sp, ret);
119-
verify_bitrate(&timing, samples[i].bitrate);
159+
const uint32_t ts = 1 + timing->prop_seg + timing->phase_seg1 + timing->phase_seg2;
160+
const uint16_t sp_calc = ((1 + timing->prop_seg + timing->phase_seg1) * 1000) / ts;
161+
162+
zassert_within(sp, sp_calc, sp_margin,
163+
"sample point %d not within calculated sample point %d +/- %d",
164+
sp, sp_calc, sp_margin);
165+
}
166+
167+
/**
168+
* @brief Test a set of CAN timing values
169+
*
170+
* Test a set of CAN timing values on a specified CAN controller device
171+
* instance.
172+
*
173+
* @param dev pointer to the device structure for the driver instance
174+
* @param test pointer to the set of CAN timing values
175+
*/
176+
static void test_timing_values(const struct device *dev, const struct can_timing_test *test)
177+
{
178+
struct can_timing timing = { 0 };
179+
int err;
180+
181+
printk("testing bitrate %u, sample point %u.%u%% (%s): ",
182+
test->bitrate, test->sp / 10, test->sp % 10, test->invalid ? "invalid" : "valid");
183+
184+
err = can_calc_timing(dev, &timing, test->bitrate, test->sp);
185+
if (test->invalid) {
186+
zassert_equal(err, -EINVAL, "err %d, expected -EINVAL", err);
187+
printk("OK\n");
188+
} else {
189+
zassert_true(err >= 0, "unknown error %d", err);
190+
zassert_true(err <= SAMPLE_POINT_MARGIN, "sample point error %d too large", err);
191+
192+
assert_bitrate_correct(dev, &timing, test->bitrate);
193+
assert_timing_within_bounds(dev, &timing);
194+
assert_sp_within_margin(&timing, test->sp, SAMPLE_POINT_MARGIN);
195+
196+
printk("OK, sample point error %d.%d%%\n", err / 10, err % 10);
120197
}
121198
}
122199

123-
void test_main(void)
200+
/**
201+
* @brief Test all CAN timing values
202+
*
203+
* @param this Pointer to a CAN timing test fixture
204+
*/
205+
ZTEST_F(can_timing_tests, test_timing)
124206
{
125-
zassert_true(device_is_ready(can_dev), "CAN device not ready");
207+
int i;
126208

127-
ztest_test_suite(can_timing,
128-
ztest_unit_test(test_verify_algo));
129-
ztest_run_test_suite(can_timing);
209+
for (i = 0; i < this->test_count; i++) {
210+
test_timing_values(this->dev, &this->tests[i]);
211+
}
130212
}

0 commit comments

Comments
 (0)