summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2019-04-05 10:42:50 -0700
committerCommit Bot <commit-bot@chromium.org>2019-07-02 23:28:41 +0000
commitc7f66d9adc31395fd0fa336ab6050c4953b98b35 (patch)
tree4a90a806eb4c51fbbac54b5a52990c3edbd2d7ad
parent4509620f1e7873ee239b558675a47c69f614a732 (diff)
downloadchrome-ec-c7f66d9adc31395fd0fa336ab6050c4953b98b35.tar.gz
add chargen command to allow EC and AP to flood the console
The chargen command sends continuous stream of characters to the console (UART console in case of EC). The stream follows a pattern where the value of each next character is the value of the previous character + 1, while staying in the ASCII range of 0..9A..Za..Z This allows to create tests which validate console output by verifying that no characters in the received sequence were lost. BRANCH=none BUG=b:38448364 TEST=Enabled the command for bobba EC board, and verified that the chargen works on both EC and AP on an Octopus device Change-Id: I9701bb493b0454de4cb4baa4784ab645b33a415f Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1554198 Reviewed-by: Namyoon Woo <namyoon@chromium.org>
-rw-r--r--common/build.mk1
-rw-r--r--common/chargen.c102
-rw-r--r--include/config.h3
-rw-r--r--util/chargen69
4 files changed, 175 insertions, 0 deletions
diff --git a/common/build.mk b/common/build.mk
index 4a3ff23abf..d0231feaf6 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -41,6 +41,7 @@ common-$(CONFIG_CROS_BOARD_INFO)+=cbi.o
common-$(CONFIG_CHARGE_MANAGER)+=charge_manager.o
common-$(CONFIG_CHARGE_RAMP_HW)+=charge_ramp.o
common-$(CONFIG_CHARGE_RAMP_SW)+=charge_ramp.o charge_ramp_sw.o
+common-$(CONFIG_CHARGEN) += chargen.o
common-$(CONFIG_CHARGER)+=charger.o
common-$(CONFIG_CHARGER_PROFILE_OVERRIDE_COMMON)+=charger_profile_override.o
common-$(CONFIG_CHARGER_V2)+=charge_state_v2.o
diff --git a/common/chargen.c b/common/chargen.c
new file mode 100644
index 0000000000..64cd138924
--- /dev/null
+++ b/common/chargen.c
@@ -0,0 +1,102 @@
+/* Copyright 2019 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "config.h"
+#include "console.h"
+#include "timer.h"
+#include "uart.h"
+#include "util.h"
+#include "watchdog.h"
+
+/*
+ * Microseconds time to drain entire UART_TX console buffer at 115200 b/s, 10
+ * bits per character.
+ */
+#define BUFFER_DRAIN_TIME_US (1000000UL * 10 * CONFIG_UART_TX_BUF_SIZE / 115200)
+/*
+ * Generate a stream of characters on the UART console.
+ *
+ * The stream is an ever incrementing pattern of characters from the following
+ * set: 0..9A..Za..z.
+ *
+ * The two optional integer command line arguments work as follows:
+ *
+ * argv[1] - reset the pattern after this many characters have been printed.
+ * Setting this value to the width of the terminal window results
+ * in a very regular stream showing on the terminal, where it is
+ * easy to observe disruptions.
+ * argv[2] - limit number of printed characters to this amount. If not
+ * specified - keep printing indefinitely.
+ *
+ * Hitting 'x' on the keyboard stops the generator.
+ */
+static int command_chargen(int argc, char **argv)
+{
+ int wrap_value = 0;
+ int wrap_counter = 0;
+ uint8_t c;
+ uint32_t seq_counter = 0;
+ uint32_t seq_number = 0;
+ timestamp_t prev_watchdog_time;
+
+ while (uart_getc() != -1)
+ ; /* Drain received characters, if any. */
+
+ if (argc > 1)
+ wrap_value = atoi(argv[1]);
+
+ if (argc > 2)
+ seq_number = atoi(argv[2]);
+
+ c = '0';
+ prev_watchdog_time = get_time();
+ while (uart_getc() != 'x') {
+ timestamp_t current_time;
+
+ while (uart_buffer_full()) {
+ /*
+ * Let's sleep enough time to drain half of TX
+ * buffer.
+ */
+ usleep(BUFFER_DRAIN_TIME_US/2);
+
+ current_time = get_time();
+
+ if ((current_time.val - prev_watchdog_time.val) <
+ (CONFIG_WATCHDOG_PERIOD_MS * 1000 / 2))
+ continue;
+
+ watchdog_reload();
+ prev_watchdog_time.val = current_time.val;
+ }
+
+ uart_putc(c++);
+
+ if (seq_number && (++seq_counter == seq_number))
+ break;
+
+ if (wrap_value && (++wrap_counter == wrap_value)) {
+ c = '0';
+ wrap_counter = 0;
+ continue;
+ }
+
+ if (c == ('z' + 1))
+ c = '0';
+ else if (c == ('Z' + 1))
+ c = 'a';
+ else if (c == ('9' + 1))
+ c = 'A';
+ }
+
+ uart_putc('\n');
+ return 0;
+}
+DECLARE_SAFE_CONSOLE_COMMAND(chargen, command_chargen,
+ "[seq_length [num_chars]]",
+ "Generate a constant stream of characters on the "
+ "UART console,\nrepeating every 'seq_length' "
+ "characters, up to 'num_chars' total."
+ );
diff --git a/include/config.h b/include/config.h
index 45e686ea8f..9765f83859 100644
--- a/include/config.h
+++ b/include/config.h
@@ -677,6 +677,9 @@
/*****************************************************************************/
+/* Cli command for generating UART console traffic, used for testing. */
+#undef CONFIG_CHARGEN
+
/* Compile charge manager */
#undef CONFIG_CHARGE_MANAGER
diff --git a/util/chargen b/util/chargen
new file mode 100644
index 0000000000..d9260fcb0b
--- /dev/null
+++ b/util/chargen
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+# Copyright 2019 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import sys
+
+def chargen(modulo, max_chars):
+ """Generate a stream of characters on the console.
+
+ The stream is an ever incrementing pattern of characters from the
+ following set: 0..9A..Za..z.
+
+ Args:
+ modulo: an int, restart the pattern every modulo characters, if
+ modulo is non zero
+ max_chars: an int, stop printing after this number of characters if non
+ zero, if zero - print indefinitely
+ """
+
+ base = '0'
+ c = base
+ counter = 0
+ while True:
+ sys.stdout.write(c)
+ counter = counter + 1
+
+ if (max_chars != 0) and (counter == max_chars):
+ sys.stdout.write('\n')
+ return
+
+ if modulo and ((counter % modulo) == 0):
+ c = base
+ continue
+
+ if c == 'z':
+ c = base
+ elif c == 'Z':
+ c = 'a'
+ elif c == '9':
+ c = 'A'
+ else:
+ c = '%c' % (ord(c) + 1)
+
+
+def main(args):
+ '''Process command line arguments and invoke chargen if args are valid'''
+
+ modulo = 0
+ max_chars = 0
+
+ try:
+ if len(args) > 0:
+ modulo = int(args[0])
+ if len(args) > 1:
+ max_chars = int(args[1])
+ except ValueError:
+ sys.stderr.write('usage %s:'
+ "['seq_length' ['max_chars']]\n")
+ sys.exit(1)
+
+ try:
+ chargen(modulo, max_chars)
+ except KeyboardInterrupt:
+ print
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
+ sys.exit(0)