[U-Boot] [PATCH 1/2] test: Add a simple time test

Sometimes the time functions are incorrect due to bad time support on a board. Add a unit test which tries to detect this.
Signed-off-by: Simon Glass sjg@chromium.org ---
test/Kconfig | 8 ++++ test/Makefile | 1 + test/time_ut.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 test/time_ut.c
diff --git a/test/Kconfig b/test/Kconfig index 1fb1716..3270c84 100644 --- a/test/Kconfig +++ b/test/Kconfig @@ -1 +1,9 @@ +config CMD_UT_TIME + bool "Unit tests for time functions" + help + Enables the 'ut_time' command which tests that the time functions + work correctly. The test is fairly simple and will not catch all + problems. But if you are having problems with udelay() and the like, + this is a good place to start. + source "test/dm/Kconfig" diff --git a/test/Makefile b/test/Makefile index 9c95805..08330e0 100644 --- a/test/Makefile +++ b/test/Makefile @@ -6,3 +6,4 @@
obj-$(CONFIG_SANDBOX) += command_ut.o obj-$(CONFIG_SANDBOX) += compression.o +obj-$(CONFIG_CMD_UT_TIME) += time_ut.o diff --git a/test/time_ut.c b/test/time_ut.c new file mode 100644 index 0000000..6b52245 --- /dev/null +++ b/test/time_ut.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass sjg@chromium.org + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <errno.h> + +static int test_get_timer(void) +{ + ulong base, start, next, diff; + int iter; + + base = get_timer(0); + start = get_timer(0); + for (iter = 0; iter < 10; iter++) { + do { + next = get_timer(0); + } while (start == next); + + if (start + 1 != next) { + printf("%s: iter=%d, start=%lu, next=%lu, expected a difference of 1\n", + __func__, iter, start, next); + return -EINVAL; + } + start++; + } + + /* + * Check that get_timer(base) matches our elapsed time, allowing that + * an extra millisecond may have passed. + */ + diff = get_timer(base); + if (diff != iter && diff != iter + 1) { + printf("%s: expected get_timer(base) to match elapsed time: diff=%lu, expected=%d\n", + __func__, diff, iter); + return -EINVAL; + } + + return 0; +} + +static int test_timer_get_us(void) +{ + ulong prev, next, min = 1000000; + long delta; + int iter; + + /* Find the minimum delta we can measure, in microseconds */ + prev = timer_get_us(); + for (iter = 0; iter < 100; ) { + next = timer_get_us(); + if (next != prev) { + delta = next - prev; + if (delta < 0) { + printf("%s: timer_get_us() went backwards from %lu to %lu\n", + __func__, prev, next); + return -EINVAL; + } else if (delta != 0) { + if (delta < min) + min = delta; + prev = next; + iter++; + } + } + } + + if (min != 1) { + printf("%s: Minimum microsecond delta should be 1 but is %lu\n", + __func__, min); + return -EINVAL; + } + + return 0; +} + +static int test_time_comparison(void) +{ + ulong start_us, end_us, delta_us; + long error; + ulong start; + + start = get_timer(0); + start_us = timer_get_us(); + while (get_timer(start) < 1000) + ; + end_us = timer_get_us(); + delta_us = end_us - start_us; + error = delta_us - 1000000; + printf("%s: Microsecond time for 1 second: %lu, error = %ld\n", + __func__, delta_us, error); + if (abs(error) > 1000) + return -EINVAL; + + return 0; +} + +static int test_udelay(void) +{ + long error; + ulong start, delta; + int iter; + + start = get_timer(0); + for (iter = 0; iter < 1000; iter++) + udelay(1000); + delta = get_timer(start); + error = delta - 1000; + printf("%s: Delay time for 1000 udelay(1000): %lu ms, error = %ld\n", + __func__, delta, error); + if (abs(error) > 100) + return -EINVAL; + + return 0; +} + +static int do_ut_time(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int ret = 0; + + ret |= test_get_timer(); + ret |= test_timer_get_us(); + ret |= test_time_comparison(); + ret |= test_udelay(); + + printf("Test %s\n", ret ? "failed" : "passed"); + + return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + ut_time, 1, 1, do_ut_time, + "Very basic test of time functions", + "" +);

Enable this command for sandbox.
Signed-off-by: Simon Glass sjg@chromium.org ---
configs/sandbox_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 5de7fbe..1a8da8d 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -26,3 +26,4 @@ CONFIG_TPM_TIS_SANDBOX=y CONFIG_SOUND=y CONFIG_CMD_SOUND=y CONFIG_SOUND_SANDBOX=y +CONFIG_CMD_UT_TIME=y

On 2 May 2015 at 09:25, Simon Glass sjg@chromium.org wrote:
Enable this command for sandbox.
Signed-off-by: Simon Glass sjg@chromium.org
configs/sandbox_defconfig | 1 + 1 file changed, 1 insertion(+)
Applied to u-boot-dm.

