Skip to content

Commit

Permalink
WIP tests/drivers/gpio: add performance tests
Browse files Browse the repository at this point in the history
Time execution of a sequence of operations.

s1 test takes 7.02 us on pca10056.
  • Loading branch information
pabigot committed Sep 18, 2019
1 parent 33a28b4 commit ab0d822
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 1 deletion.
1 change: 1 addition & 0 deletions tests/drivers/gpio/gpio_basic_api/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ void test_main(void)
{
board_setup();
ztest_test_suite(gpio_basic_test,
ztest_unit_test(test_gpio_perf),
ztest_unit_test(test_gpio_port),
ztest_unit_test(test_gpio_pin_read_write),
ztest_unit_test(test_gpio_callback_add_remove),
Expand Down
2 changes: 1 addition & 1 deletion tests/drivers/gpio/gpio_basic_api/src/test_gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void test_gpio_callback_add_remove(void);
void test_gpio_callback_self_remove(void);
void test_gpio_callback_enable_disable(void);
void test_gpio_callback_variants(void);

void test_gpio_perf(void);
void test_gpio_port(void);

#endif /* __TEST_GPIO_H__ */
158 changes: 158 additions & 0 deletions tests/drivers/gpio/gpio_basic_api/src/test_gpio_perf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* Copyright (c) 2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "test_gpio.h"

static struct device *dev;
static gpio_port_pins_t out_pins;
static gpio_port_pins_t in_pins;
static gpio_port_pins_t os1_pins; /* active high pins */
static gpio_port_pins_t os2_pins; /* active low pins */

static void measure(const char* tag,
void (*op)(void))
{
u32_t ts = k_cycle_get_32();
u32_t const dur_cyc = sys_clock_hw_cycles_per_sec() / 2;
u32_t te;
unsigned int count = 0;

do {
op();
te = k_cycle_get_32();
++count;
} while ((te - ts) < dur_cyc);


gpio_port_clear_bits_raw(dev, out_pins);

u64_t nom = (te - ts) * (u64_t)NSEC_PER_SEC;
u64_t div = count * (u64_t)sys_clock_hw_cycles_per_sec();
u32_t op_us = ceiling_fraction(nom, div);

TC_PRINT("- %s : %u iterations in %u cycles : %u ns / op\n",
tag, count, te - ts, op_us);
}

static void iter_nop(void)
{
}

static void iter_s1(void)
{
/* All pins high */
gpio_port_set_bits_raw(dev, out_pins);

/* All pins inactive: s1 goes low, s2 stays high */
gpio_port_clear_bits(dev, out_pins);

/* s1 goes high, s2 stays high */
gpio_port_set_bits(dev, os1_pins);

/* s1 stays high, s2 goes low */
gpio_port_set_bits(dev, os2_pins);

/* toggle: s1 low, s2 high */
gpio_port_toggle_bits(dev, out_pins);

/* OUT high, rest unchanged */
gpio_pin_set(dev, PIN_OUT, 1);

/* All pins low */
gpio_port_clear_bits_raw(dev, out_pins);
}

static int test_perf(void)
{
static const struct scope_type {
const char* devname;
u8_t pin;
} scope_pins[] = {
#ifdef DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_2
{ DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_CONTROLLER_2,
DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_2 },
#endif
#ifdef DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_3
{ DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_CONTROLLER_3,
DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_3 },
#endif
#ifdef DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_4
{ DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_CONTROLLER_4,
DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_4 },
#endif
#ifdef DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_5
{ DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_CONTROLLER_5,
DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_5 },
#endif
#ifdef DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_6
{ DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_CONTROLLER_6,
DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_6 },
#endif
#ifdef DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_7
{ DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_CONTROLLER_7,
DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_7 },
#endif
#ifdef DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_8
{ DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_CONTROLLER_8,
DT_TEST_SCOPE_PINS_SCOPE_PINS_GPIOS_PIN_8 },
#endif
};
const struct scope_type *sp = scope_pins;
const struct scope_type *const spe = sp + sizeof(scope_pins) / sizeof(*scope_pins);
size_t nout = 1;

out_pins = BIT(PIN_OUT);
dev = device_get_binding(DEV_NAME);
zassert_not_equal(dev, NULL,
"Device not found");

zassert_equal(gpio_pin_configure(dev, PIN_OUT, GPIO_OUTPUT_LOW), 0,
"PIN_OUT configure failed");
zassert_equal(gpio_pin_configure(dev, PIN_IN, GPIO_INPUT), 0,
"PIN_OUT configure failed");

while (sp < spe) {
printk("P%u : %s %u\n", (u32_t)(sp - scope_pins), sp->devname, sp->pin);
if (strcmp(sp->devname, DEV_NAME) == 0) {
u32_t flags = GPIO_OUTPUT_LOW;
out_pins |= BIT(sp->pin);
if ((nout & 1) == 1) {
flags |= GPIO_ACTIVE_LOW;
os2_pins |= BIT(sp->pin);
}
zassert_equal(gpio_pin_configure(dev, sp->pin, flags), 0,
"Scope pin configure failed");
++nout;
}
++sp;
}

os1_pins = out_pins ^ os2_pins;

out_pins |= BIT(PIN_OUT);
in_pins = BIT(PIN_IN);

TC_PRINT("%s : on %s os1 %x os2 %x in %x\n", __func__,
DEV_NAME, os1_pins, os2_pins, in_pins);

k_usleep(1);

measure("nop", iter_nop);
measure("s1", iter_s1);

return TC_PASS;
}


void test_gpio_perf(void)
{
if (!IS_ENABLED(DT_INST_0_TEST_SCOPE_PINS)) {
TC_PRINT("Performance test not supported\n");
return;
}
zassert_equal(test_perf(), TC_PASS,
"performance test completed");
}

0 comments on commit ab0d822

Please sign in to comment.