This article from: http://www.linuxso.com/linuxrumen/23585.html
Directory
Zero, Overview
I. init_baudrate
Ii. serial_init
3. lele_init_f
Iv. devices_init
V. lele_init_r
6. Print Information
7. Why use devlist, std_device []?
Zero, Overview
The figure above shows the serial port device driver process in U-boot, from register-level settings to final terminal information output. Next we will explain each step in detail.
I. init_baudrate
This function sets Gd-> BD-> bi_baudrate.
StatIC int init_baudrate (VOID) {Char TMP [64];/* long enough for environment variables */INT I = getenv_r ("baudrate", TMP, sizeof (TMP )); GD-> BD-> bi_baudrate = Gd-> baudrate = (I> 0 )? (INT) simple_sTrToul (TMP, null, 10): config_baudrate; // # define config_baudrate115200 is defined in/INCLude/configs/smdk2410.c // if the environment is not saved, use the macro-defined parameter return (0 );}
Ii. serial_init
Initialize the UART Controller.
Void serial _SetBrg (void) {s3c24x0_uart * const UART = s3c24x0_getbase_uart (uart_nr); int I; unsigned int Reg = 0;/* value is calculated so: (INT) (pclk/16. /baudrate)-1 */REG = get_pclk ()/(16 * Gd-> baudrate)-1;/* FIFOEnable, TX/RX FIFOClear*/UART-> ufcon = 0x07; UART-> umcon = 0x0;/* NoRmAl, no parity, 1 stop, 8 bit */UART-> ulcon = 0x3;/** Tx = level, RX = edge, disableTimeOut Int ., enable RX error Int ., * normal, interrupt or polling */UART-> ucon = 0x245; UART-> ubrdiv = reg; # ifdef config_hwflowuart-> umcon = 0x1; /* RTS up */# endiffor (I = 0; I <100; I ++);}/** initialise the serial port with the given baudrate. the settings * are always 8 data bits, no parity, 1 stop bit, no start bits. **/INT serial_init (void) {serial_setbrg (); // set the UART register return (0 );}
3. lele_init_f
Console initialization.
int console_init_f (void){gd->have_console = 1;#ifdef CONFIG_SILENT_CONSOLEif (getenv("silent") != NULL)gd->flags |= GD_FLG_SILENT;#endifreturn (0);}
Iv. devices_init
This part has been analyzed in the previous article and will not be described here.
V. lele_init_r
Console initialization later. View the device names specified for standard IO in the environment parameters stdin, stdout, and stderr. If you do not know, search for devlist by the name specified by the environment, assign the obtained device pointer to the standard Io array stdio_devices [].
Int console_init_r (void) {char * stdinname, * stdoutname, * stderrname; device_t * inputdev = NULL, * outputdev = NULL, * erRdev= NULL; # ifdef cfg_console_env_overwriteint I; # endif/* cfg_console_env_overwrite * // * Set default handlers at first to set the jump table */Gd-> JT [xf_getc] = serial_getc; GD-> JT [xf_tstc] = serial_tstc; Gd-> JT [xf_putc] = serial_putc; Gd-> JT [xf_puts] = serial_puts; Gd-> JT [xf_printf] = serial_printf; /* stdin stdout and stderr are in Environment view the specified device name of standard IO in the environment parameters stdin, stdout, and stderr * // * scan for it */stdinname = getenv ("Stdin"); stdoutname = getenv ("stdout"); stderrname = getenv ("stderr"); If (overwrite_console = 0) {/* if not overwritten by config switch */inputdev = search_device (response, stdinname); outputdev = search_device (response, stdoutname); errdev = search_device (dev_flags_output, stderrname );} /* If the devices are overwritten or not found, use default device to search devices by specified name */If (inputdev = NULL) {inputdev = search_device (dev_flags_input, "serial");} If (outputdev = NULL) {outputdev = search_device (dev_flags_output, "serial ");} if (errdev = NULL) {errdev = search_device (dev_flags_output, "serial");}/* initializes output console first assigns the found device pointer to the standard Io array stdio_devices [], why do we do this in the following? */If (outputdev! = NULL) {lele_setFile(Stdout, outputdev);} If (errdev! = NULL) {lele_setfile (stderr, errdev);} If (inputdev! = NULL) {lele_setfile (stdin, inputdev);} Gd-> flags | = gd_flg_devinit;/* Device initialization completed. The initialization of the serial port device is complete only after it is reached, this flag affects functions such as GETC */# ifndef cfg_lele_info_quiet/* print information */puts ("in:"); If (stdio_devices [stdin] = NULL) {puts ("no input devices available! \ N ");} eLsE {printf ("% s \ n", stdio_devices [stdin]-> name);} puts ("out:"); If (stdio_devices [stdout] = NULL) {puts ("no output devices available! \ N ");} else {printf (" % s \ n ", stdio_devices [stdout]-> name);} puts (" Err :"); if (stdio_devices [stderr] = NULL) {puts ("no error devices available! \ N ");} else {printf (" % s \ n ", stdio_devices [stderr]-> name );} # endif/* cfg_console_info_quiet */# ifdef cfg_console_env_overwrite/* set the environment variables (will overWritePrevious env settings) */for (I = 0; I <3; I ++ ){Setenv(Stdio_names [I], stdio_devices [I]-> name) ;}# endif/* cfg_console_env_overwrite */# If 0/* if nothing usable installed, use only the initial console */If (stdio_devices [stdin] = NULL) & (stdio_devices [stdout] = NULL) Return (0 ); # endifreturn (0 );}
6. Print Information
The following information will be printed at the end:
In: Serial
Out: Serial
Err: Serial
This indicates that the serial port Initialization is complete.
7. Why use devlist, std_device []?
To achieve more flexible standard Io redirection, any device that can be used as a standard Io, such as a USB keyboard, LCD screen, or serial port, can correspond to a device_t struct variable, you only need to implement functions such as GETC and putc to add them to the devlist list, and the assign can be used as the stdo_device of the standard IO Device. For example, the int lele_assign (INT file, char * devname) function ); /* assign the console redirection standard input/output */This function redirects a device named devname to a standard Io file (stdin, stdout, stderr ). The execution process is to find the devname device in devlist, return the device_t pointer of the device, and assign the pointer value to stdo_device.
int console_assign (int file, char *devname){int flag, i;/* Check for valid file */switch (file) {case stdin:flag = DEV_FLAGS_INPUT;break;case stdout:case stderr:flag = DEV_FLAGS_OUTPUT;break;default:return -1;}/* Check for valid device name */for (i = 1; i <= ListNumItems (devlist); i++) {device_t *dev = ListGetPtrToItem (devlist, i);if (strcmp (devname, dev->name) == 0) {if (dev->flags & flag)return console_setfile (file, dev);return -1;}}return -1;}
This function is used to call console_setfile to set stdo_device [] to complete redirect input and output.
Static int console_setfile (INT file, device_t * Dev) {int error = 0; If (Dev = NULL) Return-1; Switch (File) {Case stdin: Case stdout: case stderr:/* Start new device */If (Dev-> Start) {error = Dev-> Start (); /* if it's not started dont use it */If (error <0) break;}/* assign the new device (leavingExIsting one started) */stdio_devices = dev; // The key here/** upDateMonitor functions * (to use the console stuff by other appliCatIons) */switch (File) {Case stdin: Gd-> JT [xf_getc] = Dev-> GETC; Gd-> JT [xf_tstc] = Dev-> tstc; break; case stdout: Gd-> JT [xf_putc] = Dev-> putc; Gd-> JT [xf_puts] = Dev-> puts; Gd-> JT [xf_printf] = printf; break;} break; default:/* invalid file ID */error =-1;} return error ;}