103 lines
2.5 KiB
C
103 lines
2.5 KiB
C
|
/* 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."
|
||
|
);
|