+Masahiro
On 2 May 2015 at 09:25, Simon Glass sjg@chromium.org wrote:
Sometimes the time functions are incorrect due to bad time support on a board. Add a unit test which tries to detect this.
Signed-off-by: Simon Glass sjg@chromium.org
test/Kconfig | 8 ++++ test/Makefile | 1 + test/time_ut.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 test/time_ut.c
diff --git a/test/Kconfig b/test/Kconfig index 1fb1716..3270c84 100644 --- a/test/Kconfig +++ b/test/Kconfig @@ -1 +1,9 @@ +config CMD_UT_TIME
bool "Unit tests for time functions"
help
Enables the 'ut_time' command which tests that the time functions
work correctly. The test is fairly simple and will not catch all
problems. But if you are having problems with udelay() and the like,
this is a good place to start.
source "test/dm/Kconfig" diff --git a/test/Makefile b/test/Makefile index 9c95805..08330e0 100644 --- a/test/Makefile +++ b/test/Makefile @@ -6,3 +6,4 @@
obj-$(CONFIG_SANDBOX) += command_ut.o obj-$(CONFIG_SANDBOX) += compression.o +obj-$(CONFIG_CMD_UT_TIME) += time_ut.o diff --git a/test/time_ut.c b/test/time_ut.c new file mode 100644 index 0000000..6b52245 --- /dev/null +++ b/test/time_ut.c @@ -0,0 +1,137 @@ +/*
- Copyright (c) 2015 Google, Inc
- Written by Simon Glass sjg@chromium.org
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <command.h> +#include <errno.h>
+static int test_get_timer(void) +{
ulong base, start, next, diff;
int iter;
base = get_timer(0);
start = get_timer(0);
for (iter = 0; iter < 10; iter++) {
do {
next = get_timer(0);
} while (start == next);
if (start + 1 != next) {
printf("%s: iter=%d, start=%lu, next=%lu, expected a difference of 1\n",
__func__, iter, start, next);
return -EINVAL;
}
start++;
}
/*
* Check that get_timer(base) matches our elapsed time, allowing that
* an extra millisecond may have passed.
*/
diff = get_timer(base);
if (diff != iter && diff != iter + 1) {
printf("%s: expected get_timer(base) to match elapsed time: diff=%lu, expected=%d\n",
__func__, diff, iter);
return -EINVAL;
}
return 0;
+}
+static int test_timer_get_us(void) +{
ulong prev, next, min = 1000000;
long delta;
int iter;
/* Find the minimum delta we can measure, in microseconds */
prev = timer_get_us();
for (iter = 0; iter < 100; ) {
next = timer_get_us();
if (next != prev) {
delta = next - prev;
if (delta < 0) {
printf("%s: timer_get_us() went backwards from %lu to %lu\n",
__func__, prev, next);
return -EINVAL;
} else if (delta != 0) {
if (delta < min)
min = delta;
prev = next;
iter++;
}
}
}
if (min != 1) {
printf("%s: Minimum microsecond delta should be 1 but is %lu\n",
__func__, min);
return -EINVAL;
}
return 0;
+}
+static int test_time_comparison(void) +{
ulong start_us, end_us, delta_us;
long error;
ulong start;
start = get_timer(0);
start_us = timer_get_us();
while (get_timer(start) < 1000)
;
end_us = timer_get_us();
delta_us = end_us - start_us;
error = delta_us - 1000000;
printf("%s: Microsecond time for 1 second: %lu, error = %ld\n",
__func__, delta_us, error);
if (abs(error) > 1000)
return -EINVAL;
return 0;
+}
+static int test_udelay(void) +{
long error;
ulong start, delta;
int iter;
start = get_timer(0);
for (iter = 0; iter < 1000; iter++)
udelay(1000);
delta = get_timer(start);
error = delta - 1000;
printf("%s: Delay time for 1000 udelay(1000): %lu ms, error = %ld\n",
__func__, delta, error);
if (abs(error) > 100)
return -EINVAL;
return 0;
+}
+static int do_ut_time(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{
int ret = 0;
ret |= test_get_timer();
ret |= test_timer_get_us();
ret |= test_time_comparison();
ret |= test_udelay();
printf("Test %s\n", ret ? "failed" : "passed");
return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
+}
+U_BOOT_CMD(
ut_time, 1, 1, do_ut_time,
"Very basic test of time functions",
""
+);
2.2.0.rc0.207.ga3a616c

On 2 May 2015 at 09:32, Simon Glass sjg@chromium.org wrote:
+Masahiro
On 2 May 2015 at 09:25, Simon Glass sjg@chromium.org wrote:
Sometimes the time functions are incorrect due to bad time support on a board. Add a unit test which tries to detect this.
Signed-off-by: Simon Glass sjg@chromium.org
test/Kconfig | 8 ++++ test/Makefile | 1 + test/time_ut.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 test/time_ut.c
Applied to u-boot-dm.
participants (1)
-
Simon Glass