⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 console.c

📁 嵌入式ARM的一些源代码
💻 C
字号:
/*
 * (C) Copyright 2000
 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <ppcboot.h>
#include <stdarg.h>
#include <malloc.h>
#include <devices.h>

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 (leaving the existing one started)
	stdio_devices[file] = dev ;
	
	// Update monitor functions (to use the console stuff by other applications)
	switch (file){
	    case stdin:
		bd_ptr->bi_mon_fnc->getc = dev->getc ;
		bd_ptr->bi_mon_fnc->tstc = dev->tstc ;
		break;		
	    case stdout:
		bd_ptr->bi_mon_fnc->putc = dev->putc ;
		bd_ptr->bi_mon_fnc->puts = dev->puts ;
		bd_ptr->bi_mon_fnc->printf = printf ;
		break;		
	}
	break;
    	
    default:	// Invalid file ID
	error = -1 ;
    }
    return error ;
}

//** PPCBOOT INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************

void serial_printf(const char *fmt, ...)
{
	va_list	args;
	uint	i;
	char	printbuffer[CFG_PBSIZE];

	va_start(args, fmt);

	/* For this to work, printbuffer must be larger than
	 * anything we ever want to print.
	 */
	i = vsprintf(printbuffer, fmt, args);
	va_end(args);

	serial_puts(printbuffer);
}

int	fgetc(int file)
{
    if (file < MAX_FILES)
	return stdio_devices[file]->getc();
    
    return -1 ;
}

int	ftstc(int file)
{
    if (file < MAX_FILES)
	return stdio_devices[file]->tstc();
    
    return -1 ;
}

void	fputc(int file, const char c)
{
    if (file < MAX_FILES)
	stdio_devices[file]->putc(c);
}

void	fputs(int file, const char *s)
{
    if (file < MAX_FILES)
	stdio_devices[file]->puts(s);
}

void fprintf(int file, const char *fmt, ...)
{
	va_list	args;
	uint	i;
	char	printbuffer[CFG_PBSIZE];

	va_start(args, fmt);

	/* For this to work, printbuffer must be larger than
	 * anything we ever want to print.
	 */
	i = vsprintf(printbuffer, fmt, args);
	va_end(args);

	// Send to desired file
        fputs(file, printbuffer);
}

//** PPCBOOT INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************

int	getc(void)
{
    init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);

    if (idata->relocated)
	    // Get from the standard input
	    return fgetc (stdin);
    
    // Send directly to the handler
    return serial_getc();
}

int	tstc(void)
{
    init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);

    if (idata->relocated)
	    // Test the standard input
	    return ftstc (stdin);
    
    // Send directly to the handler
    return serial_tstc();
}

void	putc(const char c)
{
    init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);

    if (idata->relocated)
	// Send to the standard output
	fputc (stdout, c);
    else    
	// Send directly to the handler
	serial_putc(c);
}

void	puts(const char *s)
{
    init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);

    if (idata->relocated)
	// Send to the standard output
	fputs (stdout, s);
    else    
	// Send directly to the handler
	serial_puts(s);
}

void printf(const char *fmt, ...)
{
	va_list	args;
	uint	i;
	char	printbuffer[CFG_PBSIZE];

	va_start(args, fmt);

	/* For this to work, printbuffer must be larger than
	 * anything we ever want to print.
	 */
	i = vsprintf(printbuffer, fmt, args);
	va_end(args);

	// Print the string
	puts (printbuffer);
}

//** PPCBOOT INIT FUNCTIONS *************************************************

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 ;
}

// Called before relocation - use serial functions
void	console_init_f (void)
{
    init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);

    idata->relocated 		= 0 ;		// Use these pointers before relocation
    idata->bi_mon_fnc.getc   	= serial_getc;	
    idata->bi_mon_fnc.tstc   	= serial_tstc;	
    idata->bi_mon_fnc.putc   	= serial_putc;	
    idata->bi_mon_fnc.puts 	= serial_puts;	
    idata->bi_mon_fnc.printf 	= serial_printf;
}

// Called after the relocation - use desierd console functions
void	console_init_r (void)
{
    init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
    device_t	*inputdev = NULL, *outputdev = NULL ;
    int i, items = ListNumItems(devlist) ;

    // Global pointer to monitor structure (updated by the console stuff)
    bd_ptr->bi_mon_fnc = &idata->bi_mon_fnc ;

    // Scan devices looking for input and output devices
    for (i=1; (i<=items) && ((inputdev == NULL) || (outputdev == NULL)); i++)
    {	
	device_t	*dev = ListGetPtrToItem(devlist, i) ;
	
	if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev==NULL))
	    inputdev = dev ;

	if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev==NULL))
	    outputdev = dev ;
    }
	    
    // Initializes output console first
    if (outputdev != NULL)
    {
	console_setfile(stdout, outputdev);
	console_setfile(stderr, outputdev);
    }
	
    // Initializes input console
    if (inputdev != NULL)
	console_setfile(stdin, inputdev);

    // Print informations
    printf("  Input:  ");
    if (stdio_devices[stdin] == NULL)
	printf("No input devices available!\n");
    else
    {
	printf("%s\n", stdio_devices[stdin]->name);
    }
    
    printf("  Output: ");
    if (stdio_devices[stdout] == NULL)
	printf("No output devices available!\n");
    else
	printf("%s\n", stdio_devices[stdout]->name);	
    
    // Setting environment variables
    for (i=0; i<3; i++)
	setenv(stdio_names[i], stdio_devices[i]->name);

    // If nothing usable installed, use only the initial console
    if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
    	return ;

    // Set the relocation flag    
    idata->relocated = 1 ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -