1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun * (C) Copyright 2008 3*4882a593Smuzhiyun * Gary Jennejohn, DENX Software Engineering GmbH <garyj@denx.de> 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+ 6*4882a593Smuzhiyun */ 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunU-Boot console multiplexing 9*4882a593Smuzhiyun=========================== 10*4882a593Smuzhiyun 11*4882a593SmuzhiyunHOW CONSOLE MULTIPLEXING WORKS 12*4882a593Smuzhiyun------------------------------ 13*4882a593Smuzhiyun 14*4882a593SmuzhiyunThis functionality is controlled with CONFIG_CONSOLE_MUX in the board 15*4882a593Smuzhiyunconfiguration file. 16*4882a593Smuzhiyun 17*4882a593SmuzhiyunTwo new files, common/iomux.c and include/iomux.h, contain the heart 18*4882a593Smuzhiyun(iomux_doenv()) of the environment setting implementation. 19*4882a593Smuzhiyun 20*4882a593Smuzhiyuniomux_doenv() is called in common/cmd_nvedit.c to handle setenv and in 21*4882a593Smuzhiyuncommon/console.c in console_init_r() during bootup to initialize 22*4882a593Smuzhiyunstdio_devices[]. 23*4882a593Smuzhiyun 24*4882a593SmuzhiyunA user can use a comma-separated list of devices to set stdin, stdout 25*4882a593Smuzhiyunand stderr. For example: "setenv stdin serial,nc". NOTE: No spaces 26*4882a593Smuzhiyunare allowed around the comma(s)! 27*4882a593Smuzhiyun 28*4882a593SmuzhiyunThe length of the list is limited by malloc(), since the array used 29*4882a593Smuzhiyunis allocated and freed dynamically. 30*4882a593Smuzhiyun 31*4882a593SmuzhiyunIt should be possible to specify any device which console_assign() 32*4882a593Smuzhiyunfinds acceptable, but the code has only been tested with serial and 33*4882a593Smuzhiyunnc. 34*4882a593Smuzhiyun 35*4882a593Smuzhiyuniomux_doenv() prevents multiple use of the same device, e.g. "setenv 36*4882a593Smuzhiyunstdin nc,nc,serial" will discard the second nc. iomux_doenv() is 37*4882a593Smuzhiyunnot able to modify the environment, however, so that "pri stdin" still 38*4882a593Smuzhiyunshows "nc,nc,serial". 39*4882a593Smuzhiyun 40*4882a593SmuzhiyunThe major change in common/console.c was to modify fgetc() to call 41*4882a593Smuzhiyunthe iomux_tstc() routine in a for-loop. iomux_tstc() in turn calls 42*4882a593Smuzhiyunthe tstc() routine for every registered device, but exits immediately 43*4882a593Smuzhiyunwhen one of them returns true. fgetc() then calls iomux_getc(), 44*4882a593Smuzhiyunwhich calls the corresponding getc() routine. fgetc() hangs in 45*4882a593Smuzhiyunthe for-loop until iomux_tstc() returns true and the input can be 46*4882a593Smuzhiyunretrieved. 47*4882a593Smuzhiyun 48*4882a593SmuzhiyunThus, a user can type into any device registered for stdin. No effort 49*4882a593Smuzhiyunhas been made to demulitplex simultaneous input from multiple stdin 50*4882a593Smuzhiyundevices. 51*4882a593Smuzhiyun 52*4882a593Smuzhiyunfputc() and fputs() have been modified to call iomux_putc() and 53*4882a593Smuzhiyuniomux_puts() respectively, which call the corresponding output 54*4882a593Smuzhiyunroutines for every registered device. 55*4882a593Smuzhiyun 56*4882a593SmuzhiyunThus, a user can see the ouput for any device registered for stdout 57*4882a593Smuzhiyunor stderr on all devices registered for stdout or stderr. As an 58*4882a593Smuzhiyunexample, if stdin=serial,nc and stdout=serial,nc then all output 59*4882a593Smuzhiyunfor serial, e.g. echos of input on serial, will appear on serial and nc. 60*4882a593Smuzhiyun 61*4882a593SmuzhiyunJust as with the old console code, this statement is still true: 62*4882a593SmuzhiyunIf not defined in the environment, the first input device is assigned 63*4882a593Smuzhiyunto the 'stdin' file, the first output one to 'stdout' and 'stderr'. 64*4882a593Smuzhiyun 65*4882a593SmuzhiyunIf CONFIG_SYS_CONSOLE_IS_IN_ENV is defined then multiple input/output 66*4882a593Smuzhiyundevices can be set at boot time if defined in the environment. 67*4882a593Smuzhiyun 68*4882a593SmuzhiyunCAVEATS 69*4882a593Smuzhiyun------- 70*4882a593Smuzhiyun 71*4882a593SmuzhiyunNote that common/iomux.c calls console_assign() for every registered 72*4882a593Smuzhiyundevice as it is discovered. This means that the environment settings 73*4882a593Smuzhiyunfor application consoles will be set to the last device in the list. 74*4882a593Smuzhiyun 75*4882a593SmuzhiyunOn a slow machine, such as MPC852T clocked at 66MHz, the overhead associated 76*4882a593Smuzhiyunwith calling tstc() and then getc() means that copy&paste will normally not 77*4882a593Smuzhiyunwork, even when stdin=stdout=stderr=serial. 78*4882a593SmuzhiyunOn a faster machine, such as a sequoia, cut&paste of longer (about 80 79*4882a593Smuzhiyuncharacters) lines works fine when serial is the only device used. 80*4882a593Smuzhiyun 81*4882a593SmuzhiyunUsing nc as a stdin device results in even more overhead because nc_tstc() 82*4882a593Smuzhiyunis quite slow. Even on a sequoia cut&paste does not work on the serial 83*4882a593Smuzhiyuninterface when nc is added to stdin, although there is no character loss using 84*4882a593Smuzhiyunthe ethernet interface for input. In this test case stdin=serial,nc and 85*4882a593Smuzhiyunstdout=serial. 86*4882a593Smuzhiyun 87*4882a593SmuzhiyunIn addition, the overhead associated with sending to two devices, when one of 88*4882a593Smuzhiyunthem is nc, also causes problems. Even on a sequoia cut&paste does not work 89*4882a593Smuzhiyunon the serial interface (stdin=serial) when nc is added to stdout (stdout= 90*4882a593Smuzhiyunserial,nc). 91