Skip to content

Commit 50c48b9

Browse files
committed
tests: drivers: uart: async_dual: Optimize test data handling
Stress test is executed on CPUs with slow clock (16MHz). Handling of test data in UART_RX_RDY event is optimized to reduce time spent in the interrupt context. Since payload is always a decrementing sequence, fixed array is used to compare memory which allows to use standard memcmp instead of byte by byte comparison. Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
1 parent 59f43f4 commit 50c48b9

File tree

1 file changed

+91
-58
lines changed
  • tests/drivers/uart/uart_async_dual/src

1 file changed

+91
-58
lines changed

tests/drivers/uart/uart_async_dual/src/main.c

Lines changed: 91 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,25 @@ ZTEST_DMEM struct dut_data duts[] = {
6161
#endif
6262
};
6363

64+
/* Array that contains potential payload. It is used to memcmp against incoming packets. */
65+
static const uint8_t test_buf[256] = {
66+
255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241,
67+
240, 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, 226,
68+
225, 224, 223, 222, 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, 211,
69+
210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, 196,
70+
195, 194, 193, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 181,
71+
180, 179, 178, 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, 166,
72+
165, 164, 163, 162, 161, 160, 159, 158, 157, 156, 155, 154, 153, 152, 151,
73+
150, 149, 148, 147, 146, 145, 144, 143, 142, 141, 140, 139, 138, 137, 136,
74+
135, 134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123, 122, 121,
75+
120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106,
76+
105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89,
77+
88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70,
78+
69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50,
79+
49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30,
80+
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,
81+
9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
82+
6483
static void pm_check(const struct device *dev, const struct device *second_dev, bool exp_on,
6584
int line)
6685
{
@@ -128,6 +147,8 @@ enum test_rx_mode {
128147
RX_ALL,
129148
};
130149

150+
typedef bool (*test_on_rx_rdy_t)(const struct device *dev, uint8_t *buf, size_t len);
151+
131152
struct test_rx_data {
132153
uint8_t hdr[1];
133154
uint8_t buf[256];
@@ -140,6 +161,7 @@ struct test_rx_data {
140161
struct k_sem sem;
141162
uint32_t timeout;
142163
uint32_t buf_idx;
164+
test_on_rx_rdy_t on_rx_rdy;
143165
};
144166

145167
static struct test_tx_data tx_data;
@@ -277,75 +299,86 @@ static void on_tx_done(const struct device *dev, struct uart_event *evt)
277299
try_tx(dev, true);
278300
}
279301

280-
static void on_rx_rdy(const struct device *dev, struct uart_event *evt)
302+
static bool on_rx_rdy_rx_all(const struct device *dev, uint8_t *buf, size_t len)
281303
{
282-
uint32_t len = evt->data.rx.len;
283-
uint32_t off = evt->data.rx.offset;
284-
int err;
304+
bool ok;
285305

286-
if (!rx_data.cont) {
287-
return;
306+
if (rx_data.payload_idx == 0) {
307+
rx_data.payload_idx = buf[0] - 1;
308+
buf++;
309+
len--;
288310
}
289311

290-
rx_data.rx_cnt += evt->data.rx.len;
291-
if (evt->data.rx.buf == rx_data.hdr) {
292-
if (rx_data.hdr[0] == 1) {
293-
/* single byte packet. */
294-
err = uart_rx_buf_rsp(dev, rx_data.hdr, 1);
295-
zassert_equal(err, 0);
296-
return;
312+
ok = memcmp(buf, &test_buf[256 - rx_data.payload_idx], len) == 0;
313+
rx_data.payload_idx -= len;
314+
315+
return ok;
316+
}
317+
318+
static bool on_rx_rdy_hdr(const struct device *dev, uint8_t *buf, size_t len);
319+
320+
static bool on_rx_rdy_payload(const struct device *dev, uint8_t *buf, size_t len)
321+
{
322+
bool ok;
323+
int err;
324+
325+
ok = memcmp(buf, &test_buf[255 - rx_data.payload_idx], len) == 0;
326+
if (!ok) {
327+
for (int i = 0; i < len; i++) {
328+
if (buf[i] != test_buf[255 - rx_data.payload_idx + i]) {
329+
zassert_true(false, "Byte %d expected: %02x got: %02x",
330+
i, buf[i], test_buf[255 - rx_data.payload_idx + i]);
331+
}
297332
}
333+
rx_data.cont = false;
334+
tx_data.cont = false;
335+
zassert_true(ok);
336+
return false;
337+
}
298338

299-
zassert_equal(rx_data.payload_idx, 0);
300-
rx_data.state = RX_PAYLOAD;
301-
rx_data.payload_idx = rx_data.hdr[0] - 1;
302-
if ((rx_data.mode == RX_CONT) && rx_data.buf_req) {
303-
size_t l = rx_data.hdr[0] - 1;
339+
rx_data.payload_idx -= len;
304340

305-
zassert_true(l > 0);
341+
if (rx_data.payload_idx == 0) {
342+
rx_data.state = RX_HDR;
343+
rx_data.on_rx_rdy = on_rx_rdy_hdr;
344+
if ((rx_data.mode == RX_CONT) && rx_data.buf_req) {
306345
rx_data.buf_req = false;
307-
err = uart_rx_buf_rsp(dev, rx_data.buf, rx_data.hdr[0] - 1);
346+
err = uart_rx_buf_rsp(dev, rx_data.hdr, 1);
347+
zassert_equal(err, 0);
308348
}
309-
} else {
310-
for (int i = 0; i < len; i++) {
311-
bool ok;
349+
}
312350

313-
if ((rx_data.mode == RX_ALL) && (rx_data.payload_idx == 0)) {
314-
rx_data.payload_idx = evt->data.rx.buf[off + i];
315-
ok = true;
316-
} else {
317-
ok = evt->data.rx.buf[off + i] == (uint8_t)rx_data.payload_idx;
318-
}
351+
return true;
352+
}
319353

320-
if (!ok) {
321-
LOG_ERR("Unexpected data at %d, exp:%02x got:%02x",
322-
i, rx_data.payload_idx, evt->data.rx.buf[off + i]);
323-
}
354+
static bool on_rx_rdy_hdr(const struct device *dev, uint8_t *buf, size_t len)
355+
{
356+
int err;
324357

325-
zassert_true(ok, "Unexpected data at %d, exp:%02x got:%02x",
326-
i, len - i, evt->data.rx.buf[off + i]);
327-
if (!ok) {
328-
rx_data.cont = false;
329-
tx_data.cont = false;
330-
/* Avoid flood of errors as we are in the interrupt and ztest
331-
* cannot abort from here.
332-
*/
333-
return;
334-
}
335-
rx_data.payload_idx--;
336-
if (rx_data.payload_idx == 0) {
337-
if (rx_data.mode != RX_ALL) {
338-
zassert_equal(i + 1, len, "len:%d i:%d", len, i);
339-
}
340-
rx_data.state = RX_HDR;
341-
if ((rx_data.mode == RX_CONT) && rx_data.buf_req) {
342-
rx_data.buf_req = false;
343-
err = uart_rx_buf_rsp(dev, rx_data.hdr, 1);
344-
zassert_equal(err, 0);
345-
}
346-
}
358+
zassert_equal(buf, rx_data.hdr);
359+
zassert_equal(len, 1);
360+
if (rx_data.hdr[0] == 1) {
361+
/* single byte packet. */
362+
if ((rx_data.mode == RX_CONT) && rx_data.buf_req) {
363+
err = uart_rx_buf_rsp(dev, rx_data.hdr, 1);
364+
zassert_equal(err, 0);
347365
}
366+
return true;
348367
}
368+
369+
zassert_equal(rx_data.payload_idx, 0);
370+
rx_data.on_rx_rdy = on_rx_rdy_payload;
371+
rx_data.payload_idx = rx_data.hdr[0] - 1;
372+
rx_data.state = RX_PAYLOAD;
373+
if ((rx_data.mode == RX_CONT) && rx_data.buf_req) {
374+
size_t l = rx_data.hdr[0] - 1;
375+
376+
zassert_true(l > 0);
377+
rx_data.buf_req = false;
378+
err = uart_rx_buf_rsp(dev, rx_data.buf, buf[0] - 1);
379+
}
380+
381+
return true;
349382
}
350383

351384
static void on_rx_buf_req(const struct device *dev)
@@ -385,7 +418,6 @@ static void on_rx_dis(const struct device *dev, struct uart_event *evt, void *us
385418
return;
386419
}
387420

388-
389421
zassert_true(len > 0);
390422
err = uart_rx_enable(dev, buf, len, data->timeout);
391423
zassert_equal(err, 0, "Unexpected err:%d", err);
@@ -417,7 +449,8 @@ static void uart_callback(const struct device *dev, struct uart_event *evt, void
417449
break;
418450
case UART_RX_RDY:
419451
zassert_true(dev == rx_dev);
420-
on_rx_rdy(dev, evt);
452+
rx_data.on_rx_rdy(dev, &evt->data.rx.buf[evt->data.rx.offset], evt->data.rx.len);
453+
rx_data.rx_cnt += evt->data.rx.len;
421454
break;
422455
case UART_RX_BUF_RELEASED:
423456
zassert_true(dev == rx_dev);
@@ -516,7 +549,7 @@ static void var_packet(uint32_t baudrate, enum test_tx_mode tx_mode,
516549
tx_data.rx_timeout = rx_data.timeout;
517550
rx_data.cont = true;
518551
rx_data.rx_cnt = 0;
519-
rx_data.state = RX_HDR;
552+
rx_data.on_rx_rdy = rx_mode == RX_ALL ? on_rx_rdy_rx_all : on_rx_rdy_hdr;
520553
rx_data.mode = rx_mode;
521554

522555
ring_buf_init(&tx_data.rbuf, sizeof(tx_data.buf), tx_data.buf);

0 commit comments

Comments
 (0)