| /* |
| * (C) Copyright 2008 |
| * Gary Jennejohn, DENX Software Engineering GmbH <garyj@denx.de> |
| * |
| * SPDX-License-Identifier: GPL-2.0+ |
| */ |
| |
| U-Boot console multiplexing |
| =========================== |
| |
| HOW CONSOLE MULTIPLEXING WORKS |
| ------------------------------ |
| |
| This functionality is controlled with CONFIG_CONSOLE_MUX in the board |
| configuration file. |
| |
| Two new files, common/iomux.c and include/iomux.h, contain the heart |
| (iomux_doenv()) of the environment setting implementation. |
| |
| iomux_doenv() is called in common/cmd_nvedit.c to handle setenv and in |
| common/console.c in console_init_r() during bootup to initialize |
| stdio_devices[]. |
| |
| A user can use a comma-separated list of devices to set stdin, stdout |
| and stderr. For example: "setenv stdin serial,nc". NOTE: No spaces |
| are allowed around the comma(s)! |
| |
| The length of the list is limited by malloc(), since the array used |
| is allocated and freed dynamically. |
| |
| It should be possible to specify any device which console_assign() |
| finds acceptable, but the code has only been tested with serial and |
| nc. |
| |
| iomux_doenv() prevents multiple use of the same device, e.g. "setenv |
| stdin nc,nc,serial" will discard the second nc. iomux_doenv() is |
| not able to modify the environment, however, so that "pri stdin" still |
| shows "nc,nc,serial". |
| |
| The major change in common/console.c was to modify fgetc() to call |
| the iomux_tstc() routine in a for-loop. iomux_tstc() in turn calls |
| the tstc() routine for every registered device, but exits immediately |
| when one of them returns true. fgetc() then calls iomux_getc(), |
| which calls the corresponding getc() routine. fgetc() hangs in |
| the for-loop until iomux_tstc() returns true and the input can be |
| retrieved. |
| |
| Thus, a user can type into any device registered for stdin. No effort |
| has been made to demulitplex simultaneous input from multiple stdin |
| devices. |
| |
| fputc() and fputs() have been modified to call iomux_putc() and |
| iomux_puts() respectively, which call the corresponding output |
| routines for every registered device. |
| |
| Thus, a user can see the ouput for any device registered for stdout |
| or stderr on all devices registered for stdout or stderr. As an |
| example, if stdin=serial,nc and stdout=serial,nc then all output |
| for serial, e.g. echos of input on serial, will appear on serial and nc. |
| |
| Just as with the old console code, this statement is still true: |
| If not defined in the environment, the first input device is assigned |
| to the 'stdin' file, the first output one to 'stdout' and 'stderr'. |
| |
| If CONFIG_SYS_CONSOLE_IS_IN_ENV is defined then multiple input/output |
| devices can be set at boot time if defined in the environment. |
| |
| CAVEATS |
| ------- |
| |
| Note that common/iomux.c calls console_assign() for every registered |
| device as it is discovered. This means that the environment settings |
| for application consoles will be set to the last device in the list. |
| |
| On a slow machine, such as MPC852T clocked at 66MHz, the overhead associated |
| with calling tstc() and then getc() means that copy&paste will normally not |
| work, even when stdin=stdout=stderr=serial. |
| On a faster machine, such as a sequoia, cut&paste of longer (about 80 |
| characters) lines works fine when serial is the only device used. |
| |
| Using nc as a stdin device results in even more overhead because nc_tstc() |
| is quite slow. Even on a sequoia cut&paste does not work on the serial |
| interface when nc is added to stdin, although there is no character loss using |
| the ethernet interface for input. In this test case stdin=serial,nc and |
| stdout=serial. |
| |
| In addition, the overhead associated with sending to two devices, when one of |
| them is nc, also causes problems. Even on a sequoia cut&paste does not work |
| on the serial interface (stdin=serial) when nc is added to stdout (stdout= |
| serial,nc). |